mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 13:44:39 +08:00
This adds a _serializedFileOperation method to IsolatedFileSystem which waits for all pending DevTools reads/writes to finish for a file path. Change-Id: I5a1dd55dbe40ae0bf8335bc8e1994c1209fcc999 Reviewed-on: https://chromium-review.googlesource.com/991201 Commit-Queue: Joel Einbinder <einbinder@chromium.org> Reviewed-by: Andrey Lushnikov <lushnikov@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549628} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 70c0896fddc9b319eb3728438c6959c35907b35a
609 lines
20 KiB
JavaScript
609 lines
20 KiB
JavaScript
/*
|
|
* Copyright (C) 2012 Google Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following disclaimer
|
|
* in the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of Google Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
/**
|
|
* @unrestricted
|
|
* @implements {SDK.SDKModelObserver<!SDK.DebuggerModel>}
|
|
* @implements {Bindings.DebuggerSourceMapping}
|
|
*/
|
|
Snippets.ScriptSnippetModel = class extends Common.Object {
|
|
/**
|
|
* @param {!Workspace.Workspace} workspace
|
|
*/
|
|
constructor(workspace) {
|
|
super();
|
|
this._workspace = workspace;
|
|
/** @type {!Object.<string, !Workspace.UISourceCode>} */
|
|
this._uiSourceCodeForSnippetId = {};
|
|
/** @type {!Map.<!Workspace.UISourceCode, string>} */
|
|
this._snippetIdForUISourceCode = new Map();
|
|
|
|
/** @type {!Map.<!SDK.DebuggerModel, !Snippets.SnippetScriptMapping>} */
|
|
this._mappingForDebuggerModel = new Map();
|
|
this._snippetStorage = new Snippets.SnippetStorage('script', 'Script snippet #');
|
|
this._lastSnippetEvaluationIndexSetting = Common.settings.createSetting('lastSnippetEvaluationIndex', 0);
|
|
this._project = new Snippets.SnippetsProject(workspace, this);
|
|
this._loadSnippets();
|
|
SDK.targetManager.observeModels(SDK.DebuggerModel, this);
|
|
Bindings.debuggerWorkspaceBinding.addSourceMapping(this);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {!SDK.DebuggerModel} debuggerModel
|
|
*/
|
|
modelAdded(debuggerModel) {
|
|
this._mappingForDebuggerModel.set(debuggerModel, new Snippets.SnippetScriptMapping(debuggerModel, this));
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {!SDK.DebuggerModel} debuggerModel
|
|
*/
|
|
modelRemoved(debuggerModel) {
|
|
this._mappingForDebuggerModel.remove(debuggerModel);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {!SDK.DebuggerModel.Location} rawLocation
|
|
* @return {?Workspace.UILocation}
|
|
*/
|
|
rawLocationToUILocation(rawLocation) {
|
|
const mapping = this._mappingForDebuggerModel.get(rawLocation.debuggerModel);
|
|
if (!mapping)
|
|
return null;
|
|
return mapping.rawLocationToUILocation(rawLocation);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @param {number} lineNumber
|
|
* @param {number} columnNumber
|
|
* @return {?SDK.DebuggerModel.Location}
|
|
*/
|
|
uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
|
|
for (const mapping of this._mappingForDebuggerModel.values()) {
|
|
const rawLocation = mapping.uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber);
|
|
if (rawLocation)
|
|
return rawLocation;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.DebuggerModel} debuggerModel
|
|
* @return {!Snippets.SnippetScriptMapping|undefined}
|
|
*/
|
|
snippetScriptMapping(debuggerModel) {
|
|
return this._mappingForDebuggerModel.get(debuggerModel);
|
|
}
|
|
|
|
/**
|
|
* @return {!Workspace.Project}
|
|
*/
|
|
project() {
|
|
return this._project;
|
|
}
|
|
|
|
_loadSnippets() {
|
|
for (const snippet of this._snippetStorage.snippets())
|
|
this._addScriptSnippet(snippet);
|
|
}
|
|
|
|
/**
|
|
* @param {string} content
|
|
* @return {!Workspace.UISourceCode}
|
|
*/
|
|
createScriptSnippet(content) {
|
|
const snippet = this._snippetStorage.createSnippet();
|
|
snippet.content = content;
|
|
return this._addScriptSnippet(snippet);
|
|
}
|
|
|
|
/**
|
|
* @param {!Snippets.Snippet} snippet
|
|
* @return {!Workspace.UISourceCode}
|
|
*/
|
|
_addScriptSnippet(snippet) {
|
|
const uiSourceCode = this._project.addSnippet(snippet.name, new Snippets.SnippetContentProvider(snippet));
|
|
uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this._workingCopyChanged, this);
|
|
this._snippetIdForUISourceCode.set(uiSourceCode, snippet.id);
|
|
const breakpointLocations = this._removeBreakpoints(uiSourceCode);
|
|
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
|
|
this._uiSourceCodeForSnippetId[snippet.id] = uiSourceCode;
|
|
return uiSourceCode;
|
|
}
|
|
|
|
/**
|
|
* @param {!Common.Event} event
|
|
*/
|
|
_workingCopyChanged(event) {
|
|
const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
|
|
this._scriptSnippetEdited(uiSourceCode);
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
deleteScriptSnippet(uiSourceCode) {
|
|
const snippetId = this._snippetIdForUISourceCode.get(uiSourceCode) || '';
|
|
const snippet = this._snippetStorage.snippetForId(snippetId);
|
|
if (!snippet)
|
|
return;
|
|
this._snippetStorage.deleteSnippet(snippet);
|
|
this._removeBreakpoints(uiSourceCode);
|
|
this._releaseSnippetScript(uiSourceCode);
|
|
delete this._uiSourceCodeForSnippetId[snippet.id];
|
|
this._snippetIdForUISourceCode.remove(uiSourceCode);
|
|
this._project.removeFile(snippet.name);
|
|
}
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {string} newName
|
|
* @param {function(boolean, string=)} callback
|
|
*/
|
|
renameScriptSnippet(name, newName, callback) {
|
|
newName = newName.trim();
|
|
if (!newName || newName.indexOf('/') !== -1 || name === newName || this._snippetStorage.snippetForName(newName)) {
|
|
callback(false);
|
|
return;
|
|
}
|
|
const snippet = this._snippetStorage.snippetForName(name);
|
|
console.assert(snippet, 'Snippet \'' + name + '\' was not found.');
|
|
const uiSourceCode = this._uiSourceCodeForSnippetId[snippet.id];
|
|
console.assert(uiSourceCode, 'No uiSourceCode was found for snippet \'' + name + '\'.');
|
|
|
|
const breakpointLocations = this._removeBreakpoints(uiSourceCode);
|
|
snippet.name = newName;
|
|
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
|
|
callback(true, newName);
|
|
}
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {string} newContent
|
|
*/
|
|
_setScriptSnippetContent(name, newContent) {
|
|
const snippet = this._snippetStorage.snippetForName(name);
|
|
snippet.content = newContent;
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
_scriptSnippetEdited(uiSourceCode) {
|
|
const breakpointLocations = this._removeBreakpoints(uiSourceCode);
|
|
this._releaseSnippetScript(uiSourceCode);
|
|
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
|
|
this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) {
|
|
mapping._restoreBreakpoints(uiSourceCode, breakpointLocations);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @return {number}
|
|
*/
|
|
_nextEvaluationIndex() {
|
|
const evaluationIndex = this._lastSnippetEvaluationIndexSetting.get() + 1;
|
|
this._lastSnippetEvaluationIndexSetting.set(evaluationIndex);
|
|
return evaluationIndex;
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.ExecutionContext} executionContext
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @return {!Promise<undefined>}
|
|
*/
|
|
async evaluateScriptSnippet(executionContext, uiSourceCode) {
|
|
console.assert(uiSourceCode.project().type() === Workspace.projectTypes.Snippets);
|
|
let breakpointLocations = this._removeBreakpoints(uiSourceCode);
|
|
this._releaseSnippetScript(uiSourceCode);
|
|
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
|
|
|
|
const runtimeModel = executionContext.runtimeModel;
|
|
const debuggerModel = executionContext.debuggerModel;
|
|
const evaluationIndex = this._nextEvaluationIndex();
|
|
const mapping = this._mappingForDebuggerModel.get(debuggerModel);
|
|
mapping._setEvaluationIndex(evaluationIndex, uiSourceCode);
|
|
const evaluationUrl = mapping._evaluationSourceURL(uiSourceCode);
|
|
await uiSourceCode.requestContent();
|
|
const expression = uiSourceCode.workingCopy();
|
|
Common.console.show();
|
|
const result = await runtimeModel.compileScript(expression, '', true, executionContext.id);
|
|
if (!result || mapping.evaluationIndex(uiSourceCode) !== evaluationIndex)
|
|
return;
|
|
const script = /** @type {!SDK.Script} */ (
|
|
debuggerModel.scriptForId(/** @type {string} */ (result.scriptId || result.exceptionDetails.scriptId)));
|
|
mapping._addScript(script, uiSourceCode);
|
|
if (!result.scriptId) {
|
|
this._printRunOrCompileScriptResultFailure(
|
|
runtimeModel, /** @type {!Protocol.Runtime.ExceptionDetails} */ (result.exceptionDetails), evaluationUrl);
|
|
return;
|
|
}
|
|
|
|
breakpointLocations = this._removeBreakpoints(uiSourceCode);
|
|
this._restoreBreakpoints(uiSourceCode, breakpointLocations);
|
|
|
|
this._runScript(script.scriptId, executionContext, evaluationUrl);
|
|
}
|
|
|
|
/**
|
|
* @param {!Protocol.Runtime.ScriptId} scriptId
|
|
* @param {!SDK.ExecutionContext} executionContext
|
|
* @param {?string=} sourceURL
|
|
*/
|
|
async _runScript(scriptId, executionContext, sourceURL) {
|
|
const runtimeModel = executionContext.runtimeModel;
|
|
const result = await runtimeModel.runScript(
|
|
scriptId, executionContext.id, 'console', /* silent */ false, /* includeCommandLineAPI */ true,
|
|
/* returnByValue */ false, /* generatePreview */ true);
|
|
if (result.error)
|
|
return;
|
|
if (!result.exceptionDetails)
|
|
this._printRunScriptResult(runtimeModel, result.object || null, scriptId, sourceURL);
|
|
else
|
|
this._printRunOrCompileScriptResultFailure(runtimeModel, result.exceptionDetails, sourceURL);
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.RuntimeModel} runtimeModel
|
|
* @param {?SDK.RemoteObject} result
|
|
* @param {!Protocol.Runtime.ScriptId} scriptId
|
|
* @param {?string=} sourceURL
|
|
*/
|
|
_printRunScriptResult(runtimeModel, result, scriptId, sourceURL) {
|
|
const consoleMessage = new SDK.ConsoleMessage(
|
|
runtimeModel, SDK.ConsoleMessage.MessageSource.JS, SDK.ConsoleMessage.MessageLevel.Info, '',
|
|
SDK.ConsoleMessage.MessageType.Result, sourceURL, undefined, undefined, [result], undefined, undefined,
|
|
undefined, scriptId);
|
|
SDK.consoleModel.addMessage(consoleMessage);
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.RuntimeModel} runtimeModel
|
|
* @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
|
|
* @param {?string=} sourceURL
|
|
*/
|
|
_printRunOrCompileScriptResultFailure(runtimeModel, exceptionDetails, sourceURL) {
|
|
SDK.consoleModel.addMessage(
|
|
SDK.ConsoleMessage.fromException(runtimeModel, exceptionDetails, undefined, undefined, sourceURL || undefined));
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @return {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>}
|
|
*/
|
|
_removeBreakpoints(uiSourceCode) {
|
|
const breakpointLocations = Bindings.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
|
|
for (let i = 0; i < breakpointLocations.length; ++i)
|
|
breakpointLocations[i].breakpoint.remove(false /* keepInStorage */);
|
|
return breakpointLocations;
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations
|
|
*/
|
|
_restoreBreakpoints(uiSourceCode, breakpointLocations) {
|
|
for (let i = 0; i < breakpointLocations.length; ++i) {
|
|
const uiLocation = breakpointLocations[i].uiLocation;
|
|
const breakpoint = breakpointLocations[i].breakpoint;
|
|
Bindings.breakpointManager.setBreakpoint(
|
|
uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber, breakpoint.condition(), breakpoint.enabled());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
_releaseSnippetScript(uiSourceCode) {
|
|
this._mappingForDebuggerModel.valuesArray().forEach(function(mapping) {
|
|
mapping._releaseSnippetScript(uiSourceCode);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {string} sourceURL
|
|
* @return {?string}
|
|
*/
|
|
_snippetIdForSourceURL(sourceURL) {
|
|
const snippetPrefix = Snippets.ScriptSnippetModel.snippetSourceURLPrefix;
|
|
if (!sourceURL.startsWith(snippetPrefix))
|
|
return null;
|
|
const splitURL = sourceURL.substring(snippetPrefix.length).split('_');
|
|
const snippetId = splitURL[0];
|
|
return snippetId;
|
|
}
|
|
};
|
|
|
|
Snippets.ScriptSnippetModel.snippetSourceURLPrefix = 'snippets:///';
|
|
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Snippets.SnippetScriptMapping = class {
|
|
/**
|
|
* @param {!SDK.DebuggerModel} debuggerModel
|
|
* @param {!Snippets.ScriptSnippetModel} scriptSnippetModel
|
|
*/
|
|
constructor(debuggerModel, scriptSnippetModel) {
|
|
this._debuggerModel = debuggerModel;
|
|
this._scriptSnippetModel = scriptSnippetModel;
|
|
/** @type {!Object.<string, !Workspace.UISourceCode>} */
|
|
this._uiSourceCodeForScriptId = {};
|
|
/** @type {!Map.<!Workspace.UISourceCode, !SDK.Script>} */
|
|
this._scriptForUISourceCode = new Map();
|
|
/** @type {!Map.<!Workspace.UISourceCode, number>} */
|
|
this._evaluationIndexForUISourceCode = new Map();
|
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._reset, this);
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
_releaseSnippetScript(uiSourceCode) {
|
|
const script = this._scriptForUISourceCode.get(uiSourceCode);
|
|
if (!script)
|
|
return;
|
|
|
|
delete this._uiSourceCodeForScriptId[script.scriptId];
|
|
this._scriptForUISourceCode.remove(uiSourceCode);
|
|
this._evaluationIndexForUISourceCode.remove(uiSourceCode);
|
|
}
|
|
|
|
/**
|
|
* @param {number} evaluationIndex
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
_setEvaluationIndex(evaluationIndex, uiSourceCode) {
|
|
this._evaluationIndexForUISourceCode.set(uiSourceCode, evaluationIndex);
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @return {number|undefined}
|
|
*/
|
|
evaluationIndex(uiSourceCode) {
|
|
return this._evaluationIndexForUISourceCode.get(uiSourceCode);
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @return {string}
|
|
*/
|
|
_evaluationSourceURL(uiSourceCode) {
|
|
const evaluationSuffix = '_' + this._evaluationIndexForUISourceCode.get(uiSourceCode);
|
|
const snippetId = this._scriptSnippetModel._snippetIdForUISourceCode.get(uiSourceCode);
|
|
return Snippets.ScriptSnippetModel.snippetSourceURLPrefix + snippetId + evaluationSuffix;
|
|
}
|
|
|
|
_reset() {
|
|
this._uiSourceCodeForScriptId = {};
|
|
this._scriptForUISourceCode.clear();
|
|
this._evaluationIndexForUISourceCode.clear();
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.DebuggerModel.Location} rawLocation
|
|
* @return {?Workspace.UILocation}
|
|
*/
|
|
rawLocationToUILocation(rawLocation) {
|
|
const debuggerModelLocation = /** @type {!SDK.DebuggerModel.Location} */ (rawLocation);
|
|
const uiSourceCode = this._uiSourceCodeForScriptId[debuggerModelLocation.scriptId];
|
|
if (!uiSourceCode)
|
|
return null;
|
|
|
|
return uiSourceCode.uiLocation(debuggerModelLocation.lineNumber, debuggerModelLocation.columnNumber || 0);
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @param {number} lineNumber
|
|
* @param {number} columnNumber
|
|
* @return {?SDK.DebuggerModel.Location}
|
|
*/
|
|
uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) {
|
|
const script = this._scriptForUISourceCode.get(uiSourceCode);
|
|
if (!script)
|
|
return null;
|
|
|
|
return this._debuggerModel.createRawLocation(script, lineNumber, columnNumber);
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.Script} script
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
_addScript(script, uiSourceCode) {
|
|
console.assert(!this._scriptForUISourceCode.get(uiSourceCode));
|
|
this._uiSourceCodeForScriptId[script.scriptId] = uiSourceCode;
|
|
this._scriptForUISourceCode.set(uiSourceCode, script);
|
|
Bindings.debuggerWorkspaceBinding.updateLocations(script);
|
|
}
|
|
|
|
/**
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @param {!Array.<!{breakpoint: !Bindings.BreakpointManager.Breakpoint, uiLocation: !Workspace.UILocation}>} breakpointLocations
|
|
*/
|
|
_restoreBreakpoints(uiSourceCode, breakpointLocations) {
|
|
const script = this._scriptForUISourceCode.get(uiSourceCode);
|
|
if (!script)
|
|
return;
|
|
const rawLocation =
|
|
/** @type {!SDK.DebuggerModel.Location} */ (this._debuggerModel.createRawLocation(script, 0, 0));
|
|
const uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
|
|
if (uiLocation)
|
|
this._scriptSnippetModel._restoreBreakpoints(uiLocation.uiSourceCode, breakpointLocations);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @implements {Common.ContentProvider}
|
|
* @unrestricted
|
|
*/
|
|
Snippets.SnippetContentProvider = class {
|
|
/**
|
|
* @param {!Snippets.Snippet} snippet
|
|
*/
|
|
constructor(snippet) {
|
|
this._snippet = snippet;
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @return {string}
|
|
*/
|
|
contentURL() {
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @return {!Common.ResourceType}
|
|
*/
|
|
contentType() {
|
|
return Common.resourceTypes.Snippet;
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @return {!Promise<boolean>}
|
|
*/
|
|
contentEncoded() {
|
|
return Promise.resolve(false);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @return {!Promise<?string>}
|
|
*/
|
|
requestContent() {
|
|
return Promise.resolve(/** @type {?string} */ (this._snippet.content));
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {string} query
|
|
* @param {boolean} caseSensitive
|
|
* @param {boolean} isRegex
|
|
* @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
|
|
*/
|
|
async searchInContent(query, caseSensitive, isRegex) {
|
|
return Common.ContentProvider.performSearchInContent(this._snippet.content, query, caseSensitive, isRegex);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Snippets.SnippetsProject = class extends Bindings.ContentProviderBasedProject {
|
|
/**
|
|
* @param {!Workspace.Workspace} workspace
|
|
* @param {!Snippets.ScriptSnippetModel} model
|
|
*/
|
|
constructor(workspace, model) {
|
|
super(workspace, 'snippets:', Workspace.projectTypes.Snippets, '', false /* isServiceProject */);
|
|
this._model = model;
|
|
}
|
|
|
|
/**
|
|
* @param {string} name
|
|
* @param {!Common.ContentProvider} contentProvider
|
|
* @return {!Workspace.UISourceCode}
|
|
*/
|
|
addSnippet(name, contentProvider) {
|
|
return this.addContentProvider(name, contentProvider, 'text/javascript');
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @return {boolean}
|
|
*/
|
|
canSetFileContent() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
* @param {string} newContent
|
|
* @param {boolean} isBase64
|
|
* @return {!Promise}
|
|
*/
|
|
async setFileContent(uiSourceCode, newContent, isBase64) {
|
|
this._model._setScriptSnippetContent(uiSourceCode.url(), newContent);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @return {boolean}
|
|
*/
|
|
canRename() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {string} url
|
|
* @param {string} newName
|
|
* @param {function(boolean, string=)} callback
|
|
*/
|
|
performRename(url, newName, callback) {
|
|
this._model.renameScriptSnippet(url, newName, callback);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {string} url
|
|
* @param {?string} name
|
|
* @param {string} content
|
|
* @param {boolean=} isBase64
|
|
* @return {!Promise<?Workspace.UISourceCode>}
|
|
*/
|
|
createFile(url, name, content, isBase64) {
|
|
return /** @type {!Promise<?Workspace.UISourceCode>} */ (Promise.resolve(this._model.createScriptSnippet(content)));
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {!Workspace.UISourceCode} uiSourceCode
|
|
*/
|
|
deleteFile(uiSourceCode) {
|
|
this._model.deleteScriptSnippet(uiSourceCode);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @type {!Snippets.ScriptSnippetModel}
|
|
*/
|
|
Snippets.scriptSnippetModel = new Snippets.ScriptSnippetModel(Workspace.workspace);
|