Home | History | Annotate | Download | only in bindings
      1 /*
      2  * Copyright (C) 2012 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  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 /**
     32  * @constructor
     33  * @param {!WebInspector.NetworkWorkspaceBinding} networkWorkspaceBinding
     34  * @param {!WebInspector.Workspace} workspace
     35  */
     36 WebInspector.NetworkUISourceCodeProvider = function(networkWorkspaceBinding, workspace)
     37 {
     38     this._networkWorkspaceBinding = networkWorkspaceBinding;
     39     this._workspace = workspace;
     40     this._processedURLs = {};
     41     WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, this._resourceAdded, this);
     42     WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
     43     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this);
     44     WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this);
     45     WebInspector.targetManager.addModelListener(WebInspector.CSSStyleModel, WebInspector.CSSStyleModel.Events.StyleSheetAdded, this._styleSheetAdded, this);
     46 }
     47 
     48 WebInspector.NetworkUISourceCodeProvider.prototype = {
     49     /**
     50      * @param {!WebInspector.Target} target
     51      */
     52     _populate: function(target)
     53     {
     54         /**
     55          * @param {!WebInspector.ResourceTreeFrame} frame
     56          * @this {WebInspector.NetworkUISourceCodeProvider}
     57          */
     58         function populateFrame(frame)
     59         {
     60             for (var i = 0; i < frame.childFrames.length; ++i)
     61                 populateFrame.call(this, frame.childFrames[i]);
     62 
     63             var resources = frame.resources();
     64             for (var i = 0; i < resources.length; ++i)
     65                 this._addFile(resources[i].url, new WebInspector.NetworkUISourceCodeProvider.FallbackResource(resources[i]));
     66         }
     67 
     68         var mainFrame = target.resourceTreeModel.mainFrame;
     69         if (mainFrame)
     70             populateFrame.call(this, mainFrame);
     71     },
     72 
     73     /**
     74      * @param {!WebInspector.Event} event
     75      */
     76     _parsedScriptSource: function(event)
     77     {
     78         var script = /** @type {!WebInspector.Script} */ (event.data);
     79         if (!script.sourceURL || (script.isInlineScript() && !script.hasSourceURL) || script.isSnippet())
     80             return;
     81         // Filter out embedder injected content scripts.
     82         if (script.isContentScript() && !script.hasSourceURL) {
     83             var parsedURL = new WebInspector.ParsedURL(script.sourceURL);
     84             if (!parsedURL.isValid)
     85                 return;
     86         }
     87         this._addFile(script.sourceURL, script, script.isContentScript());
     88     },
     89 
     90     /**
     91      * @param {!WebInspector.Event} event
     92      */
     93     _styleSheetAdded: function(event)
     94     {
     95         var header = /** @type {!WebInspector.CSSStyleSheetHeader} */ (event.data);
     96         if (header.isInline && header.origin !== "inspector")
     97             return;
     98 
     99         this._addFile(header.resourceURL(), header, false);
    100     },
    101 
    102     /**
    103      * @param {!WebInspector.Event} event
    104      */
    105     _resourceAdded: function(event)
    106     {
    107         var resource = /** @type {!WebInspector.Resource} */ (event.data);
    108         this._addFile(resource.url, new WebInspector.NetworkUISourceCodeProvider.FallbackResource(resource));
    109     },
    110 
    111     /**
    112      * @param {!WebInspector.Event} event
    113      */
    114     _mainFrameNavigated: function(event)
    115     {
    116         var resourceTreeModel = /** @type {!WebInspector.ResourceTreeModel} */ (event.target);
    117         //We assume that mainFrameNavigated could be fired only in one main target
    118         this._reset(resourceTreeModel.target());
    119     },
    120 
    121     /**
    122      * @param {string} url
    123      * @param {!WebInspector.ContentProvider} contentProvider
    124      * @param {boolean=} isContentScript
    125      */
    126     _addFile: function(url, contentProvider, isContentScript)
    127     {
    128         if (this._workspace.hasMappingForURL(url))
    129             return;
    130 
    131         var type = contentProvider.contentType();
    132         if (type !== WebInspector.resourceTypes.Stylesheet && type !== WebInspector.resourceTypes.Document && type !== WebInspector.resourceTypes.Script)
    133             return;
    134         if (this._processedURLs[url])
    135             return;
    136         this._processedURLs[url] = true;
    137         this._networkWorkspaceBinding.addFileForURL(url, contentProvider, isContentScript);
    138     },
    139 
    140     /**
    141      * @param {!WebInspector.Target} target
    142      */
    143     _reset: function(target)
    144     {
    145         this._processedURLs = {};
    146         this._networkWorkspaceBinding.reset();
    147         this._populate(target);
    148     }
    149 }
    150 
    151 /**
    152  * @constructor
    153  * @implements {WebInspector.ContentProvider}
    154  * @param {!WebInspector.Resource} resource
    155  */
    156 WebInspector.NetworkUISourceCodeProvider.FallbackResource = function(resource)
    157 {
    158     this._resource = resource;
    159 }
    160 
    161 WebInspector.NetworkUISourceCodeProvider.FallbackResource.prototype = {
    162 
    163     /**
    164      * @return {string}
    165      */
    166     contentURL: function()
    167     {
    168         return this._resource.contentURL();
    169     },
    170 
    171     /**
    172      * @return {!WebInspector.ResourceType}
    173      */
    174     contentType: function()
    175     {
    176         return this._resource.contentType();
    177     },
    178 
    179     /**
    180      * @param {function(?string)} callback
    181      */
    182     requestContent: function(callback)
    183     {
    184         /**
    185          * @this {WebInspector.NetworkUISourceCodeProvider.FallbackResource}
    186          */
    187         function loadFallbackContent()
    188         {
    189             var scripts = this._resource.target().debuggerModel.scriptsForSourceURL(this._resource.url);
    190             if (!scripts.length) {
    191                 callback(null);
    192                 return;
    193             }
    194 
    195             var contentProvider;
    196             if (this._resource.type === WebInspector.resourceTypes.Document)
    197                 contentProvider = new WebInspector.ConcatenatedScriptsContentProvider(scripts);
    198             else if (this._resource.type === WebInspector.resourceTypes.Script)
    199                 contentProvider = scripts[0];
    200 
    201             console.assert(contentProvider, "Resource content request failed. " + this._resource.url);
    202 
    203             contentProvider.requestContent(callback);
    204         }
    205 
    206         /**
    207          * @param {?string} content
    208          * @this {WebInspector.NetworkUISourceCodeProvider.FallbackResource}
    209          */
    210         function requestContentLoaded(content)
    211         {
    212             if (content)
    213                 callback(content)
    214             else
    215                 loadFallbackContent.call(this);
    216         }
    217 
    218         this._resource.requestContent(requestContentLoaded.bind(this));
    219     },
    220 
    221     /**
    222      * @param {string} query
    223      * @param {boolean} caseSensitive
    224      * @param {boolean} isRegex
    225      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
    226      */
    227     searchInContent: function(query, caseSensitive, isRegex, callback)
    228     {
    229         /**
    230          * @param {?string} content
    231          */
    232         function documentContentLoaded(content)
    233         {
    234             if (content === null) {
    235                 callback([]);
    236                 return;
    237             }
    238 
    239             var result = WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
    240             callback(result);
    241         }
    242 
    243         if (this.contentType() === WebInspector.resourceTypes.Document) {
    244             this.requestContent(documentContentLoaded);
    245             return;
    246         }
    247 
    248         this._resource.searchInContent(query, caseSensitive, isRegex, callback);
    249     }
    250 }
    251 
    252 /**
    253  * @type {!WebInspector.NetworkWorkspaceBinding}
    254  */
    255 WebInspector.networkWorkspaceBinding;
    256