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.Object} 32 * @implements {WebInspector.ContentProvider} 33 * @param {?WebInspector.NetworkRequest} request 34 * @param {string} url 35 * @param {string} documentURL 36 * @param {!PageAgent.FrameId} frameId 37 * @param {!NetworkAgent.LoaderId} loaderId 38 * @param {!WebInspector.ResourceType} type 39 * @param {string} mimeType 40 * @param {boolean=} isHidden 41 */ 42 WebInspector.Resource = function(request, url, documentURL, frameId, loaderId, type, mimeType, isHidden) 43 { 44 this._request = request; 45 this.url = url; 46 this._documentURL = documentURL; 47 this._frameId = frameId; 48 this._loaderId = loaderId; 49 this._type = type || WebInspector.resourceTypes.Other; 50 this._mimeType = mimeType; 51 this._isHidden = isHidden; 52 53 /** @type {?string} */ this._content; 54 /** @type {boolean} */ this._contentEncoded; 55 this._pendingContentCallbacks = []; 56 if (this._request && !this._request.finished) 57 this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this); 58 } 59 60 WebInspector.Resource.Events = { 61 MessageAdded: "message-added", 62 MessagesCleared: "messages-cleared", 63 } 64 65 WebInspector.Resource.prototype = { 66 /** 67 * @return {?WebInspector.NetworkRequest} 68 */ 69 get request() 70 { 71 return this._request; 72 }, 73 74 /** 75 * @return {string} 76 */ 77 get url() 78 { 79 return this._url; 80 }, 81 82 set url(x) 83 { 84 this._url = x; 85 this._parsedURL = new WebInspector.ParsedURL(x); 86 }, 87 88 get parsedURL() 89 { 90 return this._parsedURL; 91 }, 92 93 /** 94 * @return {string} 95 */ 96 get documentURL() 97 { 98 return this._documentURL; 99 }, 100 101 /** 102 * @return {!PageAgent.FrameId} 103 */ 104 get frameId() 105 { 106 return this._frameId; 107 }, 108 109 /** 110 * @return {!NetworkAgent.LoaderId} 111 */ 112 get loaderId() 113 { 114 return this._loaderId; 115 }, 116 117 /** 118 * @return {string} 119 */ 120 get displayName() 121 { 122 return this._parsedURL.displayName; 123 }, 124 125 /** 126 * @return {!WebInspector.ResourceType} 127 */ 128 get type() 129 { 130 return this._request ? this._request.type : this._type; 131 }, 132 133 /** 134 * @return {string} 135 */ 136 get mimeType() 137 { 138 return this._request ? this._request.mimeType : this._mimeType; 139 }, 140 141 /** 142 * @return {!Array.<!WebInspector.ConsoleMessage>} 143 */ 144 get messages() 145 { 146 return this._messages || []; 147 }, 148 149 /** 150 * @param {!WebInspector.ConsoleMessage} msg 151 */ 152 addMessage: function(msg) 153 { 154 if (!msg.isErrorOrWarning() || !msg.messageText) 155 return; 156 157 if (!this._messages) 158 this._messages = []; 159 this._messages.push(msg); 160 this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg); 161 }, 162 163 /** 164 * @return {number} 165 */ 166 get errors() 167 { 168 return this._errors || 0; 169 }, 170 171 set errors(x) 172 { 173 this._errors = x; 174 }, 175 176 /** 177 * @return {number} 178 */ 179 get warnings() 180 { 181 return this._warnings || 0; 182 }, 183 184 set warnings(x) 185 { 186 this._warnings = x; 187 }, 188 189 clearErrorsAndWarnings: function() 190 { 191 this._messages = []; 192 this._warnings = 0; 193 this._errors = 0; 194 this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared); 195 }, 196 197 /** 198 * @return {?string} 199 */ 200 get content() 201 { 202 return this._content; 203 }, 204 205 /** 206 * @return {boolean} 207 */ 208 get contentEncoded() 209 { 210 return this._contentEncoded; 211 }, 212 213 /** 214 * @return {string} 215 */ 216 contentURL: function() 217 { 218 return this._url; 219 }, 220 221 /** 222 * @return {!WebInspector.ResourceType} 223 */ 224 contentType: function() 225 { 226 return this.type; 227 }, 228 229 /** 230 * @param {function(?string)} callback 231 */ 232 requestContent: function(callback) 233 { 234 if (typeof this._content !== "undefined") { 235 callback(this._content); 236 return; 237 } 238 239 this._pendingContentCallbacks.push(callback); 240 if (!this._request || this._request.finished) 241 this._innerRequestContent(); 242 }, 243 244 /** 245 * @return {string} 246 */ 247 canonicalMimeType: function() 248 { 249 return this.type.canonicalMimeType() || this.mimeType; 250 }, 251 252 /** 253 * @param {string} query 254 * @param {boolean} caseSensitive 255 * @param {boolean} isRegex 256 * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback 257 */ 258 searchInContent: function(query, caseSensitive, isRegex, callback) 259 { 260 /** 261 * @param {?Protocol.Error} error 262 * @param {!Array.<!PageAgent.SearchMatch>} searchMatches 263 */ 264 function callbackWrapper(error, searchMatches) 265 { 266 callback(searchMatches || []); 267 } 268 269 if (this.type === WebInspector.resourceTypes.Document) { 270 callback([]); 271 return; 272 } 273 274 if (this.frameId) 275 PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper); 276 else 277 callback([]); 278 }, 279 280 /** 281 * @param {!Element} image 282 */ 283 populateImageSource: function(image) 284 { 285 /** 286 * @param {?string} content 287 * @this {WebInspector.Resource} 288 */ 289 function onResourceContent(content) 290 { 291 var imageSrc = WebInspector.contentAsDataURL(this._content, this.mimeType, this._contentEncoded); 292 if (imageSrc === null) 293 imageSrc = this.url; 294 image.src = imageSrc; 295 } 296 297 this.requestContent(onResourceContent.bind(this)); 298 }, 299 300 _requestFinished: function() 301 { 302 this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this); 303 if (this._pendingContentCallbacks.length) 304 this._innerRequestContent(); 305 }, 306 307 308 _innerRequestContent: function() 309 { 310 if (this._contentRequested) 311 return; 312 this._contentRequested = true; 313 314 /** 315 * @param {?Protocol.Error} error 316 * @param {?string} content 317 * @param {boolean} contentEncoded 318 * @this {WebInspector.Resource} 319 */ 320 function contentLoaded(error, content, contentEncoded) 321 { 322 if (error || content === null) { 323 replyWithContent.call(this, null, false); 324 return; 325 } 326 replyWithContent.call(this, content, contentEncoded); 327 } 328 329 /** 330 * @param {?string} content 331 * @param {boolean} contentEncoded 332 * @this {WebInspector.Resource} 333 */ 334 function replyWithContent(content, contentEncoded) 335 { 336 this._content = content; 337 this._contentEncoded = contentEncoded; 338 var callbacks = this._pendingContentCallbacks.slice(); 339 for (var i = 0; i < callbacks.length; ++i) 340 callbacks[i](this._content); 341 this._pendingContentCallbacks.length = 0; 342 delete this._contentRequested; 343 } 344 345 /** 346 * @param {?Protocol.Error} error 347 * @param {string} content 348 * @param {boolean} contentEncoded 349 * @this {WebInspector.Resource} 350 */ 351 function resourceContentLoaded(error, content, contentEncoded) 352 { 353 contentLoaded.call(this, error, content, contentEncoded); 354 } 355 356 if (this.request) { 357 this.request.requestContent(requestContentLoaded.bind(this)); 358 return; 359 } 360 361 /** 362 * @param {?string} content 363 * @this {WebInspector.Resource} 364 */ 365 function requestContentLoaded(content) 366 { 367 contentLoaded.call(this, null, content, this.request.contentEncoded); 368 } 369 370 PageAgent.getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this)); 371 }, 372 373 /** 374 * @return {boolean} 375 */ 376 isHidden: function() 377 { 378 return !!this._isHidden; 379 }, 380 381 __proto__: WebInspector.Object.prototype 382 } 383 384