Home | History | Annotate | Download | only in sdk
      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  */
     34 WebInspector.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 
     53 WebInspector.ApplicationCacheModel.EventTypes = {
     54     FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
     55     FrameManifestAdded: "FrameManifestAdded",
     56     FrameManifestRemoved: "FrameManifestRemoved",
     57     NetworkStateChanged: "NetworkStateChanged"
     58 }
     59 
     60 WebInspector.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  */
    238 WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
    239 {
    240     this._applicationCacheModel = applicationCacheModel;
    241 }
    242 
    243 WebInspector.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