Web Inspector: ResourceContentView.js incorrectly contains call to WebInspector.UIStr...
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Models / Script.js
1 /*
2  * Copyright (C) 2013 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.Script = function(id, range, url, injected, sourceMapURL)
27 {
28     WebInspector.SourceCode.call(this);
29
30     console.assert(id);
31     console.assert(range instanceof WebInspector.TextRange);
32
33     this._id = id || null;
34     this._range = range || null;
35     this._url = url || null;
36     this._injected = injected || false;
37
38     this._resource = this._resolveResource();
39     if (this._resource)
40         this._resource.associateWithScript(this);
41
42     if (sourceMapURL)
43         WebInspector.sourceMapManager.downloadSourceMap(sourceMapURL, this._url, this);
44
45     this._scriptSyntaxTree = null;
46 };
47
48 WebInspector.Script.TypeIdentifier = "script";
49 WebInspector.Script.URLCookieKey = "script-url";
50 WebInspector.Script.DisplayNameCookieKey = "script-display-name";
51
52 WebInspector.Script.resetUniqueDisplayNameNumbers = function()
53 {
54     WebInspector.Script._nextUniqueDisplayNameNumber = 1;
55 };
56
57 WebInspector.Script._nextUniqueDisplayNameNumber = 1;
58
59 WebInspector.Script.prototype = {
60     constructor: WebInspector.Script,
61     __proto__: WebInspector.SourceCode.prototype,
62
63     // Public
64
65     get id()
66     {
67         return this._id;
68     },
69
70     get range()
71     {
72         return this._range;
73     },
74
75     get url()
76     {
77         return this._url;
78     },
79
80     get urlComponents()
81     {
82         if (!this._urlComponents)
83             this._urlComponents = parseURL(this._url);
84         return this._urlComponents;
85     },
86
87     get displayName()
88     {
89         if (this._url)
90             return WebInspector.displayNameForURL(this._url, this.urlComponents);
91
92         // Assign a unique number to the script object so it will stay the same.
93         if (!this._uniqueDisplayNameNumber)
94             this._uniqueDisplayNameNumber = this.constructor._nextUniqueDisplayNameNumber++;
95
96         return WebInspector.UIString("Anonymous Script %d").format(this._uniqueDisplayNameNumber);
97     },
98
99     get injected()
100     {
101         return this._injected;
102     },
103
104     get resource()
105     {
106         return this._resource;
107     },
108
109     get scriptSyntaxTree()
110     {
111         return this._scriptSyntaxTree;
112     },
113
114     requestContentFromBackend: function()
115     {
116         if (!this._id) {
117             // There is no identifier to request content with. Return false to cause the
118             // pending callbacks to get null content.
119             return Promise.reject(new Error("There is no identifier to request content with."));
120         }
121
122         return DebuggerAgent.getScriptSource.promise(this._id);
123     },
124
125     saveIdentityToCookie: function(cookie)
126     {
127         cookie[WebInspector.Script.URLCookieKey] = this.url;
128         cookie[WebInspector.Script.DisplayNameCookieKey] = this.displayName;
129     },
130
131     requestScriptSyntaxTree: function(callback)
132     {
133         if (this._scriptSyntaxTree) {
134             setTimeout(function() { callback(this._scriptSyntaxTree); }.bind(this), 0);
135             return;
136         }
137
138         var makeSyntaxTreeAndCallCallback = function(content)
139         {
140             this._makeSyntaxTree(content);
141             callback(this._scriptSyntaxTree);
142         }.bind(this);
143
144         var content = this.content;
145         if (!content && this._resource && this._resource.type === WebInspector.Resource.Type.Script && this._resource.finished)
146             content = this._resource.content;
147         if (content) {
148             setTimeout(makeSyntaxTreeAndCallCallback, 0, content);
149             return;
150         }
151
152         this.requestContent().then(function(parameters) {
153             makeSyntaxTreeAndCallCallback(parameters.content);
154         }).catch(function(error) {
155             makeSyntaxTreeAndCallCallback(null);
156         });
157     },
158
159     // Private
160
161     _resolveResource: function()
162     {
163         // FIXME: We should be able to associate a Script with a Resource through identifiers,
164         // we shouldn't need to lookup by URL, which is not safe with frames, where there might
165         // be multiple resources with the same URL.
166         // <rdar://problem/13373951> Scripts should be able to associate directly with a Resource
167
168         // No URL, no resource.
169         if (!this._url)
170             return null;
171
172         try {
173             // Try with the Script's full URL.
174             var resource = WebInspector.frameResourceManager.resourceForURL(this.url);
175             if (resource)
176                 return resource;
177
178             // Try with the Script's full decoded URL.
179             var decodedURL = decodeURI(this._url);
180             if (decodedURL !== this._url) {
181                 resource = WebInspector.frameResourceManager.resourceForURL(decodedURL);
182                 if (resource)
183                     return resource;
184             }
185
186             // Next try removing any fragment in the original URL.
187             var urlWithoutFragment = removeURLFragment(this._url);
188             if (urlWithoutFragment !== this._url) {
189                 resource = WebInspector.frameResourceManager.resourceForURL(urlWithoutFragment);
190                 if (resource)
191                     return resource;
192             }
193
194             // Finally try removing any fragment in the decoded URL.
195             var decodedURLWithoutFragment = removeURLFragment(decodedURL);
196             if (decodedURLWithoutFragment !== decodedURL) {
197                 resource = WebInspector.frameResourceManager.resourceForURL(decodedURLWithoutFragment);
198                 if (resource)
199                     return resource;
200             }
201         } catch (e) {
202             // Ignore possible URIErrors.
203         }
204
205         return null;
206     },
207
208     _makeSyntaxTree: function(sourceText)
209     {
210         if (this._scriptSyntaxTree || !sourceText)
211             return;
212
213         this._scriptSyntaxTree = new WebInspector.ScriptSyntaxTree(sourceText, this);
214     }
215 };