ScriptSnippetModel.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /*
  2. * Copyright (C) 2012 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. * @constructor
  32. * @extends {WebInspector.Object}
  33. * @param {WebInspector.Workspace} workspace
  34. */
  35. WebInspector.ScriptSnippetModel = function(workspace)
  36. {
  37. this._workspace = workspace;
  38. /** @type {!Object.<string, WebInspector.UISourceCode>} */
  39. this._uiSourceCodeForScriptId = {};
  40. /** @type {!Map.<WebInspector.UISourceCode, WebInspector.Script>} */
  41. this._scriptForUISourceCode = new Map();
  42. /** @type {!Object.<string, WebInspector.UISourceCode>} */
  43. this._uiSourceCodeForSnippetId = {};
  44. /** @type {!Map.<WebInspector.UISourceCode, string>} */
  45. this._snippetIdForUISourceCode = new Map();
  46. this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #");
  47. this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
  48. this._snippetScriptMapping = new WebInspector.SnippetScriptMapping(this);
  49. this._projectDelegate = new WebInspector.SnippetsProjectDelegate(this);
  50. this._project = this._workspace.addProject(this._projectDelegate);
  51. this.reset();
  52. WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this);
  53. }
  54. WebInspector.ScriptSnippetModel.prototype = {
  55. /**
  56. * @return {WebInspector.SnippetScriptMapping}
  57. */
  58. get scriptMapping()
  59. {
  60. return this._snippetScriptMapping;
  61. },
  62. /**
  63. * @return {WebInspector.Project}
  64. */
  65. project: function()
  66. {
  67. return this._project;
  68. },
  69. _loadSnippets: function()
  70. {
  71. var snippets = this._snippetStorage.snippets();
  72. for (var i = 0; i < snippets.length; ++i)
  73. this._addScriptSnippet(snippets[i]);
  74. },
  75. /**
  76. * @return {string}
  77. */
  78. createScriptSnippet: function()
  79. {
  80. var snippet = this._snippetStorage.createSnippet();
  81. return this._addScriptSnippet(snippet);
  82. },
  83. /**
  84. * @param {WebInspector.Snippet} snippet
  85. * @return {string}
  86. */
  87. _addScriptSnippet: function(snippet)
  88. {
  89. var path = this._projectDelegate.addSnippet(snippet.name, new WebInspector.SnippetContentProvider(snippet));
  90. var uiSourceCode = this._workspace.uiSourceCode(this._projectDelegate.id(), path);
  91. var scriptFile = new WebInspector.SnippetScriptFile(this, uiSourceCode);
  92. uiSourceCode.setScriptFile(scriptFile);
  93. this._snippetIdForUISourceCode.put(uiSourceCode, snippet.id);
  94. uiSourceCode.setSourceMapping(this._snippetScriptMapping);
  95. this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
  96. return path;
  97. },
  98. /**
  99. * @param {string} path
  100. */
  101. deleteScriptSnippet: function(path)
  102. {
  103. var uiSourceCode = this._workspace.uiSourceCode(this._projectDelegate.id(), path);
  104. var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || "";
  105. var snippet = this._snippetStorage.snippetForId(snippetId);
  106. this._snippetStorage.deleteSnippet(snippet);
  107. this._removeBreakpoints(uiSourceCode);
  108. this._releaseSnippetScript(uiSourceCode);
  109. delete this._uiSourceCodeForSnippetId[snippet.id];
  110. this._snippetIdForUISourceCode.remove(uiSourceCode);
  111. this._projectDelegate.removeFile(snippet.name);
  112. },
  113. /**
  114. * @param {string} name
  115. * @param {string} newName
  116. * @param {function(boolean, string=)} callback
  117. */
  118. renameScriptSnippet: function(name, newName, callback)
  119. {
  120. newName = newName.trim();
  121. if (!newName || newName.indexOf("/") !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) {
  122. callback(false);
  123. return;
  124. }
  125. var snippet = this._snippetStorage.snippetForName(name);
  126. console.assert(snippet, "Snippet '" + name + "' was not found.");
  127. var uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id];
  128. console.assert(uiSourceCode, "No uiSourceCode was found for snippet '" + name + "'.");
  129. var breakpointLocations = this._removeBreakpoints(uiSourceCode);
  130. snippet.name = newName;
  131. this._restoreBreakpoints(uiSourceCode, breakpointLocations);
  132. callback(true, newName);
  133. },
  134. /**
  135. * @param {string} name
  136. * @param {string} newContent
  137. */
  138. _setScriptSnippetContent: function(name, newContent)
  139. {
  140. var snippet = this._snippetStorage.snippetForName(name);
  141. snippet.content = newContent;
  142. },
  143. /**
  144. * @param {WebInspector.UISourceCode} uiSourceCode
  145. */
  146. _scriptSnippetEdited: function(uiSourceCode)
  147. {
  148. var script = this._scriptForUISourceCode.get(uiSourceCode);
  149. if (!script)
  150. return;
  151. var breakpointLocations = this._removeBreakpoints(uiSourceCode);
  152. this._releaseSnippetScript(uiSourceCode);
  153. this._restoreBreakpoints(uiSourceCode, breakpointLocations);
  154. var scriptUISourceCode = script.rawLocationToUILocation(0, 0).uiSourceCode;
  155. if (scriptUISourceCode)
  156. this._restoreBreakpoints(scriptUISourceCode, breakpointLocations);
  157. },
  158. /**
  159. * @param {string} snippetId
  160. * @return {number}
  161. */
  162. _nextEvaluationIndex: function(snippetId)
  163. {
  164. var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
  165. this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
  166. return evaluationIndex;
  167. },
  168. /**
  169. * @param {WebInspector.UISourceCode} uiSourceCode
  170. */
  171. evaluateScriptSnippet: function(uiSourceCode)
  172. {
  173. var breakpointLocations = this._removeBreakpoints(uiSourceCode);
  174. this._releaseSnippetScript(uiSourceCode);
  175. this._restoreBreakpoints(uiSourceCode, breakpointLocations);
  176. var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || "";
  177. var evaluationIndex = this._nextEvaluationIndex(snippetId);
  178. uiSourceCode._evaluationIndex = evaluationIndex;
  179. var evaluationUrl = this._evaluationSourceURL(uiSourceCode);
  180. var expression = uiSourceCode.workingCopy();
  181. // In order to stop on the breakpoints during the snippet evaluation we need to compile and run it separately.
  182. // If separate compilation and execution is not supported by the port we fall back to evaluation in console.
  183. // In case we don't need that since debugger is already paused.
  184. // We do the same when we are stopped on the call frame since debugger is already paused and can not stop on breakpoint anymore.
  185. if (WebInspector.debuggerModel.selectedCallFrame()) {
  186. expression = uiSourceCode.workingCopy() + "\n//# sourceURL=" + evaluationUrl + "\n";
  187. WebInspector.evaluateInConsole(expression, true);
  188. return;
  189. }
  190. WebInspector.showConsole();
  191. DebuggerAgent.compileScript(expression, evaluationUrl, compileCallback.bind(this));
  192. /**
  193. * @param {?string} error
  194. * @param {string=} scriptId
  195. * @param {string=} syntaxErrorMessage
  196. */
  197. function compileCallback(error, scriptId, syntaxErrorMessage)
  198. {
  199. if (!uiSourceCode || uiSourceCode._evaluationIndex !== evaluationIndex)
  200. return;
  201. if (error) {
  202. console.error(error);
  203. return;
  204. }
  205. if (!scriptId) {
  206. var consoleMessage = WebInspector.ConsoleMessage.create(
  207. WebInspector.ConsoleMessage.MessageSource.JS,
  208. WebInspector.ConsoleMessage.MessageLevel.Error,
  209. syntaxErrorMessage || "");
  210. WebInspector.console.addMessage(consoleMessage);
  211. return;
  212. }
  213. var breakpointLocations = this._removeBreakpoints(uiSourceCode);
  214. this._restoreBreakpoints(uiSourceCode, breakpointLocations);
  215. this._runScript(scriptId);
  216. }
  217. },
  218. /**
  219. * @param {DebuggerAgent.ScriptId} scriptId
  220. */
  221. _runScript: function(scriptId)
  222. {
  223. var currentExecutionContext = WebInspector.runtimeModel.currentExecutionContext();
  224. DebuggerAgent.runScript(scriptId, currentExecutionContext ? currentExecutionContext.id : undefined, "console", false, runCallback.bind(this));
  225. /**
  226. * @param {?string} error
  227. * @param {?RuntimeAgent.RemoteObject} result
  228. * @param {boolean=} wasThrown
  229. */
  230. function runCallback(error, result, wasThrown)
  231. {
  232. if (error) {
  233. console.error(error);
  234. return;
  235. }
  236. this._printRunScriptResult(result, wasThrown);
  237. }
  238. },
  239. /**
  240. * @param {?RuntimeAgent.RemoteObject} result
  241. * @param {boolean=} wasThrown
  242. */
  243. _printRunScriptResult: function(result, wasThrown)
  244. {
  245. var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
  246. var message = WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.JS, level, "", undefined, undefined, undefined, undefined, undefined, [result]);
  247. WebInspector.console.addMessage(message)
  248. },
  249. /**
  250. * @param {WebInspector.DebuggerModel.Location} rawLocation
  251. * @return {WebInspector.UILocation}
  252. */
  253. _rawLocationToUILocation: function(rawLocation)
  254. {
  255. var uiSourceCode = this._uiSourceCodeForScriptId[rawLocation.scriptId];
  256. if (!uiSourceCode)
  257. return null;
  258. return new WebInspector.UILocation(uiSourceCode, rawLocation.lineNumber, rawLocation.columnNumber || 0);
  259. },
  260. /**
  261. * @param {WebInspector.UISourceCode} uiSourceCode
  262. * @param {number} lineNumber
  263. * @param {number} columnNumber
  264. * @return {WebInspector.DebuggerModel.Location}
  265. */
  266. _uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
  267. {
  268. var script = this._scriptForUISourceCode.get(uiSourceCode);
  269. if (!script)
  270. return null;
  271. return WebInspector.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
  272. },
  273. /**
  274. * @param {WebInspector.Script} script
  275. */
  276. _addScript: function(script)
  277. {
  278. var snippetId = this._snippetIdForSourceURL(script.sourceURL);
  279. if (!snippetId)
  280. return;
  281. var uiSourceCode = this._uiSourceCodeForSnippetId[snippetId];
  282. if (!uiSourceCode || this._evaluationSourceURL(uiSourceCode) !== script.sourceURL)
  283. return;
  284. console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
  285. this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
  286. this._scriptForUISourceCode.put(uiSourceCode, script);
  287. uiSourceCode.scriptFile().setHasDivergedFromVM(false);
  288. script.pushSourceMapping(this._snippetScriptMapping);
  289. },
  290. /**
  291. * @param {WebInspector.UISourceCode} uiSourceCode
  292. * @return {Array.<Object>}
  293. */
  294. _removeBreakpoints: function(uiSourceCode)
  295. {
  296. var breakpointLocations = WebInspector.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
  297. for (var i = 0; i < breakpointLocations.length; ++i)
  298. breakpointLocations[i].breakpoint.remove();
  299. return breakpointLocations;
  300. },
  301. /**
  302. * @param {WebInspector.UISourceCode} uiSourceCode
  303. * @param {Array.<Object>} breakpointLocations
  304. */
  305. _restoreBreakpoints: function(uiSourceCode, breakpointLocations)
  306. {
  307. for (var i = 0; i < breakpointLocations.length; ++i) {
  308. var uiLocation = breakpointLocations[i].uiLocation;
  309. var breakpoint = breakpointLocations[i].breakpoint;
  310. WebInspector.breakpointManager.setBreakpoint(uiSourceCode, uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled());
  311. }
  312. },
  313. /**
  314. * @param {WebInspector.UISourceCode} uiSourceCode
  315. */
  316. _releaseSnippetScript: function(uiSourceCode)
  317. {
  318. var script = this._scriptForUISourceCode.get(uiSourceCode);
  319. if (!script)
  320. return null;
  321. uiSourceCode.scriptFile().setIsDivergingFromVM(true);
  322. uiSourceCode.scriptFile().setHasDivergedFromVM(true);
  323. delete this._uiSourceCodeForScriptId[script.scriptId];
  324. this._scriptForUISourceCode.remove(uiSourceCode);
  325. delete uiSourceCode._evaluationIndex;
  326. uiSourceCode.scriptFile().setIsDivergingFromVM(false);
  327. },
  328. _debuggerReset: function()
  329. {
  330. for (var snippetId in this._uiSourceCodeForSnippetId) {
  331. var uiSourceCode = this._uiSourceCodeForSnippetId[snippetId];
  332. this._releaseSnippetScript(uiSourceCode);
  333. }
  334. },
  335. /**
  336. * @param {WebInspector.UISourceCode} uiSourceCode
  337. * @return {string}
  338. */
  339. _evaluationSourceURL: function(uiSourceCode)
  340. {
  341. var evaluationSuffix = "_" + uiSourceCode._evaluationIndex;
  342. var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode);
  343. return WebInspector.Script.snippetSourceURLPrefix + snippetId + evaluationSuffix;
  344. },
  345. /**
  346. * @param {string} sourceURL
  347. * @return {string|null}
  348. */
  349. _snippetIdForSourceURL: function(sourceURL)
  350. {
  351. var snippetPrefix = WebInspector.Script.snippetSourceURLPrefix;
  352. if (!sourceURL.startsWith(snippetPrefix))
  353. return null;
  354. var splitURL = sourceURL.substring(snippetPrefix.length).split("_");
  355. var snippetId = splitURL[0];
  356. return snippetId;
  357. },
  358. reset: function()
  359. {
  360. /** @type {!Object.<string, WebInspector.UISourceCode>} */
  361. this._uiSourceCodeForScriptId = {};
  362. this._scriptForUISourceCode = new Map();
  363. /** @type {!Object.<string, WebInspector.UISourceCode>} */
  364. this._uiSourceCodeForSnippetId = {};
  365. this._snippetIdForUISourceCode = new Map();
  366. this._projectDelegate.reset();
  367. this._loadSnippets();
  368. },
  369. __proto__: WebInspector.Object.prototype
  370. }
  371. /**
  372. * @constructor
  373. * @implements {WebInspector.ScriptFile}
  374. * @extends {WebInspector.Object}
  375. * @param {WebInspector.ScriptSnippetModel} scriptSnippetModel
  376. * @param {WebInspector.UISourceCode} uiSourceCode
  377. */
  378. WebInspector.SnippetScriptFile = function(scriptSnippetModel, uiSourceCode)
  379. {
  380. WebInspector.ScriptFile.call(this);
  381. this._scriptSnippetModel = scriptSnippetModel;
  382. this._uiSourceCode = uiSourceCode;
  383. this._hasDivergedFromVM = true;
  384. this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
  385. }
  386. WebInspector.SnippetScriptFile.prototype = {
  387. /**
  388. * @return {boolean}
  389. */
  390. hasDivergedFromVM: function()
  391. {
  392. return this._hasDivergedFromVM;
  393. },
  394. /**
  395. * @param {boolean} hasDivergedFromVM
  396. */
  397. setHasDivergedFromVM: function(hasDivergedFromVM)
  398. {
  399. this._hasDivergedFromVM = hasDivergedFromVM;
  400. },
  401. /**
  402. * @return {boolean}
  403. */
  404. isDivergingFromVM: function()
  405. {
  406. return this._isDivergingFromVM;
  407. },
  408. checkMapping: function()
  409. {
  410. },
  411. /**
  412. * @return {boolean}
  413. */
  414. isMergingToVM: function()
  415. {
  416. return false;
  417. },
  418. /**
  419. * @param {boolean} isDivergingFromVM
  420. */
  421. setIsDivergingFromVM: function(isDivergingFromVM)
  422. {
  423. this._isDivergingFromVM = isDivergingFromVM;
  424. },
  425. _workingCopyChanged: function()
  426. {
  427. this._scriptSnippetModel._scriptSnippetEdited(this._uiSourceCode);
  428. },
  429. __proto__: WebInspector.Object.prototype
  430. }
  431. /**
  432. * @constructor
  433. * @implements {WebInspector.ScriptSourceMapping}
  434. * @param {WebInspector.ScriptSnippetModel} scriptSnippetModel
  435. */
  436. WebInspector.SnippetScriptMapping = function(scriptSnippetModel)
  437. {
  438. this._scriptSnippetModel = scriptSnippetModel;
  439. }
  440. WebInspector.SnippetScriptMapping.prototype = {
  441. /**
  442. * @param {WebInspector.RawLocation} rawLocation
  443. * @return {WebInspector.UILocation}
  444. */
  445. rawLocationToUILocation: function(rawLocation)
  446. {
  447. var debuggerModelLocation = /** @type {WebInspector.DebuggerModel.Location} */(rawLocation);
  448. return this._scriptSnippetModel._rawLocationToUILocation(debuggerModelLocation);
  449. },
  450. /**
  451. * @param {WebInspector.UISourceCode} uiSourceCode
  452. * @param {number} lineNumber
  453. * @param {number} columnNumber
  454. * @return {WebInspector.DebuggerModel.Location}
  455. */
  456. uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
  457. {
  458. return this._scriptSnippetModel._uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
  459. },
  460. /**
  461. * @return {boolean}
  462. */
  463. isIdentity: function()
  464. {
  465. return true;
  466. },
  467. /**
  468. * @param {string} sourceURL
  469. * @return {string|null}
  470. */
  471. snippetIdForSourceURL: function(sourceURL)
  472. {
  473. return this._scriptSnippetModel._snippetIdForSourceURL(sourceURL);
  474. },
  475. /**
  476. * @param {WebInspector.Script} script
  477. */
  478. addScript: function(script)
  479. {
  480. this._scriptSnippetModel._addScript(script);
  481. }
  482. }
  483. /**
  484. * @constructor
  485. * @implements {WebInspector.ContentProvider}
  486. * @param {WebInspector.Snippet} snippet
  487. */
  488. WebInspector.SnippetContentProvider = function(snippet)
  489. {
  490. this._snippet = snippet;
  491. }
  492. WebInspector.SnippetContentProvider.prototype = {
  493. /**
  494. * @return {string}
  495. */
  496. contentURL: function()
  497. {
  498. return "";
  499. },
  500. /**
  501. * @return {WebInspector.ResourceType}
  502. */
  503. contentType: function()
  504. {
  505. return WebInspector.resourceTypes.Script;
  506. },
  507. /**
  508. * @param {function(?string,boolean,string)} callback
  509. */
  510. requestContent: function(callback)
  511. {
  512. callback(this._snippet.content, false, WebInspector.resourceTypes.Script.canonicalMimeType());
  513. },
  514. /**
  515. * @param {string} query
  516. * @param {boolean} caseSensitive
  517. * @param {boolean} isRegex
  518. * @param {function(Array.<WebInspector.ContentProvider.SearchMatch>)} callback
  519. */
  520. searchInContent: function(query, caseSensitive, isRegex, callback)
  521. {
  522. function performSearch()
  523. {
  524. callback(WebInspector.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex));
  525. }
  526. // searchInContent should call back later.
  527. window.setTimeout(performSearch.bind(this), 0);
  528. },
  529. __proto__: WebInspector.ContentProvider.prototype
  530. }
  531. /**
  532. * @constructor
  533. * @extends {WebInspector.ContentProviderBasedProjectDelegate}
  534. * @param {WebInspector.ScriptSnippetModel} model
  535. */
  536. WebInspector.SnippetsProjectDelegate = function(model)
  537. {
  538. WebInspector.ContentProviderBasedProjectDelegate.call(this, WebInspector.projectTypes.Snippets);
  539. this._model = model;
  540. }
  541. WebInspector.SnippetsProjectDelegate.prototype = {
  542. /**
  543. * @override
  544. * @return {string}
  545. */
  546. id: function()
  547. {
  548. return WebInspector.projectTypes.Snippets + ":";
  549. },
  550. /**
  551. * @param {string} name
  552. * @param {WebInspector.ContentProvider} contentProvider
  553. * @return {string}
  554. */
  555. addSnippet: function(name, contentProvider)
  556. {
  557. return this.addContentProvider("", name, name, contentProvider, true, false);
  558. },
  559. /**
  560. * @return {boolean}
  561. */
  562. canSetFileContent: function()
  563. {
  564. return true;
  565. },
  566. /**
  567. * @param {string} path
  568. * @param {string} newContent
  569. * @param {function(?string)} callback
  570. */
  571. setFileContent: function(path, newContent, callback)
  572. {
  573. this._model._setScriptSnippetContent(path, newContent);
  574. callback("");
  575. },
  576. /**
  577. * @return {boolean}
  578. */
  579. canRename: function()
  580. {
  581. return true;
  582. },
  583. /**
  584. * @param {string} path
  585. * @param {string} newName
  586. * @param {function(boolean, string=)} callback
  587. */
  588. performRename: function(path, newName, callback)
  589. {
  590. this._model.renameScriptSnippet(path, newName, callback);
  591. },
  592. /**
  593. * @param {string} path
  594. * @param {?string} name
  595. * @param {function(?string)} callback
  596. */
  597. createFile: function(path, name, callback)
  598. {
  599. var filePath = this._model.createScriptSnippet();
  600. callback(filePath);
  601. },
  602. /**
  603. * @param {string} path
  604. */
  605. deleteFile: function(path)
  606. {
  607. this._model.deleteScriptSnippet(path);
  608. },
  609. __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
  610. }
  611. /**
  612. * @type {?WebInspector.ScriptSnippetModel}
  613. */
  614. WebInspector.scriptSnippetModel = null;