From 9c1d5c1248815733e04d803236748e32642281d8 Mon Sep 17 00:00:00 2001 From: Jan Dolejsi Date: Tue, 19 Mar 2019 22:17:35 +0100 Subject: [PATCH] - ability to open fiddle in the browser instead of writing to it. - fix fidde versioning to be zero-based --- source-control-sample/package.json | 10 +-- source-control-sample/src/extension.ts | 2 +- source-control-sample/src/fiddleRepository.ts | 62 +++++++++++------- .../src/fiddleSourceControl.ts | 63 ++++++++++--------- 4 files changed, 81 insertions(+), 56 deletions(-) diff --git a/source-control-sample/package.json b/source-control-sample/package.json index 727adcde..a13d5d38 100644 --- a/source-control-sample/package.json +++ b/source-control-sample/package.json @@ -5,7 +5,7 @@ "version": "0.0.1", "publisher": "vscode-samples", "engines": { - "vscode": "^1.30.0" + "vscode": "^1.31.0" }, "categories": [ "SCM Providers" @@ -27,7 +27,7 @@ "icon": { "light": "resources/icons/light/check.svg", "dark": "resources/icons/dark/check.svg" - } + } }, { "command": "extension.source-control.refresh", @@ -35,7 +35,7 @@ "icon": { "light": "resources/icons/light/refresh.svg", "dark": "resources/icons/dark/refresh.svg" - } + } }, { "command": "extension.source-control.discard", @@ -43,7 +43,7 @@ "icon": { "light": "resources/icons/light/discard.svg", "dark": "resources/icons/dark/discard.svg" - } + } }, { "command": "extension.source-control.checkout", @@ -51,7 +51,7 @@ "icon": { "light": "resources/icons/light/refresh.svg", "dark": "resources/icons/dark/refresh.svg" - } + } } ], "menus": { diff --git a/source-control-sample/src/extension.ts b/source-control-sample/src/extension.ts index 00fe7a4f..6c2b4252 100644 --- a/source-control-sample/src/extension.ts +++ b/source-control-sample/src/extension.ts @@ -186,7 +186,7 @@ async function selectWorkspaceFolder(context: vscode.ExtensionContext, fiddleId: } let workSpacesToReplace = workspaceFolderIndex > -1 ? 1 : 0; - if (workspaceFolderIndex < 0) workspaceFolderIndex = 0; + if (workspaceFolderIndex === undefined || workspaceFolderIndex < 0) workspaceFolderIndex = 0; // replace or insert the workspace vscode.workspace.updateWorkspaceFolders(workspaceFolderIndex, workSpacesToReplace, { uri: workspaceFolderUri }); diff --git a/source-control-sample/src/fiddleRepository.ts b/source-control-sample/src/fiddleRepository.ts index 8ffee138..879938aa 100644 --- a/source-control-sample/src/fiddleRepository.ts +++ b/source-control-sample/src/fiddleRepository.ts @@ -1,5 +1,5 @@ import JSFiddle = require("jsfiddle"); -import { QuickDiffProvider, Uri, CancellationToken, ProviderResult, WorkspaceFolder, workspace } from "vscode"; +import { QuickDiffProvider, Uri, CancellationToken, ProviderResult, WorkspaceFolder, workspace, window, env } from "vscode"; import * as path from 'path'; /** Represents one JSFiddle data and meta-data. */ @@ -39,7 +39,7 @@ export class FiddleRepository implements QuickDiffProvider { return [ Uri.file(this.createLocalResourcePath('html')), Uri.file(this.createLocalResourcePath('js')), - Uri.file(this.createLocalResourcePath('css')) ]; + Uri.file(this.createLocalResourcePath('css'))]; } /** @@ -69,13 +69,14 @@ export async function downloadFiddle(slug: string, version: number | undefined): if (slug === "demo") { // use mock fiddle - if (!demoVersionOffset) demoVersionOffset = version-1; - let maxDemoVersion = DEMO.length + demoVersionOffset; + if (demoVersionOffset === undefined && version === undefined) version = 0; + if (demoVersionOffset === undefined) demoVersionOffset = version; + let maxDemoVersion = DEMO.length -1 + demoVersionOffset; if (version === undefined) version = maxDemoVersion; - if (version >= 1 && version <= maxDemoVersion) { + if (version >= 0 && version <= maxDemoVersion) { // mock all versions committed in previous sessions by the first version - let index = Math.max(0, version-1 - demoVersionOffset); + let index = Math.max(0, version - demoVersionOffset); let fiddleData = DEMO[index]; return new Fiddle(slug, version, fiddleData); } @@ -106,25 +107,44 @@ export async function uploadFiddle(slug: string, version: number, html: string, DEMO.push(fiddleData); return new Fiddle(slug, version, fiddleData); } + else { - let data = { - slug: slug, - version: version, - html: html, - js: js, - css: css - }; + let answer = await window.showQuickPick(["Yes, open in the browser. I will paste the new Fiddle code, discard changes, refresh source control and checkout latest.", "No, I was just clicking around."], + { placeHolder: "JS Fiddle saving is not supported. Do you want to open the JSFiddle in the browser?" }); - return new Promise((resolve, reject) => { - JSFiddle.saveFiddle(data, (err: any, fiddleData: any) => { - // handle error - if (err) reject(err); + if (answer && answer.toLowerCase().startsWith("yes")) { + env.openExternal(Uri.parse(`https://jsfiddle.net/${slug}/`)); + return undefined; + } - let fiddle = new Fiddle(slug, version, fiddleData); + if (false) { + // this, sadly, does not work as advertised + let data = { + slug: slug, + version: version, + html: html, + js: js, + css: css + }; - resolve(fiddle); - }); - }); + return new Promise((resolve, reject) => { + JSFiddle.saveFiddle(data, (err: any, fiddleData: any) => { + // handle error + if (err) { + reject(err); + } + else { + let fiddle = new Fiddle(slug, version, fiddleData); + + resolve(fiddle); + } + }); + }); + } + else { + return undefined; + } + } } function toFiddleId(slug: string, version: number | undefined): string { diff --git a/source-control-sample/src/fiddleSourceControl.ts b/source-control-sample/src/fiddleSourceControl.ts index 58df9075..94e082ea 100644 --- a/source-control-sample/src/fiddleSourceControl.ts +++ b/source-control-sample/src/fiddleSourceControl.ts @@ -33,7 +33,7 @@ export class FiddleSourceControl implements vscode.Disposable { // clone fiddle to the local workspace this.setFiddle(fiddle, overwrite); - if (Number.isNaN(this.fiddle.version)) { + if (this.fiddle.version === undefined || Number.isNaN(this.fiddle.version)) { this.establishVersion(); } else { this.refresh(); @@ -75,18 +75,18 @@ export class FiddleSourceControl implements vscode.Disposable { vscode.window.showErrorMessage("Checkout the latest fiddle version before committing your changes."); } else { - let answer = await vscode.window.showQuickPick(["Yes, upload the changes to JS Fiddle.", "No, I was just clicking around."], - { placeHolder: "Are you sure you want to commit?" }); + let html = await this.getLocalResourceText('html'); + let js = await this.getLocalResourceText('js'); + let css = await this.getLocalResourceText('css'); - if (answer && answer.toLowerCase().startsWith("yes")) { - let html = await this.getLocalResourceText('html'); - let js = await this.getLocalResourceText('js'); - let css = await this.getLocalResourceText('css'); - - // here we assume nobody updated the Fiddle on the server since we refreshed the list of versions - let newFiddle = await uploadFiddle(this.fiddle.slug, this.fiddle.version + 1, html, js, css); + // here we assume nobody updated the Fiddle on the server since we refreshed the list of versions + try { + let newFiddle = await uploadFiddle(this.fiddle.slug, this.fiddle.version+1, html, js, css); + if (!newFiddle) return; this.setFiddle(newFiddle, false); this.jsFiddleScm.inputBox.value = ''; + } catch (ex) { + vscode.window.showErrorMessage("Cannot commit changes to JS Fiddle. " + ex.message); } } } @@ -115,8 +115,7 @@ export class FiddleSourceControl implements vscode.Disposable { if (!Number.isFinite(this.latestFiddleVersion)) return; if (newVersion === undefined) { - let allVersions = [...Array(this.latestFiddleVersion).keys()] - .map(n => n + 1) + let allVersions = [...Array(this.latestFiddleVersion + 1).keys()] .map(ver => new VersionQuickPickItem(ver, ver == this.fiddle.version)); let newVersionPick = await vscode.window.showQuickPick(allVersions, { canPickMany: false, placeHolder: 'Select a version...' }); if (newVersionPick) { @@ -127,6 +126,8 @@ export class FiddleSourceControl implements vscode.Disposable { } } + if (newVersion === this.fiddle.version) return; // the same version was selected + if (this.changedResources.resourceStates.length) { let changedResourcesCount = this.changedResources.resourceStates.length; vscode.window.showErrorMessage(`There is one or more changed resources. Discard or commit your local changes before checking out another version.`); @@ -189,18 +190,18 @@ export class FiddleSourceControl implements vscode.Disposable { * For example another user updates the Fiddle online. */ async refresh(): Promise { - let latestVersion = this.fiddle.version; + let latestVersion = this.fiddle.version || 0; while (true) { try { - latestVersion++; let latestFiddle = await downloadFiddle(this.fiddle.slug, latestVersion); + this.latestFiddleVersion = latestVersion; + latestVersion++; } catch (ex) { // typically the ex.statusCode == 404, when there is no further version break; } } - this.latestFiddleVersion = latestVersion - 1; this.refreshStatusBar(); } @@ -208,12 +209,14 @@ export class FiddleSourceControl implements vscode.Disposable { * Determines which version was checked out and finds the index of the latest version. */ async establishVersion(): Promise { - let latestVersion = 0; + let version = 0; + let latestVersion = Number.NaN; let currentFiddle: Fiddle = undefined; while (true) { try { - latestVersion++; - let latestFiddle = await downloadFiddle(this.fiddle.slug, latestVersion); + let latestFiddle = await downloadFiddle(this.fiddle.slug, version); + latestVersion = version; + version++; if (areIdentical(this.fiddle.data, latestFiddle.data)) { currentFiddle = latestFiddle; } @@ -223,7 +226,7 @@ export class FiddleSourceControl implements vscode.Disposable { } } - this.latestFiddleVersion = latestVersion - 1; + this.latestFiddleVersion = latestVersion; // now we know the version of the current fiddle, let's set it this.setFiddle(currentFiddle, false); @@ -317,17 +320,19 @@ export class FiddleSourceControl implements vscode.Disposable { } class VersionQuickPickItem implements vscode.QuickPickItem { - label: string; - description?: string; - detail?: string; - alwaysShow?: boolean; - constructor(public version: number, public picked: boolean) { - this.label = this.version.toString(); - this.alwaysShow = picked; + constructor(public readonly version: number, public readonly picked: boolean) { + } - if (picked) { - this.description = "Currently checked out."; - } + get label(): string { + return `Version ${this.version}`; + } + + get description(): string { + return this.picked ? '(currently checked-out)' : ''; + } + + get alwaysShow(): boolean { + return this.picked; } }