2019-03-12 23:24:46 +00:00
|
|
|
import * as vscode from 'vscode';
|
2019-05-17 00:52:52 +02:00
|
|
|
import { FiddleRepository, toExtension, downloadFiddle, areIdentical, uploadFiddle, Fiddle, toFiddleId } from './fiddleRepository';
|
2019-03-12 23:24:46 +00:00
|
|
|
import * as path from 'path';
|
2019-08-03 23:42:21 +02:00
|
|
|
import * as afs from './afs';
|
2019-03-19 03:06:13 +01:00
|
|
|
import { FiddleConfiguration, parseFiddleId } from './fiddleConfiguration';
|
2019-08-03 23:42:21 +02:00
|
|
|
import { UTF8 } from './util';
|
2019-03-19 03:06:13 +01:00
|
|
|
|
|
|
|
|
export const CONFIGURATION_FILE = '.jsfiddle';
|
2019-03-12 23:24:46 +00:00
|
|
|
|
|
|
|
|
export class FiddleSourceControl implements vscode.Disposable {
|
2019-03-19 03:06:13 +01:00
|
|
|
private jsFiddleScm: vscode.SourceControl;
|
|
|
|
|
private changedResources: vscode.SourceControlResourceGroup;
|
|
|
|
|
private fiddleRepository: FiddleRepository;
|
|
|
|
|
private latestFiddleVersion: number = Number.POSITIVE_INFINITY; // until actual value is established
|
2019-03-12 23:24:46 +00:00
|
|
|
private _onRepositoryChange = new vscode.EventEmitter<Fiddle>();
|
2019-05-10 14:34:54 -07:00
|
|
|
private timeout?: NodeJS.Timer;
|
|
|
|
|
private fiddle!: Fiddle;
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-08-03 23:42:21 +02:00
|
|
|
constructor(context: vscode.ExtensionContext, private readonly workspaceFolder: vscode.WorkspaceFolder, fiddle: Fiddle, download: boolean) {
|
2019-03-19 03:06:13 +01:00
|
|
|
this.jsFiddleScm = vscode.scm.createSourceControl('jsfiddle', 'JSFiddle #' + fiddle.slug, workspaceFolder.uri);
|
2019-03-12 23:24:46 +00:00
|
|
|
this.changedResources = this.jsFiddleScm.createResourceGroup('workingTree', 'Changes');
|
2019-03-19 03:06:13 +01:00
|
|
|
this.fiddleRepository = new FiddleRepository(workspaceFolder, fiddle.slug);
|
2019-03-12 23:24:46 +00:00
|
|
|
this.jsFiddleScm.quickDiffProvider = this.fiddleRepository;
|
2019-03-19 03:06:13 +01:00
|
|
|
this.jsFiddleScm.inputBox.placeholder = 'Message is ignored by JS Fiddle :-]';
|
|
|
|
|
|
2020-05-29 13:12:13 -07:00
|
|
|
const fileSystemWatcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(workspaceFolder, "*.*"));
|
2019-03-19 03:06:13 +01:00
|
|
|
fileSystemWatcher.onDidChange(uri => this.onResourceChange(uri), context.subscriptions);
|
|
|
|
|
fileSystemWatcher.onDidCreate(uri => this.onResourceChange(uri), context.subscriptions);
|
|
|
|
|
fileSystemWatcher.onDidDelete(uri => this.onResourceChange(uri), context.subscriptions);
|
2019-03-12 23:24:46 +00:00
|
|
|
|
|
|
|
|
context.subscriptions.push(this.jsFiddleScm);
|
2019-03-19 03:06:13 +01:00
|
|
|
context.subscriptions.push(fileSystemWatcher);
|
|
|
|
|
|
|
|
|
|
// clone fiddle to the local workspace
|
2019-08-03 23:42:21 +02:00
|
|
|
this.setFiddle(fiddle, download);
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 22:17:35 +01:00
|
|
|
if (this.fiddle.version === undefined || Number.isNaN(this.fiddle.version)) {
|
2019-03-12 23:24:46 +00:00
|
|
|
this.establishVersion();
|
|
|
|
|
} else {
|
|
|
|
|
this.refresh();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
static async fromFiddleId(id: string, context: vscode.ExtensionContext, workspaceFolder: vscode.WorkspaceFolder, overwrite: boolean): Promise<FiddleSourceControl> {
|
2020-05-29 13:12:13 -07:00
|
|
|
const fiddleConfiguration = parseFiddleId(id);
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
return await FiddleSourceControl.fromConfiguration(fiddleConfiguration, workspaceFolder, context, overwrite);
|
|
|
|
|
}
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
static async fromConfiguration(configuration: FiddleConfiguration, workspaceFolder: vscode.WorkspaceFolder, context: vscode.ExtensionContext, overwrite: boolean): Promise<FiddleSourceControl> {
|
|
|
|
|
return await FiddleSourceControl.fromFiddle(configuration.slug, configuration.version, workspaceFolder, context, overwrite);
|
|
|
|
|
}
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
private static async fromFiddle(fiddleSlug: string, fiddleVersion: number, workspaceFolder: vscode.WorkspaceFolder, context: vscode.ExtensionContext, overwrite: boolean): Promise<FiddleSourceControl> {
|
2020-05-29 13:12:13 -07:00
|
|
|
const fiddle = await downloadFiddle(fiddleSlug, fiddleVersion);
|
|
|
|
|
const workspacePath = workspaceFolder.uri.fsPath;
|
2019-03-19 03:06:13 +01:00
|
|
|
return new FiddleSourceControl(context, workspaceFolder, fiddle, overwrite);
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private refreshStatusBar() {
|
|
|
|
|
this.jsFiddleScm.statusBarCommands = [
|
|
|
|
|
{
|
|
|
|
|
"command": "extension.source-control.checkout",
|
2019-03-19 03:06:13 +01:00
|
|
|
"arguments": [this],
|
|
|
|
|
"title": `↕ ${this.fiddle.slug} #${this.fiddle.version} / ${this.latestFiddleVersion}`,
|
2019-03-12 23:24:46 +00:00
|
|
|
"tooltip": "Checkout another version of this fiddle.",
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async commitAll(): Promise<void> {
|
2019-03-19 03:06:13 +01:00
|
|
|
if (!this.changedResources.resourceStates.length) {
|
|
|
|
|
vscode.window.showErrorMessage("There is nothing to commit.");
|
|
|
|
|
}
|
|
|
|
|
else if (this.fiddle.version < this.latestFiddleVersion) {
|
|
|
|
|
vscode.window.showErrorMessage("Checkout the latest fiddle version before committing your changes.");
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-05-29 13:12:13 -07:00
|
|
|
const html = await this.getLocalResourceText('html');
|
|
|
|
|
const js = await this.getLocalResourceText('js');
|
|
|
|
|
const css = await this.getLocalResourceText('css');
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 22:17:35 +01:00
|
|
|
// here we assume nobody updated the Fiddle on the server since we refreshed the list of versions
|
|
|
|
|
try {
|
2020-05-29 13:12:13 -07:00
|
|
|
const newFiddle = await uploadFiddle(this.fiddle.slug, this.fiddle.version + 1, html, js, css);
|
2019-05-10 14:45:55 -07:00
|
|
|
if (!newFiddle) { return; }
|
2019-03-19 03:06:13 +01:00
|
|
|
this.setFiddle(newFiddle, false);
|
|
|
|
|
this.jsFiddleScm.inputBox.value = '';
|
2019-03-19 22:17:35 +01:00
|
|
|
} catch (ex) {
|
|
|
|
|
vscode.window.showErrorMessage("Cannot commit changes to JS Fiddle. " + ex.message);
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
private async getLocalResourceText(extension: string) {
|
2020-05-29 13:12:13 -07:00
|
|
|
const document = await vscode.workspace.openTextDocument(this.fiddleRepository.createLocalResourcePath(extension));
|
2019-03-19 03:06:13 +01:00
|
|
|
return document.getText();
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 23:24:46 +00:00
|
|
|
/**
|
|
|
|
|
* Throws away all local changes and resets all files to the checked out version of the repository.
|
|
|
|
|
*/
|
|
|
|
|
resetFilesToCheckedOutVersion(): void {
|
|
|
|
|
this.resetFile('html');
|
|
|
|
|
this.resetFile('css');
|
|
|
|
|
this.resetFile('js');
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
/** Resets the given local file content to the checked-out version. */
|
2019-08-03 23:42:21 +02:00
|
|
|
private async resetFile(extension: string): Promise<void> {
|
2020-05-29 13:12:13 -07:00
|
|
|
const filePath = this.fiddleRepository.createLocalResourcePath(extension);
|
2019-08-03 23:42:21 +02:00
|
|
|
await afs.writeFile(filePath, this.fiddle.data[extension]);
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async tryCheckout(newVersion: number | undefined): Promise<void> {
|
2019-05-10 14:45:55 -07:00
|
|
|
if (!Number.isFinite(this.latestFiddleVersion)) { return; }
|
2019-03-12 23:24:46 +00:00
|
|
|
|
|
|
|
|
if (newVersion === undefined) {
|
2020-05-29 13:12:13 -07:00
|
|
|
const allVersions = [...Array(this.latestFiddleVersion + 1).keys()]
|
2019-05-10 14:45:55 -07:00
|
|
|
.map(ver => new VersionQuickPickItem(ver, ver === this.fiddle.version));
|
2020-05-29 13:12:13 -07:00
|
|
|
const newVersionPick = await vscode.window.showQuickPick(allVersions, { canPickMany: false, placeHolder: 'Select a version...' });
|
2019-03-12 23:24:46 +00:00
|
|
|
if (newVersionPick) {
|
|
|
|
|
newVersion = newVersionPick.version;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-03-19 03:06:13 +01:00
|
|
|
return;
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-10 14:45:55 -07:00
|
|
|
if (newVersion === this.fiddle.version) { return; } // the same version was selected
|
2019-03-19 22:17:35 +01:00
|
|
|
|
2019-03-12 23:24:46 +00:00
|
|
|
if (this.changedResources.resourceStates.length) {
|
2020-05-29 13:12:13 -07:00
|
|
|
const changedResourcesCount = this.changedResources.resourceStates.length;
|
2019-03-12 23:24:46 +00:00
|
|
|
vscode.window.showErrorMessage(`There is one or more changed resources. Discard or commit your local changes before checking out another version.`);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
try {
|
2020-05-29 13:12:13 -07:00
|
|
|
const newFiddle = await downloadFiddle(this.fiddle.slug, newVersion);
|
2019-03-19 03:06:13 +01:00
|
|
|
this.setFiddle(newFiddle, true);
|
2019-03-12 23:24:46 +00:00
|
|
|
} catch (ex) {
|
|
|
|
|
vscode.window.showErrorMessage(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
private setFiddle(newFiddle: Fiddle, overwrite: boolean) {
|
2019-05-10 14:45:55 -07:00
|
|
|
if (newFiddle.version > this.latestFiddleVersion) { this.latestFiddleVersion = newFiddle.version; }
|
2019-03-12 23:24:46 +00:00
|
|
|
this.fiddle = newFiddle;
|
2019-05-10 14:45:55 -07:00
|
|
|
if (overwrite) { this.resetFilesToCheckedOutVersion(); } // overwrite local file content
|
2019-03-12 23:24:46 +00:00
|
|
|
this._onRepositoryChange.fire(this.fiddle);
|
|
|
|
|
this.refreshStatusBar();
|
2019-03-19 03:06:13 +01:00
|
|
|
|
|
|
|
|
this.saveCurrentConfiguration();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getFiddle(): Fiddle {
|
|
|
|
|
return this.fiddle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getWorkspaceFolder(): vscode.WorkspaceFolder {
|
|
|
|
|
return this.workspaceFolder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getSourceControl(): vscode.SourceControl {
|
|
|
|
|
return this.jsFiddleScm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getRepository(): FiddleRepository {
|
|
|
|
|
return this.fiddleRepository;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** save configuration for later VS Code sessions */
|
|
|
|
|
private saveCurrentConfiguration(): void {
|
2020-05-29 13:12:13 -07:00
|
|
|
const fiddleConfiguration: FiddleConfiguration = {
|
2019-03-19 03:06:13 +01:00
|
|
|
slug: this.fiddle.slug,
|
2019-08-03 23:42:21 +02:00
|
|
|
version: this.fiddle.version,
|
|
|
|
|
downloaded: true
|
2019-03-19 03:06:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
FiddleSourceControl.saveConfiguration(this.workspaceFolder.uri, fiddleConfiguration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static saveConfiguration(workspaceFolderUri: vscode.Uri, fiddleConfiguration: FiddleConfiguration): void {
|
2020-05-29 13:12:13 -07:00
|
|
|
const fiddleConfigurationString = JSON.stringify(fiddleConfiguration);
|
2019-08-03 23:42:21 +02:00
|
|
|
afs.writeFile(path.join(workspaceFolderUri.fsPath, CONFIGURATION_FILE), Buffer.from(fiddleConfigurationString, UTF8));
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get onRepositoryChange(): vscode.Event<Fiddle> {
|
|
|
|
|
return this._onRepositoryChange.event;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
onResourceChange(_uri: vscode.Uri): void {
|
2019-05-10 14:45:55 -07:00
|
|
|
if (this.timeout) { clearTimeout(this.timeout); }
|
2019-03-19 03:06:13 +01:00
|
|
|
this.timeout = setTimeout(() => this.tryUpdateChangedGroup(), 500);
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
async tryUpdateChangedGroup(): Promise<void> {
|
|
|
|
|
try {
|
|
|
|
|
await this.updateChangedGroup();
|
|
|
|
|
}
|
|
|
|
|
catch (ex) {
|
|
|
|
|
vscode.window.showErrorMessage(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-17 00:52:52 +02:00
|
|
|
/** This is where the source control determines, which documents were updated, removed, and theoretically added. */
|
2019-03-19 03:06:13 +01:00
|
|
|
async updateChangedGroup(): Promise<void> {
|
|
|
|
|
// for simplicity we ignore which document was changed in this event and scan all of them
|
2020-05-29 13:12:13 -07:00
|
|
|
const changedResources: vscode.SourceControlResourceState[] = [];
|
2019-03-19 03:06:13 +01:00
|
|
|
|
2020-05-29 13:12:13 -07:00
|
|
|
const uris = this.fiddleRepository.provideSourceControlledResources();
|
2019-03-19 03:06:13 +01:00
|
|
|
|
|
|
|
|
for (const uri of uris) {
|
|
|
|
|
let isDirty: boolean;
|
|
|
|
|
let wasDeleted: boolean;
|
|
|
|
|
|
2020-05-29 13:12:13 -07:00
|
|
|
const pathExists = await afs.exists(uri.fsPath);
|
2019-08-03 23:42:21 +02:00
|
|
|
|
|
|
|
|
if (pathExists) {
|
2020-05-29 13:12:13 -07:00
|
|
|
const document = await vscode.workspace.openTextDocument(uri);
|
2019-03-19 03:06:13 +01:00
|
|
|
isDirty = this.isDirty(document);
|
|
|
|
|
wasDeleted = false;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
isDirty = true;
|
|
|
|
|
wasDeleted = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isDirty) {
|
2020-05-29 13:12:13 -07:00
|
|
|
const resourceState = this.toSourceControlResourceState(uri, wasDeleted);
|
2019-03-19 03:06:13 +01:00
|
|
|
changedResources.push(resourceState);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.changedResources.resourceStates = changedResources;
|
2019-05-17 00:52:52 +02:00
|
|
|
|
|
|
|
|
// the number of modified resources needs to be assigned to the SourceControl.count filed to let VS Code show the number.
|
|
|
|
|
this.jsFiddleScm.count = this.changedResources.resourceStates.length;
|
2019-03-19 03:06:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Determines whether the resource is different, regardless of line endings. */
|
2019-03-12 23:24:46 +00:00
|
|
|
isDirty(doc: vscode.TextDocument): boolean {
|
2020-05-29 13:12:13 -07:00
|
|
|
const originalText = this.fiddle.data[toExtension(doc.uri)];
|
2019-05-10 14:45:55 -07:00
|
|
|
return originalText.replace('\r', '') !== doc.getText().replace('\r', '');
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
toSourceControlResourceState(docUri: vscode.Uri, deleted: boolean): vscode.SourceControlResourceState {
|
|
|
|
|
|
2020-05-29 13:12:13 -07:00
|
|
|
const repositoryUri = this.fiddleRepository.provideOriginalResource(docUri, null);
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 03:06:13 +01:00
|
|
|
const fiddlePart = toExtension(docUri).toUpperCase();
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2020-05-29 13:12:13 -07:00
|
|
|
const command: vscode.Command = !deleted
|
2019-03-19 03:06:13 +01:00
|
|
|
? {
|
2019-03-12 23:24:46 +00:00
|
|
|
title: "Show changes",
|
|
|
|
|
command: "vscode.diff",
|
2019-03-19 03:06:13 +01:00
|
|
|
arguments: [repositoryUri, docUri, `JSFiddle#${this.fiddle.slug} ${fiddlePart} ↔ Local changes`],
|
2019-03-12 23:24:46 +00:00
|
|
|
tooltip: "Diff your changes"
|
|
|
|
|
}
|
2019-03-19 03:06:13 +01:00
|
|
|
: null;
|
|
|
|
|
|
2020-05-29 13:12:13 -07:00
|
|
|
const resourceState: vscode.SourceControlResourceState = {
|
2019-03-19 03:06:13 +01:00
|
|
|
resourceUri: docUri,
|
|
|
|
|
command: command,
|
|
|
|
|
decorations: {
|
|
|
|
|
strikeThrough: deleted,
|
|
|
|
|
tooltip: 'File was locally deleted.'
|
|
|
|
|
}
|
2019-03-12 23:24:46 +00:00
|
|
|
};
|
2019-03-19 03:06:13 +01:00
|
|
|
|
|
|
|
|
return resourceState;
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
2019-05-17 00:52:52 +02:00
|
|
|
/**
|
|
|
|
|
* Refresh is used when the information on the server may have changed.
|
|
|
|
|
* For example another user updates the Fiddle online.
|
|
|
|
|
*/
|
|
|
|
|
async refresh(): Promise<void> {
|
|
|
|
|
let latestVersion = this.fiddle.version || 0;
|
|
|
|
|
while (true) {
|
|
|
|
|
try {
|
2020-05-29 13:12:13 -07:00
|
|
|
const latestFiddle = await downloadFiddle(this.fiddle.slug, latestVersion);
|
2019-05-17 00:52:52 +02:00
|
|
|
this.latestFiddleVersion = latestVersion;
|
|
|
|
|
latestVersion++;
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
// typically the ex.statusCode == 404, when there is no further version
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.refreshStatusBar();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determines which version was checked out and finds the index of the latest version.
|
|
|
|
|
*
|
|
|
|
|
* When a fiddle is open by the hash code, the latest version is downloaded,
|
|
|
|
|
* but extension does not know what version it is.
|
|
|
|
|
*/
|
|
|
|
|
async establishVersion(): Promise<void> {
|
|
|
|
|
let version = 0;
|
|
|
|
|
let latestVersion = Number.NaN;
|
|
|
|
|
let currentFiddle: Fiddle | undefined = undefined;
|
|
|
|
|
while (true) {
|
|
|
|
|
try {
|
2020-05-29 13:12:13 -07:00
|
|
|
const latestFiddle = await downloadFiddle(this.fiddle.slug, version);
|
2019-05-17 00:52:52 +02:00
|
|
|
latestVersion = version;
|
|
|
|
|
version++;
|
|
|
|
|
if (areIdentical(this.fiddle.data, latestFiddle.data)) {
|
|
|
|
|
currentFiddle = latestFiddle;
|
|
|
|
|
}
|
|
|
|
|
} catch (ex) {
|
|
|
|
|
// typically the ex.statusCode == 404, when there is no further version
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.latestFiddleVersion = latestVersion;
|
|
|
|
|
|
|
|
|
|
// now we know the version of the current fiddle, let's set it
|
|
|
|
|
if (currentFiddle) {
|
|
|
|
|
this.setFiddle(currentFiddle, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Opens the fiddle in the default browser. */
|
|
|
|
|
openInBrowser() {
|
2020-05-29 13:12:13 -07:00
|
|
|
const url = "https://jsfiddle.net/" + toFiddleId(this.fiddle.slug, this.fiddle.version);
|
2019-05-17 00:52:52 +02:00
|
|
|
vscode.env.openExternal(vscode.Uri.parse(url));
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 23:24:46 +00:00
|
|
|
dispose() {
|
|
|
|
|
this._onRepositoryChange.dispose();
|
2019-03-19 03:06:13 +01:00
|
|
|
this.jsFiddleScm.dispose();
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class VersionQuickPickItem implements vscode.QuickPickItem {
|
|
|
|
|
|
2019-03-19 22:17:35 +01:00
|
|
|
constructor(public readonly version: number, public readonly picked: boolean) {
|
|
|
|
|
}
|
2019-03-12 23:24:46 +00:00
|
|
|
|
2019-03-19 22:17:35 +01:00
|
|
|
get label(): string {
|
|
|
|
|
return `Version ${this.version}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get description(): string {
|
|
|
|
|
return this.picked ? '(currently checked-out)' : '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get alwaysShow(): boolean {
|
|
|
|
|
return this.picked;
|
2019-03-12 23:24:46 +00:00
|
|
|
}
|
|
|
|
|
}
|