From 4b217fba0095f4c68e6fc3e407f500c40c58c616 Mon Sep 17 00:00:00 2001 From: majik Date: Thu, 11 Apr 2019 09:07:53 +0800 Subject: [PATCH 1/9] Feature/relative url (#307) * resrouce relative url * add url pathname for require.toUrl (fix webview url) * rest resrouce relative url * fix resource url * ignore .vscode --- .gitignore | 3 ++- packages/ide/src/fill/electron.ts | 14 +++++++++----- packages/vscode/src/fill/storageDatabase.ts | 3 ++- scripts/webpack.general.config.js | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index d2ee77a37..ffaa56b42 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ dist out .DS_Store release -.cache \ No newline at end of file +.vscode +.cache diff --git a/packages/ide/src/fill/electron.ts b/packages/ide/src/fill/electron.ts index bbc1f48b8..399cda825 100644 --- a/packages/ide/src/fill/electron.ts +++ b/packages/ide/src/fill/electron.ts @@ -45,7 +45,8 @@ const newCreateElement = (tagName: K): HT }, set: (value: string): void => { if (value) { - value = value.replace(/file:\/\//g, "/resource"); + const resourceBaseUrl = location.pathname.replace(/\/$/, "") + "/resource"; + value = value.replace(/file:\/\//g, resourceBaseUrl); } oldSrc!.set!.call(img, value); }, @@ -66,7 +67,8 @@ const newCreateElement = (tagName: K): HT }, set: (value: string): void => { if (value) { - value = value.replace(/file:\/\//g, "/resource"); + const resourceBaseUrl = location.pathname.replace(/\/$/, "") + "/resource"; + value = value.replace(/file:\/\//g, resourceBaseUrl); } oldInnerHtml!.set!.call(style, value); }, @@ -80,7 +82,8 @@ const newCreateElement = (tagName: K): HT if (sheet && !overridden) { const oldInsertRule = sheet.insertRule; sheet.insertRule = (rule: string, index?: number): void => { - rule = rule.replace(/file:\/\//g, "/resource"); + const resourceBaseUrl = location.pathname.replace(/\/$/, "") + "/resource"; + rule = rule.replace(/file:\/\//g, resourceBaseUrl); oldInsertRule.call(sheet, rule, index); }; overridden = true; @@ -145,8 +148,9 @@ const newCreateElement = (tagName: K): HT (view as any).send = (channel: string, ...args: any[]): void => { // tslint:disable-line no-any if (args[0] && typeof args[0] === "object" && args[0].contents) { // TODO - args[0].contents = (args[0].contents as string).replace(/"(file:\/\/[^"]*)"/g, (m1) => `"/resource${m1}"`); - args[0].contents = (args[0].contents as string).replace(/"vscode-resource:([^"]*)"/g, (m, m1) => `"/resource${m1}"`); + const resourceBaseUrl = location.pathname.replace(/\/$/, "") + "/resource"; + args[0].contents = (args[0].contents as string).replace(/"(file:\/\/[^"]*)"/g, (m1) => `"${resourceBaseUrl}${m1}"`); + args[0].contents = (args[0].contents as string).replace(/"vscode-resource:([^"]*)"/g, (m, m1) => `"${resourceBaseUrl}${m1}"`); args[0].contents = (args[0].contents as string).replace(/style-src vscode-core-resource:/g, "style-src 'self'"); } if (view.contentWindow) { diff --git a/packages/vscode/src/fill/storageDatabase.ts b/packages/vscode/src/fill/storageDatabase.ts index 37b627c71..94343e185 100644 --- a/packages/vscode/src/fill/storageDatabase.ts +++ b/packages/vscode/src/fill/storageDatabase.ts @@ -28,7 +28,8 @@ class StorageDatabase implements workspaceStorage.IStorageDatabase { } this.triggerFlush(WillSaveStateReason.SHUTDOWN); - navigator.sendBeacon(`/resource${this.path}`, this.content); + const resourceBaseUrl = location.pathname.replace(/\/$/, "") + "/resource"; + navigator.sendBeacon(`${resourceBaseUrl}/${this.path}`, this.content); }); } diff --git a/scripts/webpack.general.config.js b/scripts/webpack.general.config.js index 4da6ca88f..17a056ba4 100644 --- a/scripts/webpack.general.config.js +++ b/scripts/webpack.general.config.js @@ -21,7 +21,7 @@ module.exports = (options = {}) => ({ // they are parsed as URIs and will throw errors if not fully formed. // The !! prefix causes it to ignore other loaders (doesn't work). search: "require\\.toUrl\\(", - replace: "location.protocol + '//' + location.host + '/' + require('!!file-loader?name=[path][name].[ext]!' + ", + replace: "location.protocol + '//' + location.host + location.pathname.replace(/\\/$/,'') + '/' + require('!!file-loader?name=[path][name].[ext]!' + ", flags: "g", }, { search: "require\\.__\\$__nodeRequire", From 2785e2219ad3da8d83074390432818e3ff070263 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Thu, 11 Apr 2019 02:11:51 +0000 Subject: [PATCH 2/9] Remove hosted from the readme --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 00b82faa2..547c336c1 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,6 @@ docker run -it -p 127.0.0.1:8443:8443 -v "${PWD}:/home/coder/project" codercom/c ## Getting Started -### Hosted - -[Try `code-server` now](https://coder.com/signup) for free at coder.com. - ### Docker See docker oneliner mentioned above. Dockerfile is at [/Dockerfile](/Dockerfile). From 7047be859cd51eadfcc2c73f8a30532ce023c123 Mon Sep 17 00:00:00 2001 From: Asher Date: Thu, 11 Apr 2019 14:55:06 -0500 Subject: [PATCH 3/9] Fix some open file/folder issues - "Open folder" now says "open folder" instead of "open file" - "Open folder" won't allow you to open files - "Open file" won't allow you to open directories Fixes #249. --- packages/server/src/cli.ts | 8 +++- packages/vscode/src/dialog.scss | 12 +++++ packages/vscode/src/dialog.ts | 51 ++++++++++++++++++++-- packages/vscode/src/fill/windowsService.ts | 22 ++++++---- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/packages/server/src/cli.ts b/packages/server/src/cli.ts index 790106285..ef18fd934 100644 --- a/packages/server/src/cli.ts +++ b/packages/server/src/cli.ts @@ -200,7 +200,13 @@ const bold = (text: string | number): string | number => { const webpackConfig = require(path.resolve(__dirname, "..", "..", "web", "webpack.config.js")); const compiler = require("webpack")(webpackConfig); app.use(require("webpack-dev-middleware")(compiler, { - logger, + logger: { + trace: (m: string): void => logger.trace("webpack", field("message", m)), + debug: (m: string): void => logger.debug("webpack", field("message", m)), + info: (m: string): void => logger.info("webpack", field("message", m)), + warn: (m: string): void => logger.warn("webpack", field("message", m)), + error: (m: string): void => logger.error("webpack", field("message", m)), + }, publicPath: webpackConfig.output.publicPath, stats: webpackConfig.stats, })); diff --git a/packages/vscode/src/dialog.scss b/packages/vscode/src/dialog.scss index 356270128..2d08911fe 100644 --- a/packages/vscode/src/dialog.scss +++ b/packages/vscode/src/dialog.scss @@ -2,6 +2,7 @@ --primary: #2A2E37; --border: black; --faded: #a0a1a5; + --disabled: #888; --header-background: #161616; --header-foreground: white; --list-active-selection-background: rgb(0, 120, 160); @@ -101,6 +102,12 @@ background-color: var(--list-active-selection-background); color: var(--list-active-selection-foreground); } + + &.disabled, &.disabled:hover { + background-color: var(--primary); + color: var(--disabled); + cursor: initial; + } } } @@ -134,6 +141,11 @@ color: white; } } + + button[disabled], button[disabled]:hover { + color: var(--disabled); + cursor: initial; + } } } diff --git a/packages/vscode/src/dialog.ts b/packages/vscode/src/dialog.ts index 4601b6d0a..1d480bd65 100644 --- a/packages/vscode/src/dialog.ts +++ b/packages/vscode/src/dialog.ts @@ -16,6 +16,9 @@ import { IThemeService } from "vs/platform/theme/common/themeService"; import { workbench } from "./workbench"; import "./dialog.scss"; +/** + * Describes the type of dialog to show. + */ export enum DialogType { NewFolder, Save, @@ -68,8 +71,12 @@ interface DialogEntry { readonly isDirectory: boolean; readonly size: number; readonly lastModified: string; + readonly isDisabled?: boolean; } +/** + * Open and save dialogs. + */ class Dialog { private _path: string | undefined; @@ -265,8 +272,7 @@ class Dialog { } if (element.isDirectory) { this.path = element.fullPath; - } else { - // Open + } else if (!(this.options as OpenDialogOptions).properties.openDirectory) { this.selectEmitter.emit(element.fullPath); } }); @@ -282,12 +288,18 @@ class Dialog { }); buttonsNode.appendChild(cancelBtn); const confirmBtn = document.createElement("button"); - confirmBtn.innerText = "Confirm"; + const openFile = (this.options as OpenDialogOptions).properties.openFile; + confirmBtn.innerText = openFile ? "Open" : "Confirm"; confirmBtn.addEventListener("click", () => { - if (this._path) { + if (this._path && !openFile) { this.selectEmitter.emit(this._path); } }); + // Since a single click opens a file, the only time this button can be + // used is on a directory, which is invalid for opening files. + if (openFile) { + confirmBtn.disabled = true; + } buttonsNode.appendChild(confirmBtn); this.root.appendChild(buttonsNode); this.entryList.layout(); @@ -303,6 +315,9 @@ class Dialog { return this.errorEmitter.event; } + /** + * Remove the dialog. + */ public dispose(): void { this.selectEmitter.dispose(); this.errorEmitter.dispose(); @@ -310,6 +325,9 @@ class Dialog { this.background.remove(); } + /** + * Build and insert the path shown at the top of the dialog. + */ private buildPath(): void { while (this.pathNode.lastChild) { this.pathNode.removeChild(this.pathNode.lastChild); @@ -376,6 +394,9 @@ class Dialog { return (this.entryList).typeFilterController.filter._pattern; } + /** + * List the files and return dialog entries. + */ private async list(directory: string): Promise> { const paths = (await util.promisify(fs.readdir)(directory)).sort(); const stats = await Promise.all(paths.map(p => util.promisify(fs.stat)(path.join(directory, p)))); @@ -386,6 +407,8 @@ class Dialog { isDirectory: stat.isDirectory(), lastModified: stat.mtime.toDateString(), size: stat.size, + // If we are opening a directory, show files as disabled. + isDisabled: !stat.isDirectory() && (this.options as OpenDialogOptions).properties.openDirectory, })); } } @@ -397,11 +420,17 @@ interface DialogEntryData { label: HighlightedLabel; } +/** + * Rendering for the different parts of a dialog entry. + */ class DialogEntryRenderer implements ITreeRenderer { public get templateId(): string { return "dialog-entry"; } + /** + * Append and return containers for each part of the dialog entry. + */ public renderTemplate(container: HTMLElement): DialogEntryData { addClass(container, "dialog-entry"); addClass(container, "dialog-grid"); @@ -422,6 +451,9 @@ class DialogEntryRenderer implements ITreeRenderer, _index: number, templateData: DialogEntryData): void { templateData.icon.className = "dialog-entry-icon monaco-icon-label"; const classes = getIconClasses( @@ -444,8 +476,19 @@ class DialogEntryRenderer implements ITreeRenderer { + public async pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise { showOpenDialog({ - ...(_options.dialogOptions || {}), + ...(options.dialogOptions || {}), properties: { openFile: true, openDirectory: true, @@ -66,9 +66,9 @@ export class WindowsService implements IWindowsService { }); } - public async pickFileAndOpen(_options: INativeOpenDialogOptions): Promise { + public async pickFileAndOpen(options: INativeOpenDialogOptions): Promise { showOpenDialog({ - ...(_options.dialogOptions || {}), + ...(options.dialogOptions || {}), properties: { openFile: true, }, @@ -84,9 +84,15 @@ export class WindowsService implements IWindowsService { }); } - public async pickFolderAndOpen(_options: INativeOpenDialogOptions): Promise { + public async pickFolderAndOpen(options: INativeOpenDialogOptions): Promise { + if (!options.dialogOptions) { + options.dialogOptions = {}; + } + if (!options.dialogOptions.title) { + options.dialogOptions.title = "Open Folder"; + } showOpenDialog({ - ...(_options.dialogOptions || {}), + ...(options.dialogOptions || {}), properties: { openDirectory: true, }, @@ -97,9 +103,9 @@ export class WindowsService implements IWindowsService { }); } - public async pickWorkspaceAndOpen(_options: INativeOpenDialogOptions): Promise { + public async pickWorkspaceAndOpen(options: INativeOpenDialogOptions): Promise { showOpenDialog({ - ...(_options.dialogOptions || {}), + ...(options.dialogOptions || {}), properties: { openDirectory: true, }, From 8f62b2bff2e1bb24f39f2fdd247e9f02d778117d Mon Sep 17 00:00:00 2001 From: Asher Date: Thu, 11 Apr 2019 14:58:29 -0500 Subject: [PATCH 4/9] Decrease max retry time to three seconds --- packages/ide/src/retry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ide/src/retry.ts b/packages/ide/src/retry.ts index 66a1575de..aefa79775 100644 --- a/packages/ide/src/retry.ts +++ b/packages/ide/src/retry.ts @@ -75,7 +75,7 @@ export class Retry { // Times are in seconds. private readonly retryMinDelay = 1; - private readonly retryMaxDelay = 10; + private readonly retryMaxDelay = 3; private readonly maxImmediateRetries = 5; private readonly retryExponent = 1.5; private blocked: string | boolean | undefined; From b781ccde9c596c47c5c99ed1e292a1510cc0b10f Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Thu, 11 Apr 2019 15:30:21 -0500 Subject: [PATCH 5/9] Add common utilities to Dockerfile (#488) --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8edaf8a93..05d04022d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,10 @@ RUN apt-get update && apt-get install -y \ git \ locales \ sudo \ - dumb-init + dumb-init \ + vim \ + curl \ + wget RUN locale-gen en_US.UTF-8 # We unfortunately cannot use update-locale because docker will not use the env variables From f7342ede6948da736c23e67b43c1a2f31dd1fac0 Mon Sep 17 00:00:00 2001 From: David Pinezich Date: Thu, 11 Apr 2019 23:18:13 +0200 Subject: [PATCH 6/9] Update digitalocean.md (#486) Seems that sudo ./code-server-linux -p 80 is outdated. The "linux" is not anymore given. --- doc/admin/install/digitalocean.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/admin/install/digitalocean.md b/doc/admin/install/digitalocean.md index 1a83d7bdb..1a1b7dd5e 100644 --- a/doc/admin/install/digitalocean.md +++ b/doc/admin/install/digitalocean.md @@ -39,7 +39,7 @@ If you're just starting out, we recommend [installing code-server locally](../.. > To ensure the connection between you and your server is encrypted view our guide on [securing your setup](../../security/ssl.md) - Finally start the code-server ``` - sudo ./code-server-linux -p 80 + sudo ./code-server -p 80 ``` > For instructions on how to keep the server running after you end your SSH session please checkout [how to use systemd](https://www.linode.com/docs/quick-answers/linux/start-service-at-boot/) to start linux based services if they are killed - When you visit the public IP for your Digital Ocean instance, you will be greeted with this page. Code-server is using a self-signed SSL certificate for easy setup. To proceed to the IDE, click **"Advanced"** From db57aa229fb62bac87b6b941df1a92e822caf257 Mon Sep 17 00:00:00 2001 From: John McCambridge Date: Fri, 12 Apr 2019 10:35:30 -0500 Subject: [PATCH 7/9] Allow use of the enter key for password input for code-server (#479) * Allow use of the enter key for password input for code-server * Remove function, make html form * Remove function and create html form * Handle form submit action * Remove button listener * Check if form exists --- packages/app/browser/src/app.html | 34 ++++++++++++++++--------------- packages/app/browser/src/app.ts | 13 +++++++----- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/packages/app/browser/src/app.html b/packages/app/browser/src/app.html index 99e237335..dadd6d540 100644 --- a/packages/app/browser/src/app.html +++ b/packages/app/browser/src/app.html @@ -7,22 +7,24 @@ - +
+ +
\ No newline at end of file diff --git a/packages/app/browser/src/app.ts b/packages/app/browser/src/app.ts index ddb35e7e2..9e377845f 100644 --- a/packages/app/browser/src/app.ts +++ b/packages/app/browser/src/app.ts @@ -20,11 +20,14 @@ window.addEventListener("message", (event) => { }); const password = document.getElementById("password") as HTMLInputElement; -const submit = document.getElementById("submit") as HTMLButtonElement; -if (!submit) { - throw new Error("No submit button found"); +const form = document.getElementById("login-form") as HTMLFormElement; + +if (!form) { + throw new Error("No password form found"); } -submit.addEventListener("click", () => { + +form.addEventListener("submit", (e) => { + e.preventDefault(); document.cookie = `password=${password.value}`; location.reload(); }); @@ -38,4 +41,4 @@ const errorDisplay = document.getElementById("error-display") as HTMLDivElement; if (document.referrer === document.location.href && matches) { errorDisplay.innerText = "Password is incorrect!"; -} \ No newline at end of file +} From 6c3ff1d6f01d393d6bef35c0c5944ae7a4b7dc16 Mon Sep 17 00:00:00 2001 From: Yen-Chi Chen Date: Fri, 12 Apr 2019 23:35:54 +0800 Subject: [PATCH 8/9] Fix typo: doc/self-hosted/index.md (#477) --- doc/self-hosted/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/self-hosted/index.md b/doc/self-hosted/index.md index 8626599c0..c3ee6a998 100644 --- a/doc/self-hosted/index.md +++ b/doc/self-hosted/index.md @@ -62,7 +62,7 @@ OPTIONS > Example: `code-server -h 127.0.0.1` ### Open - You can have the server automatically open the VS Code in your browser on startup by using the `code server -o` or `code-server --open` flags + You can have the server automatically open the VS Code in your browser on startup by using the `code-server -o` or `code-server --open` flags ### Port By default, code-server will use `8443` as its port. This can be changed by using `code-server -p` or `code-server --port=` followed by the port you want to use. From 742dd6f597850395957733dba81df42194b5cf58 Mon Sep 17 00:00:00 2001 From: Asher Date: Fri, 12 Apr 2019 16:10:45 -0500 Subject: [PATCH 9/9] Upgrade VS Code to 1.33.1 --- .travis.yml | 2 +- build/tasks.ts | 2 +- scripts/vstar.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 158ad64f6..4f9878df3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: node_js node_js: - 8.15.0 env: - - VSCODE_VERSION="1.33.0" MAJOR_VERSION="1" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER-vsc$VSCODE_VERSION" + - VSCODE_VERSION="1.33.1" MAJOR_VERSION="1" VERSION="$MAJOR_VERSION.$TRAVIS_BUILD_NUMBER-vsc$VSCODE_VERSION" matrix: include: - os: linux diff --git a/build/tasks.ts b/build/tasks.ts index b43316e17..3d7a563ab 100644 --- a/build/tasks.ts +++ b/build/tasks.ts @@ -12,7 +12,7 @@ const libPath = path.join(__dirname, "../lib"); const vscodePath = path.join(libPath, "vscode"); const defaultExtensionsPath = path.join(libPath, "extensions"); const pkgsPath = path.join(__dirname, "../packages"); -const vscodeVersion = process.env.VSCODE_VERSION || "1.33.0"; +const vscodeVersion = process.env.VSCODE_VERSION || "1.33.1"; const vsSourceUrl = `https://codesrv-ci.cdr.sh/vstar-${vscodeVersion}.tar.gz`; const buildServerBinary = register("build:server:binary", async (runner) => { diff --git a/scripts/vstar.sh b/scripts/vstar.sh index 835880634..c7be0b719 100755 --- a/scripts/vstar.sh +++ b/scripts/vstar.sh @@ -4,7 +4,7 @@ set -euxo pipefail # Builds a tarfile containing vscode sourcefiles neccessary for CI. # Done outside the CI and uploaded to object storage to reduce CI time. -branch=1.33.0 +branch=1.33.1 dir=/tmp/vstar outfile=/tmp/vstar-$branch.tar.gz rm -rf $dir