Home | History | Annotate | Download | only in sdk
      1 /*
      2  * Copyright (C) 2007, 2008 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  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 /**
     30  * @constructor
     31  * @extends {WebInspector.SDKObject}
     32  * @implements {WebInspector.ContentProvider}
     33  * @param {!WebInspector.Target} target
     34  * @param {?WebInspector.NetworkRequest} request
     35  * @param {string} url
     36  * @param {string} documentURL
     37  * @param {!PageAgent.FrameId} frameId
     38  * @param {!NetworkAgent.LoaderId} loaderId
     39  * @param {!WebInspector.ResourceType} type
     40  * @param {string} mimeType
     41  * @param {boolean=} isHidden
     42  */
     43 WebInspector.Resource = function(target, request, url, documentURL, frameId, loaderId, type, mimeType, isHidden)
     44 {
     45     WebInspector.SDKObject.call(this, target);
     46     this._request = request;
     47     this.url = url;
     48     this._documentURL = documentURL;
     49     this._frameId = frameId;
     50     this._loaderId = loaderId;
     51     this._type = type || WebInspector.resourceTypes.Other;
     52     this._mimeType = mimeType;
     53     this._isHidden = isHidden;
     54 
     55     /** @type {?string} */ this._content;
     56     /** @type {boolean} */ this._contentEncoded;
     57     this._pendingContentCallbacks = [];
     58     if (this._request && !this._request.finished)
     59         this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
     60 }
     61 
     62 WebInspector.Resource.Events = {
     63     MessageAdded: "message-added",
     64     MessagesCleared: "messages-cleared",
     65 }
     66 
     67 /**
     68  * @param {?string} content
     69  * @param {string} mimeType
     70  * @param {boolean} contentEncoded
     71  * @return {?string}
     72  */
     73 WebInspector.Resource.contentAsDataURL = function(content, mimeType, contentEncoded)
     74 {
     75     const maxDataUrlSize = 1024 * 1024;
     76     if (content === null || content.length > maxDataUrlSize)
     77         return null;
     78 
     79     return "data:" + mimeType + (contentEncoded ? ";base64," : ",") + content;
     80 }
     81 
     82 WebInspector.Resource.prototype = {
     83     /**
     84      * @return {?WebInspector.NetworkRequest}
     85      */
     86     get request()
     87     {
     88         return this._request;
     89     },
     90 
     91     /**
     92      * @return {string}
     93      */
     94     get url()
     95     {
     96         return this._url;
     97     },
     98 
     99     set url(x)
    100     {
    101         this._url = x;
    102         this._parsedURL = new WebInspector.ParsedURL(x);
    103     },
    104 
    105     get parsedURL()
    106     {
    107         return this._parsedURL;
    108     },
    109 
    110     /**
    111      * @return {string}
    112      */
    113     get documentURL()
    114     {
    115         return this._documentURL;
    116     },
    117 
    118     /**
    119      * @return {!PageAgent.FrameId}
    120      */
    121     get frameId()
    122     {
    123         return this._frameId;
    124     },
    125 
    126     /**
    127      * @return {!NetworkAgent.LoaderId}
    128      */
    129     get loaderId()
    130     {
    131         return this._loaderId;
    132     },
    133 
    134     /**
    135      * @return {string}
    136      */
    137     get displayName()
    138     {
    139         return this._parsedURL.displayName;
    140     },
    141 
    142     /**
    143      * @return {!WebInspector.ResourceType}
    144      */
    145     get type()
    146     {
    147         return this._request ? this._request.type : this._type;
    148     },
    149 
    150     /**
    151      * @return {string}
    152      */
    153     get mimeType()
    154     {
    155         return this._request ? this._request.mimeType : this._mimeType;
    156     },
    157 
    158     /**
    159      * @return {!Array.<!WebInspector.ConsoleMessage>}
    160      */
    161     get messages()
    162     {
    163         return this._messages || [];
    164     },
    165 
    166     /**
    167      * @param {!WebInspector.ConsoleMessage} msg
    168      */
    169     addMessage: function(msg)
    170     {
    171         if (!msg.isErrorOrWarning() || !msg.messageText)
    172             return;
    173 
    174         if (!this._messages)
    175             this._messages = [];
    176         this._messages.push(msg);
    177         this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg);
    178     },
    179 
    180     /**
    181      * @return {number}
    182      */
    183     get errors()
    184     {
    185         return this._errors || 0;
    186     },
    187 
    188     set errors(x)
    189     {
    190         this._errors = x;
    191     },
    192 
    193     /**
    194      * @return {number}
    195      */
    196     get warnings()
    197     {
    198         return this._warnings || 0;
    199     },
    200 
    201     set warnings(x)
    202     {
    203         this._warnings = x;
    204     },
    205 
    206     clearErrorsAndWarnings: function()
    207     {
    208         this._messages = [];
    209         this._warnings = 0;
    210         this._errors = 0;
    211         this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared);
    212     },
    213 
    214     /**
    215      * @return {?string}
    216      */
    217     get content()
    218     {
    219         return this._content;
    220     },
    221 
    222     /**
    223      * @return {boolean}
    224      */
    225     get contentEncoded()
    226     {
    227         return this._contentEncoded;
    228     },
    229 
    230     /**
    231      * @return {string}
    232      */
    233     contentURL: function()
    234     {
    235         return this._url;
    236     },
    237 
    238     /**
    239      * @return {!WebInspector.ResourceType}
    240      */
    241     contentType: function()
    242     {
    243         return this.type;
    244     },
    245 
    246     /**
    247      * @param {function(?string)} callback
    248      */
    249     requestContent: function(callback)
    250     {
    251         if (typeof this._content !== "undefined") {
    252             callback(this._content);
    253             return;
    254         }
    255 
    256         this._pendingContentCallbacks.push(callback);
    257         if (!this._request || this._request.finished)
    258             this._innerRequestContent();
    259     },
    260 
    261     /**
    262      * @return {string}
    263      */
    264     canonicalMimeType: function()
    265     {
    266         return this.type.canonicalMimeType() || this.mimeType;
    267     },
    268 
    269     /**
    270      * @param {string} query
    271      * @param {boolean} caseSensitive
    272      * @param {boolean} isRegex
    273      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
    274      */
    275     searchInContent: function(query, caseSensitive, isRegex, callback)
    276     {
    277         /**
    278          * @param {?Protocol.Error} error
    279          * @param {!Array.<!PageAgent.SearchMatch>} searchMatches
    280          */
    281         function callbackWrapper(error, searchMatches)
    282         {
    283             callback(searchMatches || []);
    284         }
    285 
    286         if (this.type === WebInspector.resourceTypes.Document) {
    287             callback([]);
    288             return;
    289         }
    290 
    291         if (this.frameId)
    292             this.target().pageAgent().searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
    293         else
    294             callback([]);
    295     },
    296 
    297     /**
    298      * @param {!Element} image
    299      */
    300     populateImageSource: function(image)
    301     {
    302         /**
    303          * @param {?string} content
    304          * @this {WebInspector.Resource}
    305          */
    306         function onResourceContent(content)
    307         {
    308             var imageSrc = WebInspector.Resource.contentAsDataURL(this._content, this.mimeType, this._contentEncoded);
    309             if (imageSrc === null)
    310                 imageSrc = this.url;
    311             image.src = imageSrc;
    312         }
    313 
    314         this.requestContent(onResourceContent.bind(this));
    315     },
    316 
    317     _requestFinished: function()
    318     {
    319         this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
    320         if (this._pendingContentCallbacks.length)
    321             this._innerRequestContent();
    322     },
    323 
    324 
    325     _innerRequestContent: function()
    326     {
    327         if (this._contentRequested)
    328             return;
    329         this._contentRequested = true;
    330 
    331         /**
    332          * @param {?Protocol.Error} error
    333          * @param {?string} content
    334          * @param {boolean} contentEncoded
    335          * @this {WebInspector.Resource}
    336          */
    337         function contentLoaded(error, content, contentEncoded)
    338         {
    339             if (error || content === null) {
    340                 replyWithContent.call(this, null, false);
    341                 return;
    342             }
    343             replyWithContent.call(this, content, contentEncoded);
    344         }
    345 
    346         /**
    347          * @param {?string} content
    348          * @param {boolean} contentEncoded
    349          * @this {WebInspector.Resource}
    350          */
    351         function replyWithContent(content, contentEncoded)
    352         {
    353             this._content = content;
    354             this._contentEncoded = contentEncoded;
    355             var callbacks = this._pendingContentCallbacks.slice();
    356             for (var i = 0; i < callbacks.length; ++i)
    357                 callbacks[i](this._content);
    358             this._pendingContentCallbacks.length = 0;
    359             delete this._contentRequested;
    360         }
    361 
    362         /**
    363          * @param {?Protocol.Error} error
    364          * @param {string} content
    365          * @param {boolean} contentEncoded
    366          * @this {WebInspector.Resource}
    367          */
    368         function resourceContentLoaded(error, content, contentEncoded)
    369         {
    370             contentLoaded.call(this, error, content, contentEncoded);
    371         }
    372 
    373         if (this.request) {
    374             this.request.requestContent(requestContentLoaded.bind(this));
    375             return;
    376         }
    377 
    378         /**
    379          * @param {?string} content
    380          * @this {WebInspector.Resource}
    381          */
    382         function requestContentLoaded(content)
    383         {
    384             contentLoaded.call(this, null, content, this.request.contentEncoded);
    385         }
    386 
    387         this.target().pageAgent().getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this));
    388     },
    389 
    390     /**
    391      * @return {boolean}
    392      */
    393     isHidden: function()
    394     {
    395         return !!this._isHidden;
    396     },
    397 
    398     __proto__: WebInspector.SDKObject.prototype
    399 }
    400 
    401