Home | History | Annotate | Download | only in front_end
      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.Object}
     32  */
     33 WebInspector.ApplicationCacheModel = function()
     34 {
     35     ApplicationCacheAgent.enable();
     36     InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
     37 
     38     WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
     39     WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
     40 
     41     this._statuses = {};
     42     this._manifestURLsByFrame = {};
     43 
     44     this._mainFrameNavigated();
     45 
     46     this._onLine = true;
     47 }
     48 
     49 WebInspector.ApplicationCacheModel.EventTypes = {
     50     FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
     51     FrameManifestAdded: "FrameManifestAdded",
     52     FrameManifestRemoved: "FrameManifestRemoved",
     53     NetworkStateChanged: "NetworkStateChanged"
     54 }
     55 
     56 WebInspector.ApplicationCacheModel.prototype = {
     57     _frameNavigated: function(event)
     58     {
     59         var frame = /** @type {WebInspector.ResourceTreeFrame} */ (event.data);
     60         if (frame.isMainFrame()) {
     61             this._mainFrameNavigated();
     62             return;
     63         }
     64 
     65         ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
     66     },
     67 
     68     /**
     69      * @param {WebInspector.Event} event
     70      */
     71     _frameDetached: function(event)
     72     {
     73         var frame = /** @type {WebInspector.ResourceTreeFrame} */ (event.data);
     74         this._frameManifestRemoved(frame.id);
     75     },
     76 
     77     _mainFrameNavigated: function()
     78     {
     79         ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
     80     },
     81 
     82     /**
     83      * @param {string} frameId
     84      * @param {?Protocol.Error} error
     85      * @param {string} manifestURL
     86      */
     87     _manifestForFrameLoaded: function(frameId, error, manifestURL)
     88     {
     89         if (error) {
     90             console.error(error);
     91             return;
     92         }
     93 
     94         if (!manifestURL)
     95             this._frameManifestRemoved(frameId);
     96     },
     97 
     98     /**
     99      * @param {?Protocol.Error} error
    100      * @param {Array.<ApplicationCacheAgent.FrameWithManifest>} framesWithManifests
    101      */
    102     _framesWithManifestsLoaded: function(error, framesWithManifests)
    103     {
    104         if (error) {
    105             console.error(error);
    106             return;
    107         }
    108 
    109         for (var i = 0; i < framesWithManifests.length; ++i)
    110             this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
    111     },
    112 
    113     /**
    114      * @param {string} frameId
    115      * @param {string} manifestURL
    116      * @param {number} status
    117      */
    118     _frameManifestUpdated: function(frameId, manifestURL, status)
    119     {
    120         if (status === applicationCache.UNCACHED) {
    121             this._frameManifestRemoved(frameId);
    122             return;
    123         }
    124 
    125         if (!manifestURL)
    126             return;
    127 
    128         if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
    129             this._frameManifestRemoved(frameId);
    130 
    131         var statusChanged = this._statuses[frameId] !== status;
    132         this._statuses[frameId] = status;
    133 
    134         if (!this._manifestURLsByFrame[frameId]) {
    135             this._manifestURLsByFrame[frameId] = manifestURL;
    136             this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
    137         }
    138 
    139         if (statusChanged)
    140             this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
    141     },
    142 
    143     /**
    144      * @param {string} frameId
    145      */
    146     _frameManifestRemoved: function(frameId)
    147     {
    148         if (!this._manifestURLsByFrame[frameId])
    149             return;
    150 
    151         var manifestURL = this._manifestURLsByFrame[frameId];
    152         delete this._manifestURLsByFrame[frameId];
    153         delete this._statuses[frameId];
    154 
    155         this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
    156     },
    157 
    158     /**
    159      * @param {string} frameId
    160      * @return {string}
    161      */
    162     frameManifestURL: function(frameId)
    163     {
    164         return this._manifestURLsByFrame[frameId] || "";
    165     },
    166 
    167     /**
    168      * @param {string} frameId
    169      * @return {number}
    170      */
    171     frameManifestStatus: function(frameId)
    172     {
    173         return this._statuses[frameId] || applicationCache.UNCACHED;
    174     },
    175 
    176     /**
    177      * @return {boolean}
    178      */
    179     get onLine()
    180     {
    181         return this._onLine;
    182     },
    183 
    184     /**
    185      * @param {string} frameId
    186      * @param {string} manifestURL
    187      * @param {number} status
    188      */
    189     _statusUpdated: function(frameId, manifestURL, status)
    190     {
    191         this._frameManifestUpdated(frameId, manifestURL, status);
    192     },
    193 
    194     /**
    195      * @param {string} frameId
    196      * @param {function(Object)} callback
    197      */
    198     requestApplicationCache: function(frameId, callback)
    199     {
    200         function callbackWrapper(error, applicationCache)
    201         {
    202             if (error) {
    203                 console.error(error);
    204                 callback(null);
    205                 return;
    206             }
    207 
    208             callback(applicationCache);
    209         }
    210 
    211         ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this));
    212     },
    213 
    214     /**
    215      * @param {boolean} isNowOnline
    216      */
    217     _networkStateUpdated: function(isNowOnline)
    218     {
    219         this._onLine = isNowOnline;
    220         this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
    221     },
    222 
    223     __proto__: WebInspector.Object.prototype
    224 }
    225 
    226 /**
    227  * @constructor
    228  * @implements {ApplicationCacheAgent.Dispatcher}
    229  */
    230 WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
    231 {
    232     this._applicationCacheModel = applicationCacheModel;
    233 }
    234 
    235 WebInspector.ApplicationCacheDispatcher.prototype = {
    236     /**
    237      * @param {string} frameId
    238      * @param {string} manifestURL
    239      * @param {number} status
    240      */
    241     applicationCacheStatusUpdated: function(frameId, manifestURL, status)
    242     {
    243         this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
    244     },
    245 
    246     /**
    247      * @param {boolean} isNowOnline
    248      */
    249     networkStateUpdated: function(isNowOnline)
    250     {
    251         this._applicationCacheModel._networkStateUpdated(isNowOnline);
    252     }
    253 }
    254