Resource.js 11 KB

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