Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / bindings / ScriptSnippetModel.js
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 /**
32  * @constructor
33  * @extends {WebInspector.Object}
34  * @implements {WebInspector.TargetManager.Observer}
35  * @param {!WebInspector.Workspace} workspace
36  */
37 WebInspector.ScriptSnippetModel = function(workspace)
38 {
39     this._workspace = workspace;
40     /** @type {!Object.<string, !WebInspector.UISourceCode>} */
41     this._uiSourceCodeForSnippetId = {};
42     /** @type {!Map.<!WebInspector.UISourceCode, string>} */
43     this._snippetIdForUISourceCode = new Map();
44
45     /** @type {!Map.<!WebInspector.Target, !WebInspector.SnippetScriptMapping>} */
46     this._mappingForTarget = new Map();
47     this._snippetStorage = new WebInspector.SnippetStorage("script", "Script snippet #");
48     this._lastSnippetEvaluationIndexSetting = WebInspector.settings.createSetting("lastSnippetEvaluationIndex", 0);
49     this._projectId = WebInspector.projectTypes.Snippets + ":";
50     this._projectDelegate = new WebInspector.SnippetsProjectDelegate(workspace, this, this._projectId);
51     this._project = this._workspace.project(this._projectId);
52     this._loadSnippets();
53     WebInspector.targetManager.observeTargets(this);
54 }
55
56 WebInspector.ScriptSnippetModel.prototype = {
57
58     /**
59      * @param {!WebInspector.Target} target
60      */
61     targetAdded: function(target)
62     {
63         this._mappingForTarget.set(target, new WebInspector.SnippetScriptMapping(target, this));
64     },
65
66     /**
67      * @param {!WebInspector.Target} target
68      */
69     targetRemoved: function(target)
70     {
71         this._mappingForTarget.remove(target);
72     },
73
74     /**
75      * @param {!WebInspector.Target} target
76      * @return {!WebInspector.SnippetScriptMapping|undefined}
77      */
78     snippetScriptMapping: function(target) {
79         return this._mappingForTarget.get(target);
80     },
81
82     /**
83      * @param {!WebInspector.Script} script
84      */
85     addScript: function(script)
86     {
87         this._mappingForTarget.get(script.target()).addScript(script);
88     },
89
90     /**
91      * @param {!WebInspector.Target} target
92      * @return {!WebInspector.SnippetScriptMapping}
93      */
94     createSnippetScriptMapping: function(target)
95     {
96         return new WebInspector.SnippetScriptMapping(target, this);
97     },
98
99     /**
100      * @return {!WebInspector.Project}
101      */
102     project: function()
103     {
104         return this._project;
105     },
106
107     _loadSnippets: function()
108     {
109         var snippets = this._snippetStorage.snippets();
110         for (var i = 0; i < snippets.length; ++i)
111             this._addScriptSnippet(snippets[i]);
112     },
113
114     /**
115      * @param {string} content
116      * @return {string}
117      */
118     createScriptSnippet: function(content)
119     {
120         var snippet = this._snippetStorage.createSnippet();
121         snippet.content = content;
122         return this._addScriptSnippet(snippet);
123     },
124
125     /**
126      * @param {!WebInspector.Snippet} snippet
127      * @return {string}
128      */
129     _addScriptSnippet: function(snippet)
130     {
131         var path = this._projectDelegate.addSnippet(snippet.name, new WebInspector.SnippetContentProvider(snippet));
132         var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path);
133         if (!uiSourceCode) {
134             console.assert(uiSourceCode);
135             return "";
136         }
137         uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
138         this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id);
139         var breakpointLocations = this._removeBreakpoints(uiSourceCode);
140         this._restoreBreakpoints(uiSourceCode, breakpointLocations);
141         this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
142         return path;
143     },
144
145     /**
146      * @param {!WebInspector.Event} event
147      */
148     _workingCopyChanged: function(event)
149     {
150         var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.target);
151         this._scriptSnippetEdited(uiSourceCode);
152     },
153
154     /**
155      * @param {string} path
156      */
157     deleteScriptSnippet: function(path)
158     {
159         var uiSourceCode = this._workspace.uiSourceCode(this._projectId, path);
160         if (!uiSourceCode)
161             return;
162         var snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || "";
163         var snippet = this._snippetStorage.snippetForId(snippetId);
164         this._snippetStorage.deleteSnippet(snippet);
165         this._removeBreakpoints(uiSourceCode);
166         this._releaseSnippetScript(uiSourceCode);
167         delete this._uiSourceCodeForSnippetId[snippet.id];
168         this._snippetIdForUISourceCode.remove(uiSourceCode);
169         this._projectDelegate.removeFile(snippet.name);
170     },
171
172     /**
173      * @param {string} name
174      * @param {string} newName
175      * @param {function(boolean, string=)} callback
176      */
177     renameScriptSnippet: function(name, newName, callback)
178     {
179         newName = newName.trim();
180         if (!newName || newName.indexOf("/") !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) {
181             callback(false);
182             return;
183         }
184         var snippet = this._snippetStorage.snippetForName(name);
185         console.assert(snippet, "Snippet '" + name + "' was not found.");
186         var uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id];
187         console.assert(uiSourceCode, "No uiSourceCode was found for snippet '" + name + "'.");
188
189         var breakpointLocations = this._removeBreakpoints(uiSourceCode);
190         snippet.name = newName;
191         this._restoreBreakpoints(uiSourceCode, breakpointLocations);
192         callback(true, newName);
193     },
194
195     /**
196      * @param {string} name
197      * @param {string} newContent
198      */
199     _setScriptSnippetContent: function(name, newContent)
200     {
201         var snippet = this._snippetStorage.snippetForName(name);
202         snippet.content = newContent;
203     },
204
205     /**
206      * @param {!WebInspector.UISourceCode} uiSourceCode
207      */
208     _scriptSnippetEdited: function(uiSourceCode)
209     {
210         var breakpointLocations = this._removeBreakpoints(uiSourceCode);
211         this._releaseSnippetScript(uiSourceCode);
212         this._restoreBreakpoints(uiSourceCode, breakpointLocations);
213         this._mappingForTarget.valuesArray().forEach(function(mapping) {mapping._restoreBreakpoints(uiSourceCode, breakpointLocations)});
214     },
215
216     /**
217      * @return {number}
218      */
219     _nextEvaluationIndex: function()
220     {
221         var evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
222         this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
223         return evaluationIndex;
224     },
225
226     /**
227      * @param {!WebInspector.ExecutionContext} executionContext
228      * @param {!WebInspector.UISourceCode} uiSourceCode
229      */
230     evaluateScriptSnippet: function(executionContext, uiSourceCode)
231     {
232         var breakpointLocations = this._removeBreakpoints(uiSourceCode);
233         this._releaseSnippetScript(uiSourceCode);
234         this._restoreBreakpoints(uiSourceCode, breakpointLocations);
235
236         var target = executionContext.target();
237         var evaluationIndex = this._nextEvaluationIndex();
238         var mapping = this._mappingForTarget.get(target);
239         mapping._setEvaluationIndex(evaluationIndex, uiSourceCode);
240         var evaluationUrl = mapping._evaluationSourceURL(uiSourceCode);
241         var expression = uiSourceCode.workingCopy();
242         WebInspector.console.show();
243         target.debuggerAgent().compileScript(expression, evaluationUrl, executionContext.id, compileCallback.bind(this, target));
244
245         /**
246          * @param {!WebInspector.Target} target
247          * @param {?string} error
248          * @param {!DebuggerAgent.ScriptId=} scriptId
249          * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
250          * @this {WebInspector.ScriptSnippetModel}
251          */
252         function compileCallback(target, error, scriptId, exceptionDetails)
253         {
254             if (!uiSourceCode || this._mappingForTarget.get(target).evaluationIndex(uiSourceCode) !== evaluationIndex)
255                 return;
256
257             if (error) {
258                 console.error(error);
259                 return;
260             }
261
262             if (!scriptId) {
263                 this._printRunOrCompileScriptResultFailure(target, exceptionDetails, evaluationUrl);
264                 return;
265             }
266
267             var breakpointLocations = this._removeBreakpoints(uiSourceCode);
268             this._restoreBreakpoints(uiSourceCode, breakpointLocations);
269
270             this._runScript(scriptId, executionContext, evaluationUrl);
271         }
272     },
273
274     /**
275      * @param {!DebuggerAgent.ScriptId} scriptId
276      * @param {!WebInspector.ExecutionContext} executionContext
277      * @param {?string=} sourceURL
278      */
279     _runScript: function(scriptId, executionContext, sourceURL)
280     {
281         var target = executionContext.target();
282         target.debuggerAgent().runScript(scriptId, executionContext.id, "console", false, runCallback.bind(this, target));
283
284         /**
285          * @param {!WebInspector.Target} target
286          * @param {?string} error
287          * @param {?RuntimeAgent.RemoteObject} result
288          * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
289          * @this {WebInspector.ScriptSnippetModel}
290          */
291         function runCallback(target, error, result, exceptionDetails)
292         {
293             if (error) {
294                 console.error(error);
295                 return;
296             }
297
298             if (!exceptionDetails)
299                 this._printRunScriptResult(target, result, sourceURL);
300             else
301                 this._printRunOrCompileScriptResultFailure(target, exceptionDetails, sourceURL);
302         }
303     },
304
305     /**
306      * @param {!WebInspector.Target} target
307      * @param {?RuntimeAgent.RemoteObject} result
308      * @param {?string=} sourceURL
309      */
310     _printRunScriptResult: function(target, result, sourceURL)
311     {
312         var consoleMessage = new WebInspector.ConsoleMessage(
313             target,
314             WebInspector.ConsoleMessage.MessageSource.JS,
315             WebInspector.ConsoleMessage.MessageLevel.Log,
316             "",
317             undefined,
318             sourceURL,
319             undefined,
320             undefined,
321             undefined,
322             [result],
323             undefined);
324         target.consoleModel.addMessage(consoleMessage);
325     },
326
327     /**
328      * @param {!WebInspector.Target} target
329      * @param {?DebuggerAgent.ExceptionDetails=} exceptionDetails
330      * @param {?string=} sourceURL
331      */
332     _printRunOrCompileScriptResultFailure: function(target, exceptionDetails, sourceURL)
333     {
334         var consoleMessage = new WebInspector.ConsoleMessage(
335             target,
336             exceptionDetails.source,
337             WebInspector.ConsoleMessage.MessageLevel.Error,
338             exceptionDetails.text,
339             undefined,
340             sourceURL,
341             exceptionDetails.line,
342             exceptionDetails.column,
343             undefined,
344             undefined,
345             exceptionDetails.stackTrace);
346         target.consoleModel.addMessage(consoleMessage);
347     },
348
349     /**
350      * @param {!WebInspector.UISourceCode} uiSourceCode
351      * @return {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>}
352      */
353     _removeBreakpoints: function(uiSourceCode)
354     {
355         var breakpointLocations = WebInspector.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
356         for (var i = 0; i < breakpointLocations.length; ++i)
357             breakpointLocations[i].breakpoint.remove();
358         return breakpointLocations;
359     },
360
361     /**
362      * @param {!WebInspector.UISourceCode} uiSourceCode
363      * @param {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>} breakpointLocations
364      */
365     _restoreBreakpoints: function(uiSourceCode, breakpointLocations)
366     {
367         for (var i = 0; i < breakpointLocations.length; ++i) {
368             var uiLocation = breakpointLocations[i].uiLocation;
369             var breakpoint = breakpointLocations[i].breakpoint;
370             WebInspector.breakpointManager.setBreakpoint(uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled());
371         }
372     },
373
374     /**
375      * @param {!WebInspector.UISourceCode} uiSourceCode
376      */
377     _releaseSnippetScript: function(uiSourceCode)
378     {
379         this._mappingForTarget.valuesArray().forEach(function(mapping) {mapping._releaseSnippetScript(uiSourceCode)});
380     },
381
382     /**
383      * @param {string} sourceURL
384      * @return {?string}
385      */
386     _snippetIdForSourceURL: function(sourceURL)
387     {
388         var snippetPrefix = WebInspector.Script.snippetSourceURLPrefix;
389         if (!sourceURL.startsWith(snippetPrefix))
390             return null;
391         var splitURL = sourceURL.substring(snippetPrefix.length).split("_");
392         var snippetId = splitURL[0];
393         return snippetId;
394     },
395
396     __proto__: WebInspector.Object.prototype
397 }
398
399 /**
400  * @constructor
401  * @implements {WebInspector.DebuggerSourceMapping}
402  * @param {!WebInspector.Target} target
403  * @param {!WebInspector.ScriptSnippetModel} scriptSnippetModel
404  */
405 WebInspector.SnippetScriptMapping = function(target, scriptSnippetModel)
406 {
407     this._target = target;
408     this._scriptSnippetModel = scriptSnippetModel;
409     /** @type {!Object.<string, !WebInspector.UISourceCode>} */
410     this._uiSourceCodeForScriptId = {};
411     /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Script>} */
412     this._scriptForUISourceCode = new Map();
413     /** @type {!Map.<!WebInspector.UISourceCode, number>} */
414     this._evaluationIndexForUISourceCode = new Map();
415     target.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._reset, this);
416 }
417
418 WebInspector.SnippetScriptMapping.prototype = {
419     /**
420      * @param {!WebInspector.UISourceCode} uiSourceCode
421      */
422     _releaseSnippetScript: function(uiSourceCode)
423     {
424         var script = this._scriptForUISourceCode.get(uiSourceCode);
425         if (!script)
426             return;
427
428         delete this._uiSourceCodeForScriptId[script.scriptId];
429         this._scriptForUISourceCode.remove(uiSourceCode);
430         this._evaluationIndexForUISourceCode.remove(uiSourceCode);
431     },
432
433     /**
434      +* @param {number} evaluationIndex
435      * @param {!WebInspector.UISourceCode} uiSourceCode
436      */
437     _setEvaluationIndex: function(evaluationIndex, uiSourceCode)
438     {
439         this._evaluationIndexForUISourceCode.set(uiSourceCode, evaluationIndex);
440     },
441
442     /**
443      * @param {!WebInspector.UISourceCode} uiSourceCode
444      * @return {number|undefined}
445      */
446     evaluationIndex: function(uiSourceCode)
447     {
448         return this._evaluationIndexForUISourceCode.get(uiSourceCode);
449     },
450
451     /**
452      * @param {!WebInspector.UISourceCode} uiSourceCode
453      * @return {string}
454      */
455     _evaluationSourceURL: function(uiSourceCode)
456     {
457         var evaluationSuffix = "_" + this._evaluationIndexForUISourceCode.get(uiSourceCode);
458         var snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);
459         return WebInspector.Script.snippetSourceURLPrefix + snippetId + evaluationSuffix;
460     },
461
462     _reset: function()
463     {
464         this._uiSourceCodeForScriptId = {};
465         this._scriptForUISourceCode.clear();
466         this._evaluationIndexForUISourceCode.clear();
467     },
468
469     /**
470      * @param {!WebInspector.DebuggerModel.Location} rawLocation
471      * @return {?WebInspector.UILocation}
472      */
473     rawLocationToUILocation: function(rawLocation)
474     {
475         var debuggerModelLocation = /** @type {!WebInspector.DebuggerModel.Location} */(rawLocation);
476         var uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
477         if (!uiSourceCode)
478             return null;
479
480         return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
481     },
482
483     /**
484      * @param {!WebInspector.UISourceCode} uiSourceCode
485      * @param {number} lineNumber
486      * @param {number} columnNumber
487      * @return {?WebInspector.DebuggerModel.Location}
488      */
489     uiLocationToRawLocation: function(uiSourceCode, lineNumber, columnNumber)
490     {
491         var script = this._scriptForUISourceCode.get(uiSourceCode);
492         if (!script)
493             return null;
494
495         return this._target.debuggerModel.createRawLocation(script, lineNumber, columnNumber);
496     },
497
498     /**
499      * @param {string} sourceURL
500      * @return {?string}
501      */
502     snippetIdForSourceURL: function(sourceURL)
503     {
504         return this._scriptSnippetModel._snippetIdForSourceURL(sourceURL);
505     },
506
507     /**
508      * @param {!WebInspector.Script} script
509      */
510     addScript: function(script)
511     {
512         var snippetId = this.snippetIdForSourceURL(script.sourceURL);
513         if (!snippetId)
514             return;
515         var uiSourceCode = this._scriptSnippetModel._uiSourceCodeForSnippetId[snippetId];
516
517         if (!uiSourceCode || this._evaluationSourceURL(uiSourceCode) !== script.sourceURL)
518             return;
519
520         console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
521         WebInspector.debuggerWorkspaceBinding.setSourceMapping(this._target, uiSourceCode, this);
522         this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
523         this._scriptForUISourceCode.set(uiSourceCode, script);
524         WebInspector.debuggerWorkspaceBinding.pushSourceMapping(script, this);
525     },
526
527     /**
528      * @param {!WebInspector.UISourceCode} uiSourceCode
529      * @param {!Array.<!{breakpoint: !WebInspector.BreakpointManager.Breakpoint, uiLocation: !WebInspector.UILocation}>} breakpointLocations
530      */
531     _restoreBreakpoints: function(uiSourceCode, breakpointLocations)
532     {
533         var script = this._scriptForUISourceCode.get(uiSourceCode);
534         if (!script)
535             return;
536
537         var rawLocation = /** @type {!WebInspector.DebuggerModel.Location} */ (script.target().debuggerModel.createRawLocation(script, 0, 0));
538         var scriptUISourceCode = WebInspector.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation).uiSourceCode;
539         if (scriptUISourceCode)
540             this._scriptSnippetModel._restoreBreakpoints(scriptUISourceCode, breakpointLocations);
541     },
542
543     /**
544      * @return {boolean}
545      */
546     isIdentity: function()
547     {
548         return false;
549     },
550
551     /**
552      * @param {!WebInspector.UISourceCode} uiSourceCode
553      * @param {number} lineNumber
554      * @return {boolean}
555      */
556     uiLineHasMapping: function(uiSourceCode, lineNumber)
557     {
558         return true;
559     }
560 }
561
562 /**
563  * @constructor
564  * @implements {WebInspector.ContentProvider}
565  * @param {!WebInspector.Snippet} snippet
566  */
567 WebInspector.SnippetContentProvider = function(snippet)
568 {
569     this._snippet = snippet;
570 }
571
572 WebInspector.SnippetContentProvider.prototype = {
573     /**
574      * @return {string}
575      */
576     contentURL: function()
577     {
578         return "";
579     },
580
581     /**
582      * @return {!WebInspector.ResourceType}
583      */
584     contentType: function()
585     {
586         return WebInspector.resourceTypes.Script;
587     },
588
589     /**
590      * @param {function(?string)} callback
591      */
592     requestContent: function(callback)
593     {
594         callback(this._snippet.content);
595     },
596
597     /**
598      * @param {string} query
599      * @param {boolean} caseSensitive
600      * @param {boolean} isRegex
601      * @param {function(!Array.<!WebInspector.ContentProvider.SearchMatch>)} callback
602      */
603     searchInContent: function(query, caseSensitive, isRegex, callback)
604     {
605         /**
606          * @this {WebInspector.SnippetContentProvider}
607          */
608         function performSearch()
609         {
610             callback(WebInspector.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex));
611         }
612
613         // searchInContent should call back later.
614         window.setTimeout(performSearch.bind(this), 0);
615     }
616 }
617
618 /**
619  * @constructor
620  * @extends {WebInspector.ContentProviderBasedProjectDelegate}
621  * @param {!WebInspector.Workspace} workspace
622  * @param {!WebInspector.ScriptSnippetModel} model
623  * @param {string} id
624  */
625 WebInspector.SnippetsProjectDelegate = function(workspace, model, id)
626 {
627     WebInspector.ContentProviderBasedProjectDelegate.call(this, workspace, id, WebInspector.projectTypes.Snippets);
628     this._model = model;
629 }
630
631 WebInspector.SnippetsProjectDelegate.prototype = {
632     /**
633      * @param {string} name
634      * @param {!WebInspector.ContentProvider} contentProvider
635      * @return {string}
636      */
637     addSnippet: function(name, contentProvider)
638     {
639         return this.addContentProvider("", name, name, name, contentProvider);
640     },
641
642     /**
643      * @return {boolean}
644      */
645     canSetFileContent: function()
646     {
647         return true;
648     },
649
650     /**
651      * @param {string} path
652      * @param {string} newContent
653      * @param {function(?string)} callback
654      */
655     setFileContent: function(path, newContent, callback)
656     {
657         this._model._setScriptSnippetContent(path, newContent);
658         callback("");
659     },
660
661     /**
662      * @return {boolean}
663      */
664     canRename: function()
665     {
666         return true;
667     },
668
669     /**
670      * @param {string} path
671      * @param {string} newName
672      * @param {function(boolean, string=)} callback
673      */
674     performRename: function(path, newName, callback)
675     {
676         this._model.renameScriptSnippet(path, newName, callback);
677     },
678
679     /**
680      * @param {string} path
681      * @param {?string} name
682      * @param {string} content
683      * @param {function(?string)} callback
684      */
685     createFile: function(path, name, content, callback)
686     {
687         var filePath = this._model.createScriptSnippet(content);
688         callback(filePath);
689     },
690
691     /**
692      * @param {string} path
693      */
694     deleteFile: function(path)
695     {
696         this._model.deleteScriptSnippet(path);
697     },
698
699     __proto__: WebInspector.ContentProviderBasedProjectDelegate.prototype
700 }
701
702 /**
703  * @type {!WebInspector.ScriptSnippetModel}
704  */
705 WebInspector.scriptSnippetModel;