61a55a9f781b67fc9e28c59d949999b5e79ab087
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Controllers / ApplicationCacheManager.js
1 /*
2  * Copyright (C) 2013 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.ApplicationCacheManager = class ApplicationCacheManager extends WebInspector.Object
27 {
28     constructor()
29     {
30         super();
31
32         if (window.ApplicationCacheAgent)
33             ApplicationCacheAgent.enable();
34
35         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
36         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasRemoved, this._childFrameWasRemoved, this);
37
38         this._online = true;
39
40         this.initialize();
41     }
42
43     // Public
44
45     initialize()
46     {
47         this._applicationCacheObjects = {};
48
49         if (window.ApplicationCacheAgent)
50             ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
51     }
52
53     get applicationCacheObjects()
54     {
55         var applicationCacheObjects = [];
56         for (var id in this._applicationCacheObjects)
57             applicationCacheObjects.push(this._applicationCacheObjects[id]);
58         return applicationCacheObjects;
59     }
60
61     networkStateUpdated(isNowOnline)
62     {
63         this._online = isNowOnline;
64
65         this.dispatchEventToListeners(WebInspector.ApplicationCacheManager.Event.NetworkStateUpdated, {online: this._online});
66     }
67
68     get online()
69     {
70         return this._online;
71     }
72
73     applicationCacheStatusUpdated(frameId, manifestURL, status)
74     {
75         var frame = WebInspector.frameResourceManager.frameForIdentifier(frameId);
76         if (!frame)
77             return;
78
79         this._frameManifestUpdated(frame, manifestURL, status);
80     }
81
82     requestApplicationCache(frame, callback)
83     {
84         function callbackWrapper(error, applicationCache)
85         {
86             if (error) {
87                 callback(null);
88                 return;
89             }
90
91             callback(applicationCache);
92         }
93
94         ApplicationCacheAgent.getApplicationCacheForFrame(frame.id, callbackWrapper);
95     }
96
97     // Private
98
99     _mainResourceDidChange(event)
100     {
101         console.assert(event.target instanceof WebInspector.Frame);
102
103         if (event.target.isMainFrame()) {
104             // If we are dealing with the main frame, we want to clear our list of objects, because we are navigating to a new page.
105             this.initialize();
106
107             this.dispatchEventToListeners(WebInspector.ApplicationCacheManager.Event.Cleared);
108
109             return;
110         }
111
112         if (window.ApplicationCacheAgent)
113             ApplicationCacheAgent.getManifestForFrame(event.target.id, this._manifestForFrameLoaded.bind(this, event.target.id));
114     }
115
116     _childFrameWasRemoved(event)
117     {
118         this._frameManifestRemoved(event.data.childFrame);
119     }
120
121     _manifestForFrameLoaded(frameId, error, manifestURL)
122     {
123         if (error)
124             return;
125
126         var frame = WebInspector.frameResourceManager.frameForIdentifier(frameId);
127         if (!frame)
128             return;
129
130         if (!manifestURL)
131             this._frameManifestRemoved(frame);
132     }
133
134     _framesWithManifestsLoaded(error, framesWithManifests)
135     {
136         if (error)
137             return;
138
139         for (var i = 0; i < framesWithManifests.length; ++i) {
140             var frame = WebInspector.frameResourceManager.frameForIdentifier(framesWithManifests[i].frameId);
141             if (!frame)
142                 continue;
143
144             this._frameManifestUpdated(frame, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
145         }
146     }
147
148     _frameManifestUpdated(frame, manifestURL, status)
149     {
150         if (status === WebInspector.ApplicationCacheManager.Status.Uncached) {
151             this._frameManifestRemoved(frame);
152             return;
153         }
154
155         if (!manifestURL)
156             return;
157
158         var manifestFrame = this._applicationCacheObjects[frame.id];
159         if (manifestFrame && manifestURL !== manifestFrame.manifest.manifestURL)
160             this._frameManifestRemoved(frame);
161
162         var oldStatus = manifestFrame ? manifestFrame.status : -1;
163         var statusChanged = manifestFrame && status !== oldStatus;
164         if (manifestFrame)
165             manifestFrame.status = status;
166
167         if (!this._applicationCacheObjects[frame.id]) {
168             var cacheManifest = new WebInspector.ApplicationCacheManifest(manifestURL);
169             this._applicationCacheObjects[frame.id] = new WebInspector.ApplicationCacheFrame(frame, cacheManifest, status);
170
171             this.dispatchEventToListeners(WebInspector.ApplicationCacheManager.Event.FrameManifestAdded, {frameManifest: this._applicationCacheObjects[frame.id]});
172         }
173
174         if (statusChanged)
175             this.dispatchEventToListeners(WebInspector.ApplicationCacheManager.Event.FrameManifestStatusChanged, {frameManifest: this._applicationCacheObjects[frame.id]});
176     }
177
178     _frameManifestRemoved(frame)
179     {
180         if (!this._applicationCacheObjects[frame.id])
181             return;
182
183         delete this._applicationCacheObjects[frame.id];
184
185         this.dispatchEventToListeners(WebInspector.ApplicationCacheManager.Event.FrameManifestRemoved, {frame});
186     }
187 };
188
189 WebInspector.ApplicationCacheManager.Event = {
190     Cleared: "application-cache-manager-cleared",
191     FrameManifestAdded: "application-cache-manager-frame-manifest-added",
192     FrameManifestRemoved: "application-cache-manager-frame-manifest-removed",
193     FrameManifestStatusChanged: "application-cache-manager-frame-manifest-status-changed",
194     NetworkStateUpdated: "application-cache-manager-network-state-updated"
195 };
196
197 WebInspector.ApplicationCacheManager.Status = {
198     Uncached: 0,
199     Idle: 1,
200     Checking: 2,
201     Downloading: 3,
202     UpdateReady: 4,
203     Obsolete: 5
204 };