Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / sdk / ContentProviders.js
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  *     * 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  * @implements {WebInspector.ContentProvider}
34  * @param {!Array.<!WebInspector.Script>} scripts
35  */
36 WebInspector.ConcatenatedScriptsContentProvider = function(scripts)
37 {
38     this._scripts = scripts;
39 }
40
41 WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag = "<script>";
42 WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag = "</script>";
43
44 WebInspector.ConcatenatedScriptsContentProvider.prototype = {
45     /**
46      * @return {!Array.<!WebInspector.Script>}
47      */
48     _sortedScripts: function()
49     {
50         if (this._sortedScriptsArray)
51             return this._sortedScriptsArray;
52
53         this._sortedScriptsArray = [];
54
55         var scripts = this._scripts.slice();
56         scripts.sort(function(x, y) { return x.lineOffset - y.lineOffset || x.columnOffset - y.columnOffset; });
57
58         var scriptOpenTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag.length;
59         var scriptCloseTagLength = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag.length;
60
61         this._sortedScriptsArray.push(scripts[0]);
62         for (var i = 1; i < scripts.length; ++i) {
63             var previousScript = this._sortedScriptsArray[this._sortedScriptsArray.length - 1];
64
65             var lineNumber = previousScript.endLine;
66             var columnNumber = previousScript.endColumn + scriptCloseTagLength + scriptOpenTagLength;
67
68             if (lineNumber < scripts[i].lineOffset || (lineNumber === scripts[i].lineOffset && columnNumber <= scripts[i].columnOffset))
69                 this._sortedScriptsArray.push(scripts[i]);
70         }
71         return this._sortedScriptsArray;
72     },
73
74     /**
75      * @return {string}
76      */
77     contentURL: function()
78     {
79         return "";
80     },
81
82     /**
83      * @return {!WebInspector.ResourceType}
84      */
85     contentType: function()
86     {
87         return WebInspector.resourceTypes.Document;
88     },
89
90     /**
91      * @param {function(?string)} callback
92      */
93     requestContent: function(callback)
94     {
95         var scripts = this._sortedScripts();
96         var sources = [];
97
98         /**
99          * @param {?string} content
100          * @this {WebInspector.ConcatenatedScriptsContentProvider}
101          */
102         function didRequestSource(content)
103         {
104             sources.push(content);
105             if (sources.length == scripts.length)
106                 callback(this._concatenateScriptsContent(scripts, sources));
107         }
108         for (var i = 0; i < scripts.length; ++i)
109             scripts[i].requestContent(didRequestSource.bind(this));
110     },
111
112     /**
113      * @param {string} query
114      * @param {boolean} caseSensitive
115      * @param {boolean} isRegex
116      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
117      */
118     searchInContent: function(query, caseSensitive, isRegex, callback)
119     {
120         var results = {};
121         var scripts = this._sortedScripts();
122         var scriptsLeft = scripts.length;
123
124         function maybeCallback()
125         {
126             if (scriptsLeft)
127                 return;
128
129             var result = [];
130             for (var i = 0; i < scripts.length; ++i)
131                 result = result.concat(results[scripts[i].scriptId]);
132             callback(result);
133         }
134
135         /**
136          * @param {!WebInspector.Script} script
137          * @param {!Array.<!PageAgent.SearchMatch>} searchMatches
138          */
139         function searchCallback(script, searchMatches)
140         {
141             results[script.scriptId] = [];
142             for (var i = 0; i < searchMatches.length; ++i) {
143                 var searchMatch = new WebInspector.ContentProvider.SearchMatch(searchMatches[i].lineNumber + script.lineOffset, searchMatches[i].lineContent);
144                 results[script.scriptId].push(searchMatch);
145             }
146             scriptsLeft--;
147             maybeCallback();
148         }
149
150         maybeCallback();
151         for (var i = 0; i < scripts.length; ++i)
152             scripts[i].searchInContent(query, caseSensitive, isRegex, searchCallback.bind(null, scripts[i]));
153     },
154
155     /**
156      * @return {string}
157      */
158     _concatenateScriptsContent: function(scripts, sources)
159     {
160         var content = "";
161         var lineNumber = 0;
162         var columnNumber = 0;
163
164         var scriptOpenTag = WebInspector.ConcatenatedScriptsContentProvider.scriptOpenTag;
165         var scriptCloseTag = WebInspector.ConcatenatedScriptsContentProvider.scriptCloseTag;
166         for (var i = 0; i < scripts.length; ++i) {
167             // Fill the gap with whitespace characters.
168             for (var newLinesCount = scripts[i].lineOffset - lineNumber; newLinesCount > 0; --newLinesCount) {
169                 columnNumber = 0;
170                 content += "\n";
171             }
172             for (var spacesCount = scripts[i].columnOffset - columnNumber - scriptOpenTag.length; spacesCount > 0; --spacesCount)
173                 content += " ";
174
175             // Add script tag.
176             content += scriptOpenTag;
177             content += sources[i];
178             content += scriptCloseTag;
179             lineNumber = scripts[i].endLine;
180             columnNumber = scripts[i].endColumn + scriptCloseTag.length;
181         }
182
183         return content;
184     }
185 }
186
187 /**
188  * @constructor
189  * @implements {WebInspector.ContentProvider}
190  * @param {string} sourceURL
191  * @param {!WebInspector.ResourceType} contentType
192  */
193 WebInspector.CompilerSourceMappingContentProvider = function(sourceURL, contentType)
194 {
195     this._sourceURL = sourceURL;
196     this._contentType = contentType;
197 }
198
199 WebInspector.CompilerSourceMappingContentProvider.prototype = {
200     /**
201      * @return {string}
202      */
203     contentURL: function()
204     {
205         return this._sourceURL;
206     },
207
208     /**
209      * @return {!WebInspector.ResourceType}
210      */
211     contentType: function()
212     {
213         return this._contentType;
214     },
215
216     /**
217      * @param {function(?string)} callback
218      */
219     requestContent: function(callback)
220     {
221         NetworkAgent.loadResourceForFrontend(WebInspector.resourceTreeModel.mainFrame.id, this._sourceURL, undefined, contentLoaded.bind(this));
222
223         /**
224          * @param {?Protocol.Error} error
225          * @param {number} statusCode
226          * @param {!NetworkAgent.Headers} headers
227          * @param {string} content
228          * @this {WebInspector.CompilerSourceMappingContentProvider}
229          */
230         function contentLoaded(error, statusCode, headers, content)
231         {
232             if (error || statusCode >= 400) {
233                 console.error("Could not load content for " + this._sourceURL + " : " + (error || ("HTTP status code: " + statusCode)));
234                 callback(null);
235                 return;
236             }
237
238             callback(content);
239         }
240     },
241
242     /**
243      * @param {string} query
244      * @param {boolean} caseSensitive
245      * @param {boolean} isRegex
246      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
247      */
248     searchInContent: function(query, caseSensitive, isRegex, callback)
249     {
250         this.requestContent(contentLoaded);
251
252         /**
253          * @param {?string} content
254          */
255         function contentLoaded(content)
256         {
257             if (typeof content !== "string") {
258                 callback([]);
259                 return;
260             }
261
262             callback(WebInspector.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex));
263         }
264     }
265 }
266
267 /**
268  * @constructor
269  * @implements {WebInspector.ContentProvider}
270  * @param {!WebInspector.ResourceType} contentType
271  * @param {string} content
272  */
273 WebInspector.StaticContentProvider = function(contentType, content)
274 {
275     this._content = content;
276     this._contentType = contentType;
277 }
278
279 WebInspector.StaticContentProvider.prototype = {
280     /**
281      * @return {string}
282      */
283     contentURL: function()
284     {
285         return "";
286     },
287
288     /**
289      * @return {!WebInspector.ResourceType}
290      */
291     contentType: function()
292     {
293         return this._contentType;
294     },
295
296     /**
297      * @param {function(?string)} callback
298      */
299     requestContent: function(callback)
300     {
301         callback(this._content);
302     },
303
304     /**
305      * @param {string} query
306      * @param {boolean} caseSensitive
307      * @param {boolean} isRegex
308      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
309      */
310     searchInContent: function(query, caseSensitive, isRegex, callback)
311     {
312         /**
313          * @this {WebInspector.StaticContentProvider}
314          */
315         function performSearch()
316         {
317             callback(WebInspector.ContentProvider.performSearchInContent(this._content, query, caseSensitive, isRegex));
318         }
319
320         // searchInContent should call back later.
321         window.setTimeout(performSearch.bind(this), 0);
322     }
323 }