OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 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 | 14 * its contributors may be used to endorse or promote products derived |
15 * from this software without specific prior written permission. | 15 * from this software without specific prior written permission. |
16 * | 16 * |
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 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 | 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 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 | 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 */ | 27 */ |
28 | |
29 /** | 28 /** |
30 * @constructor | |
31 * @extends {WebInspector.SDKObject} | |
32 * @implements {WebInspector.ContentProvider} | 29 * @implements {WebInspector.ContentProvider} |
33 * @param {!WebInspector.Target} target | 30 * @unrestricted |
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 {?Date} lastModified | |
42 * @param {?number} contentSize | |
43 */ | 31 */ |
44 WebInspector.Resource = function(target, request, url, documentURL, frameId, loa
derId, type, mimeType, lastModified, contentSize) | 32 WebInspector.Resource = class extends WebInspector.SDKObject { |
45 { | 33 /** |
46 WebInspector.SDKObject.call(this, target); | 34 * @param {!WebInspector.Target} target |
| 35 * @param {?WebInspector.NetworkRequest} request |
| 36 * @param {string} url |
| 37 * @param {string} documentURL |
| 38 * @param {!PageAgent.FrameId} frameId |
| 39 * @param {!NetworkAgent.LoaderId} loaderId |
| 40 * @param {!WebInspector.ResourceType} type |
| 41 * @param {string} mimeType |
| 42 * @param {?Date} lastModified |
| 43 * @param {?number} contentSize |
| 44 */ |
| 45 constructor(target, request, url, documentURL, frameId, loaderId, type, mimeTy
pe, lastModified, contentSize) { |
| 46 super(target); |
47 this._request = request; | 47 this._request = request; |
48 this.url = url; | 48 this.url = url; |
49 this._documentURL = documentURL; | 49 this._documentURL = documentURL; |
50 this._frameId = frameId; | 50 this._frameId = frameId; |
51 this._loaderId = loaderId; | 51 this._loaderId = loaderId; |
52 this._type = type || WebInspector.resourceTypes.Other; | 52 this._type = type || WebInspector.resourceTypes.Other; |
53 this._mimeType = mimeType; | 53 this._mimeType = mimeType; |
54 | 54 |
55 this._lastModified = lastModified && lastModified.isValid() ? lastModified :
null; | 55 this._lastModified = lastModified && lastModified.isValid() ? lastModified :
null; |
56 this._contentSize = contentSize; | 56 this._contentSize = contentSize; |
57 | 57 |
58 /** @type {?string} */ this._content; | 58 /** @type {?string} */ this._content; |
59 /** @type {boolean} */ this._contentEncoded; | 59 /** @type {boolean} */ this._contentEncoded; |
60 this._pendingContentCallbacks = []; | 60 this._pendingContentCallbacks = []; |
61 if (this._request && !this._request.finished) | 61 if (this._request && !this._request.finished) |
62 this._request.addEventListener(WebInspector.NetworkRequest.Events.Finish
edLoading, this._requestFinished, this); | 62 this._request.addEventListener(WebInspector.NetworkRequest.Events.Finished
Loading, this._requestFinished, this); |
| 63 } |
| 64 |
| 65 /** |
| 66 * @return {?Date} |
| 67 */ |
| 68 lastModified() { |
| 69 if (this._lastModified || !this._request) |
| 70 return this._lastModified; |
| 71 var lastModifiedHeader = this._request.responseLastModified(); |
| 72 var date = lastModifiedHeader ? new Date(lastModifiedHeader) : null; |
| 73 this._lastModified = date && date.isValid() ? date : null; |
| 74 return this._lastModified; |
| 75 } |
| 76 |
| 77 /** |
| 78 * @return {?number} |
| 79 */ |
| 80 contentSize() { |
| 81 if (typeof this._contentSize === 'number' || !this._request) |
| 82 return this._contentSize; |
| 83 return this._request.resourceSize; |
| 84 } |
| 85 |
| 86 /** |
| 87 * @return {?WebInspector.NetworkRequest} |
| 88 */ |
| 89 get request() { |
| 90 return this._request; |
| 91 } |
| 92 |
| 93 /** |
| 94 * @return {string} |
| 95 */ |
| 96 get url() { |
| 97 return this._url; |
| 98 } |
| 99 |
| 100 /** |
| 101 * @param {string} x |
| 102 */ |
| 103 set url(x) { |
| 104 this._url = x; |
| 105 this._parsedURL = new WebInspector.ParsedURL(x); |
| 106 } |
| 107 |
| 108 get parsedURL() { |
| 109 return this._parsedURL; |
| 110 } |
| 111 |
| 112 /** |
| 113 * @return {string} |
| 114 */ |
| 115 get documentURL() { |
| 116 return this._documentURL; |
| 117 } |
| 118 |
| 119 /** |
| 120 * @return {!PageAgent.FrameId} |
| 121 */ |
| 122 get frameId() { |
| 123 return this._frameId; |
| 124 } |
| 125 |
| 126 /** |
| 127 * @return {!NetworkAgent.LoaderId} |
| 128 */ |
| 129 get loaderId() { |
| 130 return this._loaderId; |
| 131 } |
| 132 |
| 133 /** |
| 134 * @return {string} |
| 135 */ |
| 136 get displayName() { |
| 137 return this._parsedURL.displayName; |
| 138 } |
| 139 |
| 140 /** |
| 141 * @return {!WebInspector.ResourceType} |
| 142 */ |
| 143 resourceType() { |
| 144 return this._request ? this._request.resourceType() : this._type; |
| 145 } |
| 146 |
| 147 /** |
| 148 * @return {string} |
| 149 */ |
| 150 get mimeType() { |
| 151 return this._request ? this._request.mimeType : this._mimeType; |
| 152 } |
| 153 |
| 154 /** |
| 155 * @return {?string} |
| 156 */ |
| 157 get content() { |
| 158 return this._content; |
| 159 } |
| 160 |
| 161 /** |
| 162 * @return {boolean} |
| 163 */ |
| 164 get contentEncoded() { |
| 165 return this._contentEncoded; |
| 166 } |
| 167 |
| 168 /** |
| 169 * @override |
| 170 * @return {string} |
| 171 */ |
| 172 contentURL() { |
| 173 return this._url; |
| 174 } |
| 175 |
| 176 /** |
| 177 * @override |
| 178 * @return {!WebInspector.ResourceType} |
| 179 */ |
| 180 contentType() { |
| 181 if (this.resourceType() === WebInspector.resourceTypes.Document && this.mime
Type.indexOf('javascript') !== -1) |
| 182 return WebInspector.resourceTypes.Script; |
| 183 return this.resourceType(); |
| 184 } |
| 185 |
| 186 /** |
| 187 * @override |
| 188 * @return {!Promise<?string>} |
| 189 */ |
| 190 requestContent() { |
| 191 if (typeof this._content !== 'undefined') |
| 192 return Promise.resolve(this._content); |
| 193 |
| 194 var callback; |
| 195 var promise = new Promise(fulfill => callback = fulfill); |
| 196 this._pendingContentCallbacks.push(callback); |
| 197 if (!this._request || this._request.finished) |
| 198 this._innerRequestContent(); |
| 199 return promise; |
| 200 } |
| 201 |
| 202 /** |
| 203 * @return {string} |
| 204 */ |
| 205 canonicalMimeType() { |
| 206 return this.contentType().canonicalMimeType() || this.mimeType; |
| 207 } |
| 208 |
| 209 /** |
| 210 * @override |
| 211 * @param {string} query |
| 212 * @param {boolean} caseSensitive |
| 213 * @param {boolean} isRegex |
| 214 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callb
ack |
| 215 */ |
| 216 searchInContent(query, caseSensitive, isRegex, callback) { |
| 217 /** |
| 218 * @param {?Protocol.Error} error |
| 219 * @param {!Array.<!DebuggerAgent.SearchMatch>} searchMatches |
| 220 */ |
| 221 function callbackWrapper(error, searchMatches) { |
| 222 callback(searchMatches || []); |
| 223 } |
| 224 |
| 225 if (this.frameId) |
| 226 this.target().pageAgent().searchInResource( |
| 227 this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper
); |
| 228 else |
| 229 callback([]); |
| 230 } |
| 231 |
| 232 /** |
| 233 * @param {!Element} image |
| 234 */ |
| 235 populateImageSource(image) { |
| 236 /** |
| 237 * @param {?string} content |
| 238 * @this {WebInspector.Resource} |
| 239 */ |
| 240 function onResourceContent(content) { |
| 241 var imageSrc = WebInspector.ContentProvider.contentAsDataURL(content, this
._mimeType, true); |
| 242 if (imageSrc === null) |
| 243 imageSrc = this._url; |
| 244 image.src = imageSrc; |
| 245 } |
| 246 |
| 247 this.requestContent().then(onResourceContent.bind(this)); |
| 248 } |
| 249 |
| 250 _requestFinished() { |
| 251 this._request.removeEventListener(WebInspector.NetworkRequest.Events.Finishe
dLoading, this._requestFinished, this); |
| 252 if (this._pendingContentCallbacks.length) |
| 253 this._innerRequestContent(); |
| 254 } |
| 255 |
| 256 _innerRequestContent() { |
| 257 if (this._contentRequested) |
| 258 return; |
| 259 this._contentRequested = true; |
| 260 |
| 261 /** |
| 262 * @param {?Protocol.Error} error |
| 263 * @param {?string} content |
| 264 * @param {boolean} contentEncoded |
| 265 * @this {WebInspector.Resource} |
| 266 */ |
| 267 function contentLoaded(error, content, contentEncoded) { |
| 268 if (error || content === null) { |
| 269 replyWithContent.call(this, null, false); |
| 270 return; |
| 271 } |
| 272 replyWithContent.call(this, content, contentEncoded); |
| 273 } |
| 274 |
| 275 /** |
| 276 * @param {?string} content |
| 277 * @param {boolean} contentEncoded |
| 278 * @this {WebInspector.Resource} |
| 279 */ |
| 280 function replyWithContent(content, contentEncoded) { |
| 281 this._content = content; |
| 282 this._contentEncoded = contentEncoded; |
| 283 var callbacks = this._pendingContentCallbacks.slice(); |
| 284 for (var i = 0; i < callbacks.length; ++i) |
| 285 callbacks[i](this._content); |
| 286 this._pendingContentCallbacks.length = 0; |
| 287 delete this._contentRequested; |
| 288 } |
| 289 |
| 290 /** |
| 291 * @param {?Protocol.Error} error |
| 292 * @param {string} content |
| 293 * @param {boolean} contentEncoded |
| 294 * @this {WebInspector.Resource} |
| 295 */ |
| 296 function resourceContentLoaded(error, content, contentEncoded) { |
| 297 contentLoaded.call(this, error, content, contentEncoded); |
| 298 } |
| 299 |
| 300 if (this.request) { |
| 301 this.request.requestContent().then(requestContentLoaded.bind(this)); |
| 302 return; |
| 303 } |
| 304 |
| 305 /** |
| 306 * @param {?string} content |
| 307 * @this {WebInspector.Resource} |
| 308 */ |
| 309 function requestContentLoaded(content) { |
| 310 contentLoaded.call(this, null, content, this.request.contentEncoded); |
| 311 } |
| 312 |
| 313 this.target().pageAgent().getResourceContent(this.frameId, this.url, resourc
eContentLoaded.bind(this)); |
| 314 } |
| 315 |
| 316 /** |
| 317 * @return {boolean} |
| 318 */ |
| 319 hasTextContent() { |
| 320 if (this._type.isTextType()) |
| 321 return true; |
| 322 if (this._type === WebInspector.resourceTypes.Other) |
| 323 return !!this._content && !this._contentEncoded; |
| 324 return false; |
| 325 } |
63 }; | 326 }; |
64 | |
65 WebInspector.Resource.prototype = { | |
66 /** | |
67 * @return {?Date} | |
68 */ | |
69 lastModified: function() | |
70 { | |
71 if (this._lastModified || !this._request) | |
72 return this._lastModified; | |
73 var lastModifiedHeader = this._request.responseLastModified(); | |
74 var date = lastModifiedHeader ? new Date(lastModifiedHeader) : null; | |
75 this._lastModified = date && date.isValid() ? date : null; | |
76 return this._lastModified; | |
77 }, | |
78 | |
79 /** | |
80 * @return {?number} | |
81 */ | |
82 contentSize: function() | |
83 { | |
84 if (typeof this._contentSize === "number" || !this._request) | |
85 return this._contentSize; | |
86 return this._request.resourceSize; | |
87 }, | |
88 | |
89 /** | |
90 * @return {?WebInspector.NetworkRequest} | |
91 */ | |
92 get request() | |
93 { | |
94 return this._request; | |
95 }, | |
96 | |
97 /** | |
98 * @return {string} | |
99 */ | |
100 get url() | |
101 { | |
102 return this._url; | |
103 }, | |
104 | |
105 set url(x) | |
106 { | |
107 this._url = x; | |
108 this._parsedURL = new WebInspector.ParsedURL(x); | |
109 }, | |
110 | |
111 get parsedURL() | |
112 { | |
113 return this._parsedURL; | |
114 }, | |
115 | |
116 /** | |
117 * @return {string} | |
118 */ | |
119 get documentURL() | |
120 { | |
121 return this._documentURL; | |
122 }, | |
123 | |
124 /** | |
125 * @return {!PageAgent.FrameId} | |
126 */ | |
127 get frameId() | |
128 { | |
129 return this._frameId; | |
130 }, | |
131 | |
132 /** | |
133 * @return {!NetworkAgent.LoaderId} | |
134 */ | |
135 get loaderId() | |
136 { | |
137 return this._loaderId; | |
138 }, | |
139 | |
140 /** | |
141 * @return {string} | |
142 */ | |
143 get displayName() | |
144 { | |
145 return this._parsedURL.displayName; | |
146 }, | |
147 | |
148 /** | |
149 * @return {!WebInspector.ResourceType} | |
150 */ | |
151 resourceType: function() | |
152 { | |
153 return this._request ? this._request.resourceType() : this._type; | |
154 }, | |
155 | |
156 /** | |
157 * @return {string} | |
158 */ | |
159 get mimeType() | |
160 { | |
161 return this._request ? this._request.mimeType : this._mimeType; | |
162 }, | |
163 | |
164 /** | |
165 * @return {?string} | |
166 */ | |
167 get content() | |
168 { | |
169 return this._content; | |
170 }, | |
171 | |
172 /** | |
173 * @return {boolean} | |
174 */ | |
175 get contentEncoded() | |
176 { | |
177 return this._contentEncoded; | |
178 }, | |
179 | |
180 /** | |
181 * @override | |
182 * @return {string} | |
183 */ | |
184 contentURL: function() | |
185 { | |
186 return this._url; | |
187 }, | |
188 | |
189 /** | |
190 * @override | |
191 * @return {!WebInspector.ResourceType} | |
192 */ | |
193 contentType: function() | |
194 { | |
195 if (this.resourceType() === WebInspector.resourceTypes.Document && this.
mimeType.indexOf("javascript") !== -1) | |
196 return WebInspector.resourceTypes.Script; | |
197 return this.resourceType(); | |
198 }, | |
199 | |
200 /** | |
201 * @override | |
202 * @return {!Promise<?string>} | |
203 */ | |
204 requestContent: function() | |
205 { | |
206 if (typeof this._content !== "undefined") | |
207 return Promise.resolve(this._content); | |
208 | |
209 var callback; | |
210 var promise = new Promise(fulfill => callback = fulfill); | |
211 this._pendingContentCallbacks.push(callback); | |
212 if (!this._request || this._request.finished) | |
213 this._innerRequestContent(); | |
214 return promise; | |
215 }, | |
216 | |
217 /** | |
218 * @return {string} | |
219 */ | |
220 canonicalMimeType: function() | |
221 { | |
222 return this.contentType().canonicalMimeType() || this.mimeType; | |
223 }, | |
224 | |
225 /** | |
226 * @override | |
227 * @param {string} query | |
228 * @param {boolean} caseSensitive | |
229 * @param {boolean} isRegex | |
230 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} cal
lback | |
231 */ | |
232 searchInContent: function(query, caseSensitive, isRegex, callback) | |
233 { | |
234 /** | |
235 * @param {?Protocol.Error} error | |
236 * @param {!Array.<!DebuggerAgent.SearchMatch>} searchMatches | |
237 */ | |
238 function callbackWrapper(error, searchMatches) | |
239 { | |
240 callback(searchMatches || []); | |
241 } | |
242 | |
243 if (this.frameId) | |
244 this.target().pageAgent().searchInResource(this.frameId, this.url, q
uery, caseSensitive, isRegex, callbackWrapper); | |
245 else | |
246 callback([]); | |
247 }, | |
248 | |
249 /** | |
250 * @param {!Element} image | |
251 */ | |
252 populateImageSource: function(image) | |
253 { | |
254 /** | |
255 * @param {?string} content | |
256 * @this {WebInspector.Resource} | |
257 */ | |
258 function onResourceContent(content) | |
259 { | |
260 var imageSrc = WebInspector.ContentProvider.contentAsDataURL(content
, this._mimeType, true); | |
261 if (imageSrc === null) | |
262 imageSrc = this._url; | |
263 image.src = imageSrc; | |
264 } | |
265 | |
266 this.requestContent().then(onResourceContent.bind(this)); | |
267 }, | |
268 | |
269 _requestFinished: function() | |
270 { | |
271 this._request.removeEventListener(WebInspector.NetworkRequest.Events.Fin
ishedLoading, this._requestFinished, this); | |
272 if (this._pendingContentCallbacks.length) | |
273 this._innerRequestContent(); | |
274 }, | |
275 | |
276 | |
277 _innerRequestContent: function() | |
278 { | |
279 if (this._contentRequested) | |
280 return; | |
281 this._contentRequested = true; | |
282 | |
283 /** | |
284 * @param {?Protocol.Error} error | |
285 * @param {?string} content | |
286 * @param {boolean} contentEncoded | |
287 * @this {WebInspector.Resource} | |
288 */ | |
289 function contentLoaded(error, content, contentEncoded) | |
290 { | |
291 if (error || content === null) { | |
292 replyWithContent.call(this, null, false); | |
293 return; | |
294 } | |
295 replyWithContent.call(this, content, contentEncoded); | |
296 } | |
297 | |
298 /** | |
299 * @param {?string} content | |
300 * @param {boolean} contentEncoded | |
301 * @this {WebInspector.Resource} | |
302 */ | |
303 function replyWithContent(content, contentEncoded) | |
304 { | |
305 this._content = content; | |
306 this._contentEncoded = contentEncoded; | |
307 var callbacks = this._pendingContentCallbacks.slice(); | |
308 for (var i = 0; i < callbacks.length; ++i) | |
309 callbacks[i](this._content); | |
310 this._pendingContentCallbacks.length = 0; | |
311 delete this._contentRequested; | |
312 } | |
313 | |
314 /** | |
315 * @param {?Protocol.Error} error | |
316 * @param {string} content | |
317 * @param {boolean} contentEncoded | |
318 * @this {WebInspector.Resource} | |
319 */ | |
320 function resourceContentLoaded(error, content, contentEncoded) | |
321 { | |
322 contentLoaded.call(this, error, content, contentEncoded); | |
323 } | |
324 | |
325 if (this.request) { | |
326 this.request.requestContent().then(requestContentLoaded.bind(this)); | |
327 return; | |
328 } | |
329 | |
330 /** | |
331 * @param {?string} content | |
332 * @this {WebInspector.Resource} | |
333 */ | |
334 function requestContentLoaded(content) | |
335 { | |
336 contentLoaded.call(this, null, content, this.request.contentEncoded)
; | |
337 } | |
338 | |
339 this.target().pageAgent().getResourceContent(this.frameId, this.url, res
ourceContentLoaded.bind(this)); | |
340 }, | |
341 | |
342 /** | |
343 * @return {boolean} | |
344 */ | |
345 hasTextContent: function() | |
346 { | |
347 if (this._type.isTextType()) | |
348 return true; | |
349 if (this._type === WebInspector.resourceTypes.Other) | |
350 return !!this._content && !this._contentEncoded; | |
351 return false; | |
352 }, | |
353 | |
354 __proto__: WebInspector.SDKObject.prototype | |
355 }; | |
356 | |
OLD | NEW |