feat: add eslint add fix indent

This commit is contained in:
netcon
2021-02-09 13:29:57 +08:00
parent 62eb1a5e03
commit 26343837f8
45 changed files with 1800 additions and 769 deletions

15
.editorconfig Normal file
View File

@@ -0,0 +1,15 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Tab indentation
[*]
indent_style = tab
trim_trailing_whitespace = true
# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
[{*.yml,*.yaml,*.json}]
indent_style = space
indent_size = 2

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
**/node_modules/**
**/lib/vscode/**
**/dist/**

65
.eslintrc.json Normal file
View File

@@ -0,0 +1,65 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"jsdoc"
],
"rules": {
"constructor-super": "warn",
"curly": "warn",
"eqeqeq": "warn",
"no-buffer-constructor": "warn",
"no-caller": "warn",
"no-debugger": "warn",
"no-duplicate-case": "warn",
"no-duplicate-imports": "warn",
"no-eval": "warn",
"no-extra-semi": "warn",
"no-new-wrappers": "warn",
"no-redeclare": "off",
"no-sparse-arrays": "warn",
"no-throw-literal": "warn",
"no-unsafe-finally": "warn",
"no-unused-labels": "warn",
"no-restricted-globals": [
"warn",
"name",
"length",
"event",
"closed",
"external",
"status",
"origin",
"orientation",
"context"
], // non-complete list of globals that are easy to access unintentionally
"no-var": "warn",
"jsdoc/no-types": "warn",
"semi": "off",
"@typescript-eslint/semi": "warn",
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "class",
"format": [
"PascalCase"
]
}
]
},
"overrides": [
{
"files": [
"*.js"
],
"rules": {
"jsdoc/no-types": "off"
}
}
]
}

View File

@@ -7,63 +7,63 @@ import * as vscode from 'vscode';
import { fetch, RequestError, RequestRateLimitError, RequestInvalidTokenError, RequestNotFoundError, throttledReportNetworkError } from './util/fetch';
interface UriState {
owner: string;
repo: string;
branch: string;
path: string;
};
owner: string;
repo: string;
branch: string;
path: string;
}
const parseUri = (uri: vscode.Uri): UriState => {
const [owner, repo, branch] = (uri.authority || '').split('+').filter(Boolean);
return {
owner,
repo,
branch,
path: uri.path,
};
const [owner, repo, branch] = (uri.authority || '').split('+').filter(Boolean);
return {
owner,
repo,
branch,
path: uri.path,
};
};
const handleRequestError = (error: RequestError) => {
if (error instanceof RequestRateLimitError) {
if (!error.token) {
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Offer an OAuth Token.');
}
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Change Another OAuth Token.');
}
if (error instanceof RequestInvalidTokenError) {
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
}
if (error instanceof RequestNotFoundError) {
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
}
if (error instanceof RequestNotFoundError) {
throw vscode.FileSystemError.FileNotFound('GitHub Resource Not Found');
}
throw vscode.FileSystemError.Unavailable(error.message || 'Unknown Error Occurred When Request To GitHub');
if (error instanceof RequestRateLimitError) {
if (!error.token) {
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Offer an OAuth Token.');
}
throw vscode.FileSystemError.NoPermissions('API Rate Limit Exceeded, Please Change Another OAuth Token.');
}
if (error instanceof RequestInvalidTokenError) {
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
}
if (error instanceof RequestNotFoundError) {
throw vscode.FileSystemError.NoPermissions('Current OAuth Token Is Invalid, Please Change Another One.');
}
if (error instanceof RequestNotFoundError) {
throw vscode.FileSystemError.FileNotFound('GitHub Resource Not Found');
}
throw vscode.FileSystemError.Unavailable(error.message || 'Unknown Error Occurred When Request To GitHub');
};
export const readGitHubDirectory = (uri: vscode.Uri) => {
const state: UriState = parseUri(uri);
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/trees/${state.branch}${state.path.replace(/^\//, ':')}`)
.catch(handleRequestError)
const state: UriState = parseUri(uri);
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/trees/${state.branch}${state.path.replace(/^\//, ':')}`)
.catch(handleRequestError);
};
export const readGitHubFile = (uri: vscode.Uri, fileSha: string) => {
const state: UriState = parseUri(uri);
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/blobs/${fileSha}`)
.catch(handleRequestError);
const state: UriState = parseUri(uri);
return fetch(`https://api.github.com/repos/${state.owner}/${state.repo}/git/blobs/${fileSha}`)
.catch(handleRequestError);
};
export const validateToken = (token: string) => {
const authHeaders = token ? { Authorization: `token ${token}` } : {};
return self.fetch(`https://api.github.com`, { headers: { ...authHeaders } }).then(response => ({
token: !!token, // if the token is not empty
valid: response.status !== 401 ? true : false, // if the request is valid
limit: +response.headers.get('X-RateLimit-Limit') || 0, // limit count
remaining: +response.headers.get('X-RateLimit-Remaining') || 0, // remains request count
reset: +response.headers.get('X-RateLimit-Reset') || 0, // reset time
})).catch(() => {
throttledReportNetworkError();
throw new RequestError('Request Failed, Maybe an Network Error', token);
});
const authHeaders = token ? { Authorization: `token ${token}` } : {};
return self.fetch(`https://api.github.com`, { headers: { ...authHeaders } }).then(response => ({
token: !!token, // if the token is not empty
valid: response.status !== 401 ? true : false, // if the request is valid
limit: +response.headers.get('X-RateLimit-Limit') || 0, // limit count
remaining: +response.headers.get('X-RateLimit-Remaining') || 0, // remains request count
reset: +response.headers.get('X-RateLimit-Reset') || 0, // reset time
})).catch(() => {
throttledReportNetworkError();
throw new RequestError('Request Failed, Maybe an Network Error', token);
});
};

View File

@@ -8,55 +8,59 @@ import { getExtensionContext } from './util';
import { validateToken } from './api';
export const commandValidateToken = (silent: boolean = false) => {
const context = getExtensionContext();
const oAuthToken = context.globalState.get('github-oauth-token') as string || '';
return validateToken(oAuthToken).then(tokenStatus => {
if (!silent) {
const remaining = tokenStatus.remaining;
if (!oAuthToken) {
if (remaining > 0) {
vscode.window.showWarningMessage(`You haven\'t set a GitHub OAuth Token yet, and you can have ${remaining} requests in the current rate limit window.`);
} else {
vscode.window.showWarningMessage('You haven\'t set a GitHub OAuth Token yet, and the rate limit is exceeded.');
}
} else if (!tokenStatus.valid) {
vscode.window.showErrorMessage('Current GitHub OAuth Token is invalid.');
} else if (tokenStatus.valid && tokenStatus.remaining > 0) {
vscode.window.showInformationMessage(`Current GitHub OAuth Token is OK, and you can have ${remaining} requests in the current rate limit window.`);
} else if (tokenStatus.valid && tokenStatus.remaining <= 0) {
vscode.window.showWarningMessage('Current GitHub OAuth Token is Valid, but the rate limit is exceeded.');
}
}
return tokenStatus;
});
const context = getExtensionContext();
const oAuthToken = context.globalState.get('github-oauth-token') as string || '';
return validateToken(oAuthToken).then(tokenStatus => {
if (!silent) {
const remaining = tokenStatus.remaining;
if (!oAuthToken) {
if (remaining > 0) {
vscode.window.showWarningMessage(`You haven\'t set a GitHub OAuth Token yet, and you can have ${remaining} requests in the current rate limit window.`);
} else {
vscode.window.showWarningMessage('You haven\'t set a GitHub OAuth Token yet, and the rate limit is exceeded.');
}
} else if (!tokenStatus.valid) {
vscode.window.showErrorMessage('Current GitHub OAuth Token is invalid.');
} else if (tokenStatus.valid && tokenStatus.remaining > 0) {
vscode.window.showInformationMessage(`Current GitHub OAuth Token is OK, and you can have ${remaining} requests in the current rate limit window.`);
} else if (tokenStatus.valid && tokenStatus.remaining <= 0) {
vscode.window.showWarningMessage('Current GitHub OAuth Token is Valid, but the rate limit is exceeded.');
}
}
return tokenStatus;
});
};
export const commandUpdateToken = (silent: boolean = false) => {
return vscode.window.showInputBox({
placeHolder: 'Please input the GitHub OAuth Token',
}).then(token => {
if (!token) return;
return getExtensionContext()!.globalState.update('github-oauth-token', token || '').then(() => {
// we don't need wait validate, so we don't `return`
validateToken(token).then(tokenStatus => {
if (!silent) {
if (!tokenStatus.valid) vscode.window.showErrorMessage('GitHub OAuth Token have updated, but it is invalid.')
else if (tokenStatus.remaining <= 0) vscode.window.showWarningMessage('GitHub OAuth Token have updated, but the rate limit is exceeded.');
else vscode.window.showInformationMessage('GitHub OAuth Token have updated.');
}
tokenStatus.valid && tokenStatus.remaining > 0 && vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
});
});
});
return vscode.window.showInputBox({
placeHolder: 'Please input the GitHub OAuth Token',
}).then(token => {
if (!token) {
return;
}
return getExtensionContext()!.globalState.update('github-oauth-token', token || '').then(() => {
// we don't need wait validate, so we don't `return`
validateToken(token).then(tokenStatus => {
if (!silent) {
if (!tokenStatus.valid) {vscode.window.showErrorMessage('GitHub OAuth Token have updated, but it is invalid.');}
else if (tokenStatus.remaining <= 0) {vscode.window.showWarningMessage('GitHub OAuth Token have updated, but the rate limit is exceeded.');}
else {
vscode.window.showInformationMessage('GitHub OAuth Token have updated.');
}
}
tokenStatus.valid && tokenStatus.remaining > 0 && vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
});
});
});
};
export const commandClearToken = (silent: boolean = false) => {
return vscode.window.showWarningMessage('Would you want to clear the saved GitHub OAuth Token?', { modal: true }, 'Confirm').then(choose => {
if (choose === 'Confirm') {
return getExtensionContext()!.globalState.update('github-oauth-token', '').then(() => {
!silent && vscode.window.showInformationMessage('You have cleared the saved GitHb OAuth Token.');
}).then(() => true);
}
return false;
});
return vscode.window.showWarningMessage('Would you want to clear the saved GitHub OAuth Token?', { modal: true }, 'Confirm').then(choose => {
if (choose === 'Confirm') {
return getExtensionContext()!.globalState.update('github-oauth-token', '').then(() => {
!silent && vscode.window.showInformationMessage('You have cleared the saved GitHb OAuth Token.');
}).then(() => true);
}
return false;
});
};

View File

@@ -10,12 +10,12 @@ import { setExtensionContext } from './util';
import { commandUpdateToken, commandValidateToken, commandClearToken } from './commands';
export function activate(context: vscode.ExtensionContext) {
setExtensionContext(context);
context.subscriptions.push(new GitHub1sFS());
setExtensionContext(context);
context.subscriptions.push(new GitHub1sFS());
context.subscriptions.push(vscode.window.registerWebviewViewProvider(SettingsView.viewType, new SettingsView()));
context.subscriptions.push(vscode.window.registerWebviewViewProvider(SettingsView.viewType, new SettingsView()));
context.subscriptions.push(vscode.commands.registerCommand('github1s.validate-token', commandValidateToken));
context.subscriptions.push(vscode.commands.registerCommand('github1s.validate-token', commandValidateToken));
context.subscriptions.push(vscode.commands.registerCommand('github1s.update-token', commandUpdateToken));
context.subscriptions.push(vscode.commands.registerCommand('github1s.clear-token', commandClearToken));
};
}

View File

@@ -4,16 +4,16 @@
*/
import {
workspace,
Disposable,
FileSystemProvider,
FileSystemError,
Event,
EventEmitter,
FileChangeEvent,
FileStat,
FileType,
Uri,
workspace,
Disposable,
FileSystemProvider,
FileSystemError,
Event,
EventEmitter,
FileChangeEvent,
FileStat,
FileType,
Uri,
} from 'vscode';
import { noop, dirname, reuseable, b64DecodeUnicode} from './util';
import { readGitHubDirectory, readGitHubFile } from './api';
@@ -62,24 +62,24 @@ export class Directory implements FileStat {
export type Entry = File | Directory;
export class GitHub1sFS implements FileSystemProvider, Disposable {
static scheme = 'github1s';
private readonly disposable: Disposable;
private _emitter = new EventEmitter<FileChangeEvent[]>();
private root: Directory = null;
static scheme = 'github1s';
private readonly disposable: Disposable;
private _emitter = new EventEmitter<FileChangeEvent[]>();
private root: Directory = null;
onDidChangeFile: Event<FileChangeEvent[]> = this._emitter.event;
onDidChangeFile: Event<FileChangeEvent[]> = this._emitter.event;
constructor() {
this.disposable = Disposable.from(
constructor() {
this.disposable = Disposable.from(
workspace.registerFileSystemProvider(GitHub1sFS.scheme, this, { isCaseSensitive: true, isReadonly: true }),
);
}
}
dispose() {
this.disposable?.dispose();
}
dispose() {
this.disposable?.dispose();
}
// --- lookup
// --- lookup
private async _lookup(uri: Uri, silent: false): Promise<Entry>;
private async _lookup(uri: Uri, silent: boolean): Promise<Entry | undefined>;
private async _lookup(uri: Uri, silent: boolean): Promise<Entry | undefined> {
@@ -110,9 +110,9 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
if (entry instanceof Directory) {
return entry;
}
if (!silent) {
throw FileSystemError.FileNotADirectory(uri);
}
if (!silent) {
throw FileSystemError.FileNotADirectory(uri);
}
}
private async _lookupAsFile(uri: Uri, silent: boolean): Promise<File> {
@@ -120,9 +120,9 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
if (entry instanceof File) {
return entry;
}
if (!silent) {
throw FileSystemError.FileIsADirectory(uri);
}
if (!silent) {
throw FileSystemError.FileIsADirectory(uri);
}
}
private _lookupParentDirectory(uri: Uri): Promise<Directory> {
@@ -130,16 +130,18 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
return this._lookupAsDirectory(_dirname, false);
}
watch(uri: Uri, options: { recursive: boolean; excludes: string[]; }): Disposable {
return new Disposable(noop);
}
watch(uri: Uri, options: { recursive: boolean; excludes: string[]; }): Disposable {
return new Disposable(noop);
}
stat(uri: Uri): FileStat | Thenable<FileStat> {
return this._lookup(uri, false);
}
stat(uri: Uri): FileStat | Thenable<FileStat> {
return this._lookup(uri, false);
}
readDirectory = reuseable((uri: Uri): [string, FileType][] | Thenable<[string, FileType][]> => {
if (!uri.authority) throw FileSystemError.FileNotFound(uri);
readDirectory = reuseable((uri: Uri): [string, FileType][] | Thenable<[string, FileType][]> => {
if (!uri.authority) {
throw FileSystemError.FileNotFound(uri);
}
return this._lookupAsDirectory(uri, false).then(parent => {
if (parent.entries !== null) {
const res = Array.from(parent.entries.values())
@@ -161,10 +163,12 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
});
});
});
}, (uri: Uri) => uri.toString());
}, (uri: Uri) => uri.toString());
readFile = reuseable((uri: Uri): Uint8Array | Thenable<Uint8Array> => {
if (!uri.authority) throw FileSystemError.FileNotFound(uri);
if (!uri.authority) {
throw FileSystemError.FileNotFound(uri);
}
return this._lookupAsFile(uri, false).then(file => {
if (file.data !== null) {
return file.data;
@@ -175,26 +179,26 @@ export class GitHub1sFS implements FileSystemProvider, Disposable {
file.data = encoder.encode(b64DecodeUnicode(blob.content));
return file.data;
});
})
}, (uri: Uri) => uri.toString());
});
}, (uri: Uri) => uri.toString());
createDirectory(uri: Uri): void | Thenable<void> {
return Promise.resolve();
}
createDirectory(uri: Uri): void | Thenable<void> {
return Promise.resolve();
}
writeFile(uri: Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
writeFile(uri: Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
delete(uri: Uri, options: { recursive: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
delete(uri: Uri, options: { recursive: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
rename(oldUri: Uri, newUri: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
rename(oldUri: Uri, newUri: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
copy?(source: Uri, destination: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
copy?(source: Uri, destination: Uri, options: { overwrite: boolean; }): void | Thenable<void> {
return Promise.resolve();
}
}

View File

@@ -9,361 +9,367 @@ import { commandClearToken } from './commands';
import { validateToken } from './api';
interface WebviewState {
token?: string;
pageType?: 'EDIT' | 'PREVIEW';
valid?: boolean;
validating?: boolean;
};
token?: string;
pageType?: 'EDIT' | 'PREVIEW';
valid?: boolean;
validating?: boolean;
}
export class SettingsView implements vscode.WebviewViewProvider {
public static readonly viewType = 'github1s-settings';
private readonly _extensionContext: vscode.ExtensionContext;
private _webviewView: vscode.WebviewView;
public static readonly viewType = 'github1s-settings';
private readonly _extensionContext: vscode.ExtensionContext;
private _webviewView: vscode.WebviewView;
constructor() {
this._extensionContext = getExtensionContext();
}
constructor() {
this._extensionContext = getExtensionContext();
}
resolveWebviewView(
webviewView: vscode.WebviewView,
context: vscode.WebviewViewResolveContext<unknown>,
token: vscode.CancellationToken
): void | Thenable<void> {
this._webviewView = webviewView;
webviewView.webview.options = getWebviewOptions(this._extensionContext.extensionUri);
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
resolveWebviewView(
webviewView: vscode.WebviewView,
context: vscode.WebviewViewResolveContext<unknown>,
token: vscode.CancellationToken
): void | Thenable<void> {
this._webviewView = webviewView;
webviewView.webview.options = getWebviewOptions(this._extensionContext.extensionUri);
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);
webviewView.webview.onDidReceiveMessage(data => {
switch(data.type) {
case 'validate-token':
this.handleValidateToken(data.payload);
break;
case 'update-token':
this.handleUpdateToken(data.payload);
break;
case 'clear-token':
commandClearToken().then(cleared => {
cleared && this.updateWebviewState({token: '', pageType: 'EDIT', valid: false, validating: false });
})
break;
case 'welcome-page':
vscode.commands.executeCommand('workbench.action.showWelcomePage');
break;
default:
const oauthToken = this._extensionContext.globalState.get('github-oauth-token') as string|| '';
(oauthToken ? validateToken(oauthToken).then(data => (data.valid && data.remaining > 0)) : Promise.resolve(false)).then(isValid => {
this.updateWebviewState({ token: oauthToken, pageType: oauthToken ? 'PREVIEW' : 'EDIT', valid: isValid, validating: false });
});
}
});
}
webviewView.webview.onDidReceiveMessage(data => {
switch(data.type) {
case 'validate-token':
this.handleValidateToken(data.payload);
break;
case 'update-token':
this.handleUpdateToken(data.payload);
break;
case 'clear-token':
commandClearToken().then(cleared => {
cleared && this.updateWebviewState({token: '', pageType: 'EDIT', valid: false, validating: false });
});
break;
case 'welcome-page':
vscode.commands.executeCommand('workbench.action.showWelcomePage');
break;
default:
const oauthToken = this._extensionContext.globalState.get('github-oauth-token') as string|| '';
(oauthToken ? validateToken(oauthToken).then(data => (data.valid && data.remaining > 0)) : Promise.resolve(false)).then(isValid => {
this.updateWebviewState({ token: oauthToken, pageType: oauthToken ? 'PREVIEW' : 'EDIT', valid: isValid, validating: false });
});
}
});
}
updateWebviewState(state: WebviewState) {
this._webviewView.webview.postMessage({ type: 'update-state', payload: state });
}
updateWebviewState(state: WebviewState) {
this._webviewView.webview.postMessage({ type: 'update-state', payload: state });
}
handleValidateToken(token: string) {
this.updateWebviewState({ validating: true });
validateToken(token).then(tokenStatus => {
if (!tokenStatus.valid) vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
else if (tokenStatus.remaining <= 0) vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
else vscode.window.showInformationMessage('This GitHub OAuth Token is OK.');
this.updateWebviewState({ valid: tokenStatus.valid && tokenStatus.remaining > 0, validating: false });
}).catch(() => this.updateWebviewState({ valid: false, validating: false }));
}
handleValidateToken(token: string) {
this.updateWebviewState({ validating: true });
validateToken(token).then(tokenStatus => {
if (!tokenStatus.valid) {
vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
} else if (tokenStatus.remaining <= 0) {
vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
} else {
vscode.window.showInformationMessage('This GitHub OAuth Token is OK.');
}
this.updateWebviewState({ valid: tokenStatus.valid && tokenStatus.remaining > 0, validating: false });
}).catch(() => this.updateWebviewState({ valid: false, validating: false }));
}
handleUpdateToken(token: string) {
if (!token) return;
this.updateWebviewState({ validating: true });
validateToken(token).then(tokenStatus => {
if (!tokenStatus.valid) {
this.updateWebviewState({ pageType: 'EDIT', validating: false });
vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
} else if (tokenStatus.remaining <= 0) {
this.updateWebviewState({ pageType: 'EDIT', validating: false });
vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
} else {
this.updateWebviewState({ token, valid: true, pageType: 'PREVIEW', validating: false })
this._extensionContext.globalState.update('github-oauth-token', token || '').then(() => {
vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
});
}
}).catch(() => this.updateWebviewState({ token, validating: false }));
}
handleUpdateToken(token: string) {
if (!token) {
return;
}
this.updateWebviewState({ validating: true });
validateToken(token).then(tokenStatus => {
if (!tokenStatus.valid) {
this.updateWebviewState({ pageType: 'EDIT', validating: false });
vscode.window.showErrorMessage('This GitHub OAuth Token is invalid.');
} else if (tokenStatus.remaining <= 0) {
this.updateWebviewState({ pageType: 'EDIT', validating: false });
vscode.window.showWarningMessage('This GitHub OAuth Token is valid, but the rate limit is exceeded.');
} else {
this.updateWebviewState({ token, valid: true, pageType: 'PREVIEW', validating: false });
this._extensionContext.globalState.update('github-oauth-token', token || '').then(() => {
vscode.commands.executeCommand('workbench.files.action.refreshFilesExplorer');
});
}
}).catch(() => this.updateWebviewState({ token, validating: false }));
}
_getHtmlForWebview(webview): string {
const nonce = getNonce();
_getHtmlForWebview(webview): string {
const nonce = getNonce();
return `
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'nonce-${nonce}'; script-src 'nonce-${nonce}';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub1s Settings</title>
<style nonce="${nonce}">
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'nonce-${nonce}'; script-src 'nonce-${nonce}';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub1s Settings</title>
<style nonce="${nonce}">
html {
box-sizing: border-box;
font-size: 13px;
box-sizing: border-box;
font-size: 13px;
}
*,
*:before,
*:after {
box-sizing: inherit;
box-sizing: inherit;
}
body, h1, h2, h3, h4, h5, h6, p, ol, ul {
margin: 0;
padding: 0;
font-weight: normal;
margin: 0;
padding: 0;
font-weight: normal;
}
body {
background-color: transparent;
background-color: transparent;
}
input {
display: block;
width: 100%;
height: 24px;
border: none;
margin-bottom: 10px;
padding-left: 4px;
padding-right: 4px;
font-family: var(--vscode-font-family);
color: var(--vscode-input-foreground);
outline-color: var(--vscode-input-border);
background-color: var(--vscode-input-background);
display: block;
width: 100%;
height: 24px;
border: none;
margin-bottom: 10px;
padding-left: 4px;
padding-right: 4px;
font-family: var(--vscode-font-family);
color: var(--vscode-input-foreground);
outline-color: var(--vscode-input-border);
background-color: var(--vscode-input-background);
}
button {
border: none;
width: 100%;
height: 26px;
margin-bottom: 10px;
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
text-align: center;
outline: 1px solid transparent;
outline-offset: 2px !important;
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
border: none;
width: 100%;
height: 26px;
margin-bottom: 10px;
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
text-align: center;
outline: 1px solid transparent;
outline-offset: 2px !important;
color: var(--vscode-button-foreground);
background: var(--vscode-button-background);
}
button:hover {
cursor: pointer;
background: var(--vscode-button-hoverBackground);
cursor: pointer;
background: var(--vscode-button-hoverBackground);
}
button:focus {
outline-color: var(--vscode-focusBorder);
outline-color: var(--vscode-focusBorder);
}
button.secondary {
color: var(--vscode-button-secondaryForeground);
background: var(--vscode-button-secondaryBackground);
color: var(--vscode-button-secondaryForeground);
background: var(--vscode-button-secondaryBackground);
}
button.secondary:hover {
background: var(--vscode-button-secondaryHoverBackground);
background: var(--vscode-button-secondaryHoverBackground);
}
.loading-page {
width: 50px;
height: 40px;
margin: 60px auto;
text-align: center;
width: 50px;
height: 40px;
margin: 60px auto;
text-align: center;
}
.loading-page span {
width: 5px;
height: 100%;
margin-right: 4px;
display: inline-block;
background:#2b6298;
animation: loading 1.2s infinite ease-in-out;
-webkit-animation: loading 1.2s infinite ease-in-out;
width: 5px;
height: 100%;
margin-right: 4px;
display: inline-block;
background:#2b6298;
animation: loading 1.2s infinite ease-in-out;
-webkit-animation: loading 1.2s infinite ease-in-out;
}
.loading-page >span:nth-child(2) {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
.loading-page >span:nth-child(3) {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.loading-page >span:nth-child(4) {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
.loading-page >span:nth-child(5) {
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s;
-webkit-animation-delay: -0.7s;
animation-delay: -0.7s;
}
@keyframes loading {
0% { transform: scaleY(0.4); }
25% { transform: scaleY(1.0); }
50% { transform: scaleY(0.4); }
75% { transform: scaleY(0.4); }
100% { transform: scaleY(0.4); }
0% { transform: scaleY(0.4); }
25% { transform: scaleY(1.0); }
50% { transform: scaleY(0.4); }
75% { transform: scaleY(0.4); }
100% { transform: scaleY(0.4); }
}
.preview-page, .edit-page {
display: none;
display: none;
}
.container {
padding: 10px;
padding: 10px;
}
.container .token-invalid {
display: none;
display: none;
}
.page-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
}
.description {
margin-bottom: 10px;
margin-bottom: 10px;
}
.description div {
margin-bottom: 5px;
margin-bottom: 5px;
}
.description div:last-child {
margin-bottom: 0;
margin-bottom: 0;
}
.token-link {
margin-bottom: 10px;
margin-bottom: 10px;
}
</style>
</style>
</head>
<body>
<div class="loading-page">
<span></span><span></span><span></span><span></span><span></span>
</div>
<div class="container edit-page">
<div class="page-title">Set OAuth Token</div>
<div class="description">
<div>For unauthenticated requests, the rate limit of GitHub allows for up to 60 requests per hour.</div>
<div>For API requests using Authentication, you can make up to 5,000 requests per hour.</div>
</div>
<div class="token-link">
<a href="https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s" target="_blank">
Generate New OAuth Token
</a>
</div>
<div><input id="token-input" name="token" autocomplete="off" /></div>
<div><button id="save-button">Save</button></div>
<div><button id="preview-button">Cancel</button></div>
</div>
<div class="container preview-page">
<div class="page-title">You have authenticated</div>
<div class="description">
<div class="token-status">
Current OAuth Token is <span class="token-status-text"> ...</span>.
</div>
<div id="token-text"></div>
</div>
<div><button id="welcome-button">Detail</button></div>
<div><button id="validate-button">Validate</button></div>
<div><button id="edit-button">Edit</button></div>
<div><button id="clear-button">Clear</button></div>
</div>
<script nonce="${nonce}">
<div class="loading-page">
<span></span><span></span><span></span><span></span><span></span>
</div>
<div class="container edit-page">
<div class="page-title">Set OAuth Token</div>
<div class="description">
<div>For unauthenticated requests, the rate limit of GitHub allows for up to 60 requests per hour.</div>
<div>For API requests using Authentication, you can make up to 5,000 requests per hour.</div>
</div>
<div class="token-link">
<a href="https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s" target="_blank">
Generate New OAuth Token
</a>
</div>
<div><input id="token-input" name="token" autocomplete="off" /></div>
<div><button id="save-button">Save</button></div>
<div><button id="preview-button">Cancel</button></div>
</div>
<div class="container preview-page">
<div class="page-title">You have authenticated</div>
<div class="description">
<div class="token-status">
Current OAuth Token is <span class="token-status-text"> ...</span>.
</div>
<div id="token-text"></div>
</div>
<div><button id="welcome-button">Detail</button></div>
<div><button id="validate-button">Validate</button></div>
<div><button id="edit-button">Edit</button></div>
<div><button id="clear-button">Clear</button></div>
</div>
<script nonce="${nonce}">
(function () {
const vscode = acquireVsCodeApi();
const vscode = acquireVsCodeApi();
const updateState = (state) => {
const prevState = vscode.getState();
vscode.setState({ ...prevState, ...state });
updatePage();
};
const updateState = (state) => {
const prevState = vscode.getState();
vscode.setState({ ...prevState, ...state });
updatePage();
};
window.addEventListener('message', ({ data }) => {
if (data && data.type === 'update-state') {
updateState(data.payload);
}
});
vscode.postMessage({ type: 'initialization', payload: null });
window.addEventListener('message', ({ data }) => {
if (data && data.type === 'update-state') {
updateState(data.payload);
}
});
vscode.postMessage({ type: 'initialization', payload: null });
const delegate = (element, selector, eventName, handler) => {
if (!element) return null;
element.addEventListener(eventName, function (event) {
const children = element.querySelectorAll(selector);
for (let i = 0, len = children.length; i < len; i++) {
if (children[i] === event.target) {
handler.call(this, event);
}
}
});
};
const delegate = (element, selector, eventName, handler) => {
if (!element) return null;
element.addEventListener(eventName, function (event) {
const children = element.querySelectorAll(selector);
for (let i = 0, len = children.length; i < len; i++) {
if (children[i] === event.target) {
handler.call(this, event);
}
}
});
};
delegate(document.body, '#save-button', 'click', () => {
const tokenInput = document.getElementById('token-input');
vscode.postMessage({ type: 'update-token', payload: tokenInput ? tokenInput.value : '' });
});
delegate(document.body, '#save-button', 'click', () => {
const tokenInput = document.getElementById('token-input');
vscode.postMessage({ type: 'update-token', payload: tokenInput ? tokenInput.value : '' });
});
delegate(document.body, '#preview-button', 'click', () => {
updateState({ pageType: 'PREVIEW' });
});
delegate(document.body, '#preview-button', 'click', () => {
updateState({ pageType: 'PREVIEW' });
});
delegate(document.body, '#validate-button', 'click', () => {
const state = vscode.getState();
vscode.postMessage({ type: 'validate-token', payload: state ? state.token : '' });
});
delegate(document.body, '#validate-button', 'click', () => {
const state = vscode.getState();
vscode.postMessage({ type: 'validate-token', payload: state ? state.token : '' });
});
delegate(document.body, '#edit-button', 'click', () => {
updateState({ pageType: 'EDIT' });
});
delegate(document.body, '#edit-button', 'click', () => {
updateState({ pageType: 'EDIT' });
});
delegate(document.body, '#clear-button', 'click', () => {
vscode.postMessage({ type: 'clear-token' });
});
delegate(document.body, '#clear-button', 'click', () => {
vscode.postMessage({ type: 'clear-token' });
});
delegate(document.body, '#welcome-button', 'click', () => {
vscode.postMessage({ type: 'welcome-page' });
});
delegate(document.body, '#welcome-button', 'click', () => {
vscode.postMessage({ type: 'welcome-page' });
});
const updatePage = () => {
const { token, pageType, valid, validating } = vscode.getState() || { token: '', preview: 'EDIT', valid: true, validating: true };
if (validating) {
document.querySelector('.loading-page').style.display = 'block';
document.querySelector('.preview-page').style.display = 'none';
document.querySelector('.edit-page').style.display = 'none';
return;
}
const updatePage = () => {
const { token, pageType, valid, validating } = vscode.getState() || { token: '', preview: 'EDIT', valid: true, validating: true };
if (validating) {
document.querySelector('.loading-page').style.display = 'block';
document.querySelector('.preview-page').style.display = 'none';
document.querySelector('.edit-page').style.display = 'none';
return;
}
if (pageType === 'EDIT') {
document.querySelector('.loading-page').style.display = 'none';
document.querySelector('.preview-page').style.display = 'none';
document.querySelector('.edit-page').style.display = 'block';
document.querySelector('#preview-button').style.display = (token ? 'block' : 'none');
return;
}
if (pageType === 'EDIT') {
document.querySelector('.loading-page').style.display = 'none';
document.querySelector('.preview-page').style.display = 'none';
document.querySelector('.edit-page').style.display = 'block';
document.querySelector('#preview-button').style.display = (token ? 'block' : 'none');
return;
}
document.querySelector('.loading-page').style.display = 'none';
document.querySelector('.edit-page').style.display = 'none';
document.querySelector('.preview-page').style.display = 'block';
document.querySelector('.container .token-status .token-status-text').innerText = (valid ? ' VALID' : ' INVALID');
document.querySelector('#token-text').innerText = token.slice(0, 7) + token.slice(7).replace(/./g, '*');
document.querySelector('#token-text').style.color = (valid ? '#73c991' : '#f88070');
};
document.querySelector('.loading-page').style.display = 'none';
document.querySelector('.edit-page').style.display = 'none';
document.querySelector('.preview-page').style.display = 'block';
document.querySelector('.container .token-status .token-status-text').innerText = (valid ? ' VALID' : ' INVALID');
document.querySelector('#token-text').innerText = token.slice(0, 7) + token.slice(7).replace(/./g, '*');
document.querySelector('#token-text').style.color = (valid ? '#73c991' : '#f88070');
};
})();
</script>
</script>
</body>
</html>
`;
}
`;
}
}

View File

@@ -8,9 +8,9 @@ import * as vscode from 'vscode';
let extensionContext: vscode.ExtensionContext | null = null;
export const setExtensionContext = (_extensionContext: vscode.ExtensionContext) => {
extensionContext = _extensionContext;
extensionContext = _extensionContext;
};
export const getExtensionContext = (): vscode.ExtensionContext | null => {
return extensionContext;
return extensionContext;
};

View File

@@ -8,72 +8,72 @@ import { throttle } from './func';
import { getExtensionContext } from './context';
const getGitHubAuthToken = (): string => {
const context = getExtensionContext();
return context?.globalState.get('github-oauth-token') || '';
const context = getExtensionContext();
return context?.globalState.get('github-oauth-token') || '';
};
export class RequestError extends Error {
constructor(message: string, public token: string) {
super(message);
if (typeof (<any>Object).setPrototypeOf === 'function') {
constructor(message: string, public token: string) {
super(message);
if (typeof (<any>Object).setPrototypeOf === 'function') {
(<any>Object).setPrototypeOf(this, RequestError.prototype);
}
}
};
}
}
export class RequestNotFoundError extends RequestError {
constructor(message: string, token: string) {
super(message, token);
if (typeof (<any>Object).setPrototypeOf === 'function') {
constructor(message: string, token: string) {
super(message, token);
if (typeof (<any>Object).setPrototypeOf === 'function') {
(<any>Object).setPrototypeOf(this, RequestNotFoundError.prototype);
}
}
};
}
}
export class RequestRateLimitError extends RequestError {
constructor(message: string, token: string) {
super(message, token);
if (typeof (<any>Object).setPrototypeOf === 'function') {
constructor(message: string, token: string) {
super(message, token);
if (typeof (<any>Object).setPrototypeOf === 'function') {
(<any>Object).setPrototypeOf(this, RequestRateLimitError.prototype);
}
}
};
}
}
export class RequestInvalidTokenError extends RequestError {
constructor(message: string, token: string) {
super(message, token);
if (typeof (<any>Object).setPrototypeOf === 'function') {
constructor(message: string, token: string) {
super(message, token);
if (typeof (<any>Object).setPrototypeOf === 'function') {
(<any>Object).setPrototypeOf(this, RequestInvalidTokenError.prototype);
}RequestInvalidTokenError
}
};
};
}
}
// only report network error once in 5 seconds
export const throttledReportNetworkError = throttle(() => vscode.window.showErrorMessage('Request Failed, Maybe an Network Error'), 5000);
export const fetch = (url: string, options?: RequestInit) => {
const token = getGitHubAuthToken();
const authHeaders = token ? { Authorization: `token ${token}` } : {};
const customHeaders = (options && 'headers' in options ? options.headers : {})
const token = getGitHubAuthToken();
const authHeaders = token ? { Authorization: `token ${token}` } : {};
const customHeaders = (options && 'headers' in options ? options.headers : {});
return self.fetch(url, { mode: 'cors', ...options, headers: { ...authHeaders, ...customHeaders } })
.catch(() => {
throttledReportNetworkError();
throw new RequestError('Request Failed, Maybe an Network Error', token);
})
.then(response => {
if (response.status < 400) {
return response.json();
}
if (response.status === 403) {
return response.json().then(data => { throw new RequestRateLimitError(data.message, token); });
}
if (response.status === 401) {
return response.json().then(data => { throw new RequestInvalidTokenError(data.message, token); });
}
if (response.status === 404) {
throw new RequestNotFoundError('Not Found', token);
}
throw new RequestError(`GitHub1s: Request got HTTP ${response.status} response`, token);
});
return self.fetch(url, { mode: 'cors', ...options, headers: { ...authHeaders, ...customHeaders } })
.catch(() => {
throttledReportNetworkError();
throw new RequestError('Request Failed, Maybe an Network Error', token);
})
.then(response => {
if (response.status < 400) {
return response.json();
}
if (response.status === 403) {
return response.json().then(data => { throw new RequestRateLimitError(data.message, token); });
}
if (response.status === 401) {
return response.json().then(data => { throw new RequestInvalidTokenError(data.message, token); });
}
if (response.status === 404) {
throw new RequestNotFoundError('Not Found', token);
}
throw new RequestError(`GitHub1s: Request got HTTP ${response.status} response`, token);
});
};

View File

@@ -11,25 +11,27 @@ const defaultComputeCacheKey = (...args) => jsonStableStringify([...args]);
// reuse previous promise when a request call
// and previous request not completed
export const reuseable = (func, computeCacheKey = defaultComputeCacheKey) => {
const cache = new Map<string, Promise<any>>();
const cache = new Map<string, Promise<any>>();
return function (...args: any[]): Promise<any> {
const key = computeCacheKey(...args);
if (cache.has(key)) {
return cache.get(key);
}
return function (...args: any[]): Promise<any> {
const key = computeCacheKey(...args);
if (cache.has(key)) {
return cache.get(key);
}
const promise = func.call(this, ...args);
cache.set(key, promise);
return pFinally(promise, () => cache.delete(key));
};
const promise = func.call(this, ...args);
cache.set(key, promise);
return pFinally(promise, () => cache.delete(key));
};
};
export const throttle = (func: Function, interval: number) => {
let timer = null;
return function(...args: any[]): any {
if (timer) return;
func.call(this, ...args);
timer = setTimeout(() => (timer = null), interval);
}
let timer = null;
return function(...args: any[]): any {
if (timer) {
return;
}
func.call(this, ...args);
timer = setTimeout(() => (timer = null), interval);
};
};

View File

@@ -11,51 +11,51 @@ export { getExtensionContext, setExtensionContext } from './context';
export const noop = () => { };
export const trimStart = (str: string, chars: string = ' '): string => {
let index = 0;
while (chars.indexOf(str[index]) !== -1) {
index++;
}
return str.slice(index);
let index = 0;
while (chars.indexOf(str[index]) !== -1) {
index++;
}
return str.slice(index);
};
export const trimEnd = (str: string, chars: string = ' '): string => {
let length = str.length;
while (length && chars.indexOf(str[length - 1]) !== -1) {
length--;
}
return str.slice(0, length);
let length = str.length;
while (length && chars.indexOf(str[length - 1]) !== -1) {
length--;
}
return str.slice(0, length);
};
export const joinPath = (...segments: string[]): string => {
if (!segments.length) {
return '';
}
if (!segments.length) {
return '';
}
return segments.reduce((prev, segment) => {
return trimEnd(prev, '/') + '/' + trimStart(segment, '/');
});
return segments.reduce((prev, segment) => {
return trimEnd(prev, '/') + '/' + trimStart(segment, '/');
});
};
export const dirname = (path: string): string => {
const trimmedPath = trimEnd(path, '/');
return trimmedPath.substr(0, trimmedPath.lastIndexOf('/')) || '';
}
const trimmedPath = trimEnd(path, '/');
return trimmedPath.substr(0, trimmedPath.lastIndexOf('/')) || '';
};
export const uniqueId = (id => () => id++)(1);
export const prop = (obj: object, path: (string | number)[] = []): any => {
let cur = obj;
path.forEach(key => (cur = (cur ? cur[key] : undefined)));
return cur;
let cur = obj;
path.forEach(key => (cur = (cur ? cur[key] : undefined)));
return cur;
};
export const getNonce = (): string => {
let text: string = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
let text: string = '';
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
export const getWebviewOptions = (extensionUri: vscode.Uri): vscode.WebviewOptions => {
@@ -68,9 +68,9 @@ export const getWebviewOptions = (extensionUri: vscode.Uri): vscode.WebviewOptio
};
export const b64DecodeUnicode = (str) => {
// https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
// https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
}
};

View File

@@ -8,9 +8,14 @@
},
"dependencies": {},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.15.0",
"@typescript-eslint/parser": "^4.15.0",
"chokidar": "^3.5.1",
"eslint": "^7.19.0",
"eslint-plugin-jsdoc": "^31.6.1",
"fs-extra": "^9.1.0",
"serve-handler": "^6.1.3"
"serve-handler": "^6.1.3",
"typescript": "^4.1.3"
},
"scripts": {
"postinstall": "./scripts/postinstall.sh",
@@ -20,7 +25,8 @@
"hash": "./scripts/hash.sh",
"package": "./scripts/package.sh",
"watch": "./scripts/watch.sh",
"serve": "node ./scripts/serve-dist.js"
"serve": "node ./scripts/serve-dist.js",
"eslint": "eslint --ext .ts --ext .js ./src/vs ./extensions"
},
"keywords": [],
"author": "",

View File

@@ -55,6 +55,6 @@
document.getElementById('vscode-workbench-builtin-extensions').setAttribute('data-settings', extensionsJson);
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/static/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
require(['vs/code/browser/workbench/workbench'], function() {});
});
});
</script>
</html>

View File

@@ -54,8 +54,8 @@
<script>
fetch('/{STATIC_FOLDER}/configure/extensions.json').then(response => response.text()).then(extensionsJson => {
document.getElementById('vscode-workbench-builtin-extensions').setAttribute('data-settings', extensionsJson);
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/{STATIC_FOLDER}/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/{STATIC_FOLDER}/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
require(['vs/code/browser/workbench/workbench'], function() {});
});
});
</script>
</html>

View File

@@ -56,6 +56,6 @@
document.getElementById('vscode-workbench-builtin-extensions').setAttribute('data-settings', extensionsJson);
document.getElementById('vscode-extension-host-iframe-src').setAttribute('data-settings', '/static/vscode/vs/workbench/services/extensions/worker/httpWebWorkerExtensionHostIframe.html');
require(['vs/code/browser/workbench/workbench'], function() {});
});
});
</script>
</html>

View File

@@ -7,14 +7,14 @@ export IS_BUILD="true"
# execute all necessary tasks
function main() {
rm -rf "${APP_ROOT}/dist"
cd "${APP_ROOT}/scripts"
./build/sync-code.sh
./build/build-vscode.sh
./build/build-github1s-extensions.sh
./package.sh
rm -rf "${APP_ROOT}/dist"
cd "${APP_ROOT}/scripts"
./build/sync-code.sh
./build/build-vscode.sh
./build/build-github1s-extensions.sh
./package.sh
echo "all build done!"
echo "all build done!"
}
main "$@"

View File

@@ -5,9 +5,9 @@ cd "$(dirname "${0}")/../.."
APP_ROOT=$(pwd)
function main() {
cd "${APP_ROOT}/extensions/github1s"
yarn build
echo "build github1s-extensions done!"
cd "${APP_ROOT}/extensions/github1s"
yarn build
echo "build github1s-extensions done!"
}
main "$@"

View File

@@ -6,15 +6,15 @@ APP_ROOT=$(pwd)
# build vscode source and vscode builtin extensions
function main() {
cd ${APP_ROOT}
rsync -a resources/gulp-github1s.js lib/vscode
cd lib/vscode
cd ${APP_ROOT}
rsync -a resources/gulp-github1s.js lib/vscode
cd lib/vscode
yarn gulp compile-build
yarn gulp optimize --gulpfile ./gulp-github1s.js
yarn gulp minify --gulpfile ./gulp-github1s.js
yarn gulp compile-build
yarn gulp optimize --gulpfile ./gulp-github1s.js
yarn gulp minify --gulpfile ./gulp-github1s.js
echo "build vscode done!"
echo "build vscode done!"
}
main "$@"

View File

@@ -6,8 +6,8 @@ APP_ROOT=$(pwd)
# sync src/* to vscode
function main() {
cd ${APP_ROOT}
rsync -a src/ lib/vscode/src
cd ${APP_ROOT}
rsync -a src/ lib/vscode/src
}
main "$@"

View File

@@ -6,9 +6,9 @@ APP_ROOT=$(pwd)
# execute all necessary tasks
function main() {
cd ${APP_ROOT}
rm -rf dist extensions/github1s/dist
echo "remove dist"
cd ${APP_ROOT}
rm -rf dist extensions/github1s/dist
echo "remove dist"
}
main "$@"

View File

@@ -6,10 +6,10 @@ APP_ROOT=$(pwd)
# execute all necessary tasks
function main() {
./scripts/clean-build.sh
cd ${APP_ROOT}
rm -rf node_modules lib extensions/github1s/node_modules
echo "clean all"
./scripts/clean-build.sh
cd ${APP_ROOT}
rm -rf node_modules lib extensions/github1s/node_modules
echo "clean all"
}
main "$@"

View File

@@ -9,9 +9,9 @@ SHORT_COMMIT_ID=${COMMIT_ID:0:7}
STATIC_FOLDER_NAME="static-${SHORT_COMMIT_ID-unknown}"
if [ -e "${APP_ROOT}/dist/static" ]; then
mv "${APP_ROOT}/dist/static" "${APP_ROOT}/dist/${STATIC_FOLDER_NAME}"
sed "s/{STATIC_FOLDER}/${STATIC_FOLDER_NAME}/" "${APP_ROOT}/resources/index-hash.html" > "${APP_ROOT}/dist/index.html"
echo "hash static files done"
mv "${APP_ROOT}/dist/static" "${APP_ROOT}/dist/${STATIC_FOLDER_NAME}"
sed "s/{STATIC_FOLDER}/${STATIC_FOLDER_NAME}/" "${APP_ROOT}/resources/index-hash.html" > "${APP_ROOT}/dist/index.html"
echo "hash static files done"
else
echo "Please build github1s first"
echo "Please build github1s first"
fi

View File

@@ -5,14 +5,14 @@ cd "$(dirname "${0}")/.."
APP_ROOT=$(pwd)
function main() {
cd "${APP_ROOT}/scripts"
./package/copy-vscode.sh
./package/copy-extensions.sh
./package/copy-node_modules.sh
./package/copy-resources.sh
node ./package/generate-config.js
cd "${APP_ROOT}/scripts"
./package/copy-vscode.sh
./package/copy-extensions.sh
./package/copy-node_modules.sh
./package/copy-resources.sh
node ./package/generate-config.js
echo "all copy done!"
echo "all copy done!"
}
main "$@"

View File

@@ -8,21 +8,21 @@ const TARGET_DIR = path.join(APP_ROOT, 'dist/static/extensions');
const enableExtensions = require(path.join(APP_ROOT, 'resources/builtin-extensions.json')) || [];
const main = () => {
fs.ensureDirSync(TARGET_DIR);
fs.ensureDirSync(TARGET_DIR);
enableExtensions.forEach(extension => {
fs.copySync(
path.join(APP_ROOT, 'lib/vscode', extension.path),
path.join(TARGET_DIR, path.basename(extension.path)),
{ filter: src => !src.includes('node_modules') }
);
});
enableExtensions.forEach(extension => {
fs.copySync(
path.join(APP_ROOT, 'lib/vscode', extension.path),
path.join(TARGET_DIR, path.basename(extension.path)),
{ filter: src => !src.includes('node_modules') }
);
});
fs.copySync(
path.join(APP_ROOT, 'extensions/github1s'),
path.join(TARGET_DIR, 'github1s'),
{ filter: src => !src.includes('node_modules') }
);
fs.copySync(
path.join(APP_ROOT, 'extensions/github1s'),
path.join(TARGET_DIR, 'github1s'),
{ filter: src => !src.includes('node_modules') }
);
};
main();

View File

@@ -5,21 +5,21 @@ cd "$(dirname "${0}")/../.."
APP_ROOT=$(pwd)
function ensureBuiltinExtensitions() {
cd "${APP_ROOT}/lib/vscode"
if [ ! -e "extensions/emmet/dist/browser" ]
then
echo "compile vscode builtin extensions..."
yarn gulp compile-web
fi
cd "${APP_ROOT}/lib/vscode"
if [ ! -e "extensions/emmet/dist/browser" ]
then
echo "compile vscode builtin extensions..."
yarn gulp compile-web
fi
}
function main() {
ensureBuiltinExtensitions
cd ${APP_ROOT}
mkdir -p dist/static/extensions
node scripts/package/copy-extensions.js
ensureBuiltinExtensitions
cd ${APP_ROOT}
mkdir -p dist/static/extensions
node scripts/package/copy-extensions.js
echo "copy vscode builtin extensions done!"
echo "copy vscode builtin extensions done!"
}
main "$@"

View File

@@ -5,16 +5,16 @@ cd "$(dirname "${0}")/../.."
APP_ROOT=$(pwd)
function main() {
cd ${APP_ROOT}
mkdir -p dist/static/node_modules
dependencies=(vscode-textmate vscode-oniguruma xterm xterm-addon-search xterm-addon-unicode11 xterm-addon-webgl tas-client-umd iconv-lite-umd jschardet)
cd ${APP_ROOT}
mkdir -p dist/static/node_modules
dependencies=(vscode-textmate vscode-oniguruma xterm xterm-addon-search xterm-addon-unicode11 xterm-addon-webgl tas-client-umd iconv-lite-umd jschardet)
for dependency in ${dependencies[@]};
do
rsync -a --del lib/vscode/node_modules/${dependency} dist/static/node_modules
done
for dependency in ${dependencies[@]};
do
rsync -a --del lib/vscode/node_modules/${dependency} dist/static/node_modules
done
echo "copy necessary node_modules done!"
echo "copy necessary node_modules done!"
}
main "$@"

View File

@@ -5,18 +5,18 @@ cd "$(dirname "${0}")/../.."
APP_ROOT=$(pwd)
function main() {
cd ${APP_ROOT}
mkdir -p dist
if [ "${IS_BUILD-}" ];
then
cp resources/index.html dist/index.html
else
cp resources/index-dev.html dist/index.html
fi
cp resources/favicon.ico dist
cp resources/manifest.json dist
cd ${APP_ROOT}
mkdir -p dist
if [ "${IS_BUILD-}" ];
then
cp resources/index.html dist/index.html
else
cp resources/index-dev.html dist/index.html
fi
cp resources/favicon.ico dist
cp resources/manifest.json dist
echo "copy resources done!"
echo "copy resources done!"
}
main "$@"

View File

@@ -5,11 +5,11 @@ cd "$(dirname "${0}")/../.."
APP_ROOT=$(pwd)
function main() {
cd ${APP_ROOT}
mkdir -p dist/static
rsync -a --del lib/vscode/out-vscode-min/ dist/static/vscode
cd ${APP_ROOT}
mkdir -p dist/static
rsync -a --del lib/vscode/out-vscode-min/ dist/static/vscode
echo "copy vscode done!"
echo "copy vscode done!"
}
main "$@"

View File

@@ -19,44 +19,44 @@ const isWebExtension = (manifest) => {
};
const getExtensionData = (absolutePath) => {
try {
const packageJSONPath = path.join(absolutePath, 'package.json');
if (!fs.existsSync(packageJSONPath)) {
return null;
}
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8'));
if (!isWebExtension(packageJSON)) {
return null;
}
const children = fs.readdirSync(absolutePath);
const packageNLSPath = children.filter(child => child === 'package.nls.json')[0];
const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(absolutePath, packageNLSPath)).toString()) : undefined;
const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
const extensionFolder = path.basename(absolutePath);
try {
const packageJSONPath = path.join(absolutePath, 'package.json');
if (!fs.existsSync(packageJSONPath)) {
return null;
}
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8'));
if (!isWebExtension(packageJSON)) {
return null;
}
const children = fs.readdirSync(absolutePath);
const packageNLSPath = children.filter(child => child === 'package.nls.json')[0];
const packageNLS = packageNLSPath ? JSON.parse(fs.readFileSync(path.join(absolutePath, packageNLSPath)).toString()) : undefined;
const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
const extensionFolder = path.basename(absolutePath);
return {
extensionPath: extensionFolder,
packageJSON,
packageNLS,
readmePath: readme ? path.join(extensionFolder, readme) : undefined,
changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined,
};
} catch {
return null;
}
return {
extensionPath: extensionFolder,
packageJSON,
packageNLS,
readmePath: readme ? path.join(extensionFolder, readme) : undefined,
changelogPath: changelog ? path.join(extensionFolder, changelog) : undefined,
};
} catch {
return null;
}
};
const scanBuiltinExtensions = () => {
return enableExtensions.map(item => getExtensionData(path.join(VSCODE_PATH, item.path))).filter(Boolean);
return enableExtensions.map(item => getExtensionData(path.join(VSCODE_PATH, item.path))).filter(Boolean);
};
const main = () => {
const CONFIGURE_PATH = path.join(APP_ROOT, 'dist/static/configure');
const extensions = [...scanBuiltinExtensions(), getExtensionData(path.join(APP_ROOT, 'extensions/github1s'))];
const CONFIGURE_PATH = path.join(APP_ROOT, 'dist/static/configure');
const extensions = [...scanBuiltinExtensions(), getExtensionData(path.join(APP_ROOT, 'extensions/github1s'))];
fs.ensureDirSync(CONFIGURE_PATH);
fs.writeFileSync(path.join(CONFIGURE_PATH, 'extensions.json'), JSON.stringify(extensions));
fs.ensureDirSync(CONFIGURE_PATH);
fs.writeFileSync(path.join(CONFIGURE_PATH, 'extensions.json'), JSON.stringify(extensions));
};
main();

View File

@@ -5,17 +5,17 @@ cd "$(dirname "${0}")/.."
APP_ROOT=$(pwd)
function main() {
# install github1s extension dependencies
cd ${APP_ROOT}/extensions/github1s
yarn ${CI+--frozen-lockfile}
# install github1s extension dependencies
cd ${APP_ROOT}/extensions/github1s
yarn ${CI+--frozen-lockfile}
# clone vscode and install dependencies
cd ${APP_ROOT}
mkdir -p lib
cd lib
git clone --depth 1 -b 1.52.1 https://github.com/microsoft/vscode.git vscode
cd vscode
yarn ${CI+--frozen-lockfile}
# clone vscode and install dependencies
cd ${APP_ROOT}
mkdir -p lib
cd lib
git clone --depth 1 -b 1.52.1 https://github.com/microsoft/vscode.git vscode
cd vscode
yarn ${CI+--frozen-lockfile}
}
main "$@"

View File

@@ -10,13 +10,13 @@ const APP_ROOT = path.join(__dirname, '..');
const options = { public: path.join(APP_ROOT, 'dist'), cleanUrls: false, };
const server = http.createServer((request, response) => {
const urlObj = url.parse(request.url);
return fs.access(path.join(APP_ROOT, 'dist', urlObj.pathname), fs.constants.F_OK, (error) => {
if (!error) return handler(request, response, options);
return handler(request, response, { rewrites: [{ source: '*', destination: '/index.html' }], ...options });
});
const urlObj = url.parse(request.url);
return fs.access(path.join(APP_ROOT, 'dist', urlObj.pathname), fs.constants.F_OK, (error) => {
if (!error) return handler(request, response, options);
return handler(request, response, { rewrites: [{ source: '*', destination: '/index.html' }], ...options });
});
});
server.listen(5000, () => {
console.log('Running GitHub1s at http://localhost:5000');
console.log('Running GitHub1s at http://localhost:5000');
});

View File

@@ -5,48 +5,48 @@ cd "$(dirname "${0}")/.."
APP_ROOT=$(pwd)
function watch_vscode() {
cd ${APP_ROOT}/lib/vscode
yarn watch 2>&1 > /dev/null &
echo "watching vscode"
cd ${APP_ROOT}/lib/vscode
yarn watch 2>&1 > /dev/null &
echo "watching vscode"
}
function watch_github1s() {
cd ${APP_ROOT}/scripts/watch
node watch-src.js 2>&1 > /dev/null &
echo "watching github1s"
cd ${APP_ROOT}/scripts/watch
node watch-src.js 2>&1 > /dev/null &
echo "watching github1s"
}
function watch_github1s_extension() {
cd ${APP_ROOT}/extensions/github1s
yarn dev 2>&1 > /dev/null &
echo "watching github1s_extensions"
cd ${APP_ROOT}/extensions/github1s
yarn dev 2>&1 > /dev/null &
echo "watching github1s_extensions"
}
function watch_dist() {
cd ${APP_ROOT}/scripts/watch
node watch-dist.js
echo "auto sync to dist"
cd ${APP_ROOT}/scripts/watch
node watch-dist.js
echo "auto sync to dist"
}
# execute all necessary tasks
function main() {
rm -rf "${APP_ROOT}/dist"
cd "${APP_ROOT}/scripts"
./package/copy-resources.sh
./package/copy-node_modules.sh
./package/copy-extensions.sh
node ./package/generate-config.js
watch_vscode
watch_github1s
watch_github1s_extension
rm -rf "${APP_ROOT}/dist"
cd "${APP_ROOT}/scripts"
./package/copy-resources.sh
./package/copy-node_modules.sh
./package/copy-extensions.sh
node ./package/generate-config.js
watch_vscode
watch_github1s
watch_github1s_extension
echo 'please waiting...'
while [ ! -e "${APP_ROOT}/lib/vscode/out" ]
do
echo "waiting for vsocde build..."
sleep 3
done
watch_dist
echo 'please waiting...'
while [ ! -e "${APP_ROOT}/lib/vscode/out" ]
do
echo "waiting for vsocde build..."
sleep 3
done
watch_dist
}
main "$@"

View File

@@ -9,48 +9,48 @@ const util = require('util');
const APP_ROOT = path.join(__dirname, '../..');
const debounce = (func, delay) => {
let timer = null;
let lastResult = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
lastResult = func.apply(this, Array.prototype.slice.call(arguments, 0));
}, delay);
return lastResult;
};
let timer = null;
let lastResult = null;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
lastResult = func.apply(this, Array.prototype.slice.call(arguments, 0));
}, delay);
return lastResult;
};
};
const autoSyncVscodeOut = async () => {
const SOURCE = path.join(APP_ROOT, 'lib/vscode/out');
const TARGET = path.join(APP_ROOT, 'dist/static/vscode');
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
console.log(`sync ${path}`);
}, 300));
const SOURCE = path.join(APP_ROOT, 'lib/vscode/out');
const TARGET = path.join(APP_ROOT, 'dist/static/vscode');
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
console.log(`sync ${path}`);
}, 300));
};
const autoSyncGitHub1sExtension = async () => {
const SOURCE = path.join(APP_ROOT, 'extensions/github1s');
const TARGET = path.join(APP_ROOT, 'dist/static/extensions/github1s');
const SOURCE = path.join(APP_ROOT, 'extensions/github1s');
const TARGET = path.join(APP_ROOT, 'dist/static/extensions/github1s');
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
await util.promisify(cp.exec)(`rsync -a ${SOURCE}/ ${TARGET}`);
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
console.log(`sync ${path}`);
}, 300));
chokidar.watch(SOURCE).on('all', debounce((_, path) => {
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
console.log(`sync ${path}`);
}, 300));
};
const main = () => {
fs.ensureDirSync(path.join(APP_ROOT, 'dist/static'))
fs.ensureDirSync(path.join(APP_ROOT, 'dist/static'))
autoSyncVscodeOut();
autoSyncGitHub1sExtension();
autoSyncVscodeOut();
autoSyncGitHub1sExtension();
};
main();

View File

@@ -7,13 +7,13 @@ const cp = require('child_process');
const APP_ROOT = path.join(__dirname, '../..');
const main = () => {
const SOURCE = path.join(APP_ROOT, 'src');
const TARGET = path.join(APP_ROOT, 'lib/vscode/src');
const watcher = chokidar.watch(SOURCE);
const SOURCE = path.join(APP_ROOT, 'src');
const TARGET = path.join(APP_ROOT, 'lib/vscode/src');
const watcher = chokidar.watch(SOURCE);
watcher.on('all', () => {
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
});
watcher.on('all', () => {
cp.exec(`rsync -a ${SOURCE}/ ${TARGET}`);
});
};
main();

View File

@@ -398,12 +398,12 @@ class WindowIndicator implements IWindowIndicator {
}
(function () {
const route = parseGitHubUrl(window.location.href);
const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = {
folderUri: URI.from({ scheme: "github1s", path: '/', authority: `${route.owner}+${route.repo}+${route.branch}` }),
staticExtensions: [],
enableSyncByDefault: false,
webWorkerExtensionHostIframeSrc: document.getElementById('vscode-extension-host-iframe-src')?.getAttribute('data-settings') as string,
const route = parseGitHubUrl(window.location.href);
const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = {
folderUri: URI.from({ scheme: "github1s", path: '/', authority: `${route.owner}+${route.repo}+${route.branch}` }),
staticExtensions: [],
enableSyncByDefault: false,
webWorkerExtensionHostIframeSrc: document.getElementById('vscode-extension-host-iframe-src')?.getAttribute('data-settings') as string,
};
// Revive static extension locations

View File

@@ -4,28 +4,28 @@
*/
interface GitHubRouteState {
owner: string;
repo: string;
type: string;
branch: string;
path: string;
search: string;
hash: string;
owner: string;
repo: string;
type: string;
branch: string;
path: string;
search: string;
hash: string;
}
export const parseGitHubUrl = (url: string): GitHubRouteState => {
const urlObj = new window.URL(url);
const parts = urlObj.pathname.split('/').filter(Boolean);
const hasFileType = ['tree', 'blob'].includes(parts[2]);
const hasBranchName = hasFileType && parts[3];
const urlObj = new window.URL(url);
const parts = urlObj.pathname.split('/').filter(Boolean);
const hasFileType = ['tree', 'blob'].includes(parts[2]);
const hasBranchName = hasFileType && parts[3];
return {
owner: parts[0] || 'conwnet',
repo: parts[1] || 'github1s',
type: (hasFileType ? parts[2] : 'tree').toLowerCase(),
branch: hasBranchName ? parts[3] : 'HEAD',
path: '/' + (hasBranchName ? parts.slice(4).join('/') : ''),
search: urlObj.search || '',
hash: urlObj.hash || ''
};
return {
owner: parts[0] || 'conwnet',
repo: parts[1] || 'github1s',
type: (hasFileType ? parts[2] : 'tree').toLowerCase(),
branch: hasBranchName ? parts[3] : 'HEAD',
path: '/' + (hasBranchName ? parts.slice(4).join('/') : ''),
search: urlObj.search || '',
hash: urlObj.hash || ''
};
};

View File

@@ -569,7 +569,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
ignoreOrientationForPreviousAndNextKey: true
}));
// modify-by-github1s, hide home-bar-icon-badge
// modify-by-github1s, hide home-bar-icon-badge
// const homeBarIconBadge = document.createElement('div');
// homeBarIconBadge.classList.add('home-bar-icon-badge');
// this.homeBarContainer.appendChild(homeBarIconBadge);

View File

@@ -229,23 +229,23 @@ export class TitlebarPart extends Part implements ITitleService {
}
/**
* Possible template values:
*
* {activeEditorLong}: e.g. /Users/Development/myFolder/myFileFolder/myFile.txt
* {activeEditorMedium}: e.g. myFolder/myFileFolder/myFile.txt
* {activeEditorShort}: e.g. myFile.txt
* {activeFolderLong}: e.g. /Users/Development/myFolder/myFileFolder
* {activeFolderMedium}: e.g. myFolder/myFileFolder
* {activeFolderShort}: e.g. myFileFolder
* {rootName}: e.g. myFolder1, myFolder2, myFolder3
* {rootPath}: e.g. /Users/Development
* {folderName}: e.g. myFolder
* {folderPath}: e.g. /Users/Development/myFolder
* {appName}: e.g. VS Code
* {remoteName}: e.g. SSH
* {dirty}: indicator
* {separator}: conditional separator
*/
* Possible template values:
*
* {activeEditorLong}: e.g. /Users/Development/myFolder/myFileFolder/myFile.txt
* {activeEditorMedium}: e.g. myFolder/myFileFolder/myFile.txt
* {activeEditorShort}: e.g. myFile.txt
* {activeFolderLong}: e.g. /Users/Development/myFolder/myFileFolder
* {activeFolderMedium}: e.g. myFolder/myFileFolder
* {activeFolderShort}: e.g. myFileFolder
* {rootName}: e.g. myFolder1, myFolder2, myFolder3
* {rootPath}: e.g. /Users/Development
* {folderName}: e.g. myFolder
* {folderPath}: e.g. /Users/Development/myFolder
* {appName}: e.g. VS Code
* {remoteName}: e.g. SSH
* {dirty}: indicator
* {separator}: conditional separator
*/
private doGetWindowTitle(): string {
const editor = this.editorService.activeEditor;
const workspace = this.contextService.getWorkspace();
@@ -291,7 +291,7 @@ export class TitlebarPart extends Part implements ITitleService {
const remoteName = this.labelService.getHostLabel(Schemas.vscodeRemote, this.environmentService.remoteAuthority);
const separator = this.configurationService.getValue<string>('window.titleSeparator');
const titleTemplate = this.configurationService.getValue<string>('window.title');
const [owner, repo] = (folderName || '').split('+');
const [owner, repo] = (folderName || '').split('+');
return template(titleTemplate, {
activeEditorShort,

View File

@@ -233,7 +233,7 @@ export class ExplorerView extends ViewPane {
const currentFolderUri = workspace.folders?.[0].uri;
const textContent = (currentFolderUri && currentFolderUri.scheme === 'github1s' && currentFolderUri.authority)
? currentFolderUri.authority.split('+').slice(0, 2).join('/')
: this.name;
: this.name;
titleElement.textContent = textContent;
titleElement.title = title;
titleElement.setAttribute('aria-label', nls.localize('explorerSection', "Explorer Section: {0}", this.name));
@@ -583,9 +583,9 @@ export class ExplorerView extends ViewPane {
// General methods
/**
* Refresh the contents of the explorer to get up to date data from the disk about the file structure.
* If the item is passed we refresh only that level of the tree, otherwise we do a full refresh.
*/
* Refresh the contents of the explorer to get up to date data from the disk about the file structure.
* If the item is passed we refresh only that level of the tree, otherwise we do a full refresh.
*/
refresh(recursive: boolean, item?: ExplorerItem, cancelEditing: boolean = true): Promise<void> {
if (!this.tree || !this.isBodyVisible() || (item && !this.tree.hasNode(item))) {
// Tree node doesn't exist yet

View File

@@ -213,9 +213,9 @@ export async function readAuthenticationTrustedDomains(accessor: ServicesAccesso
// modify by vscode
const github1sDefaultTrustedDomains = [
'*.github.com',
'*.microsoft.com',
'*.github1s.com',
'*.github.com',
'*.microsoft.com',
'*.github1s.com',
];
export function readStaticTrustedDomains(accessor: ServicesAccessor): IStaticTrustedDomains {

View File

@@ -18,32 +18,32 @@
}
.monaco-workbench .part.editor > .content .welcomePage .text-warning {
color: #cca700;
color: #cca700;
}
.monaco-workbench .part.editor > .content .welcomePage .text-error {
color: #f48771;
color: #f48771;
}
.monaco-workbench .part.editor > .content .welcomePage .text-success {
color: #89d185
color: #89d185
}
.monaco-workbench .part.editor > .content .welcomePage .refresh-button {
vertical-align: bottom;
cursor: pointer;
vertical-align: bottom;
cursor: pointer;
}
.monaco-workbench .part.editor > .content .welcomePage .refresh-button:hover {
color: #3794ff;
color: #3794ff;
}
.monaco-workbench .part.editor > .content .welcomePage .refresh-button:hover {
color: #3794ff;
color: #3794ff;
}
.monaco-workbench .part.editor > .content .welcomePage .refresh-button:active {
color: #094771;
color: #094771;
}
.monaco-workbench .part.editor > .content .welcomePage .row {

View File

@@ -139,7 +139,7 @@ export class WelcomePageContribution implements IWorkbenchContribution {
private registerListeners() {
this.editorService.onDidActiveEditorChange(() => this.doUpdateWindowUrl());
};
}
}
function isWelcomePageEnabled(configurationService: IConfigurationService, contextService: IWorkspaceContextService) {
@@ -401,10 +401,12 @@ class WelcomePage extends Disposable {
container.querySelector('.create-new-token')?.addEventListener('click', () => window?.open('https://github.com/settings/tokens/new?scopes=repo&description=GitHub1s'));
container.querySelector('.update-oauth-token')?.addEventListener('click', () => this.commandService.executeCommand('github1s.update-token').then(() => this.refreshGitHubTokenStatus(container)));
container.querySelector('.clear-oauth-token')?.addEventListener('click', () => this.commandService.executeCommand('github1s.clear-token').then(() => this.refreshGitHubTokenStatus(container)));
};
}
updateElementText(element: HTMLElement, text: string | number, type?: 'SUCCESS' | 'WARNING' | 'ERROR') {
if (!element) return;
if (!element) {
return;
}
element.innerText = `${text}`;
element.classList.remove('text-warning', 'text-error', 'text-success');
if (type === 'SUCCESS') {
@@ -417,7 +419,7 @@ class WelcomePage extends Disposable {
}
getGitHubTokenStatus() {
return this.commandService.executeCommand('github1s.validate-token', true);
return this.commandService.executeCommand('github1s.validate-token', true);
}
refreshGitHubTokenStatus(container: HTMLElement) {
@@ -445,15 +447,19 @@ class WelcomePage extends Disposable {
}
const textType = (value: number) => {
if (value <= 0) return 'ERROR';
if (value > 99) return 'SUCCESS';
return 'WARNING';
}
if (value <= 0) {
return 'ERROR';
}
if (value > 99) {
return 'SUCCESS';
}
return 'WARNING';
};
this.updateElementText(limitElement, tokenStatus.limit, textType(+tokenStatus.limit));
this.updateElementText(remainingElement, tokenStatus.remaining, textType(+tokenStatus.remaining));
this.updateElementText(resetElement, tokenStatus.reset);
this.updateElementText(timerElement, Math.max(tokenStatus.reset - Math.ceil(Date.now() / 1000), 0));
if (!tokenStatus.token) {
this.updateElementText(statusElement, 'Unauthorized', 'WARNING');
return;

View File

@@ -35,7 +35,7 @@ const colorThemeSettingEnumDescriptions: string[] = [];
const colorThemeSettingSchema: IConfigurationPropertySchema = {
type: 'string',
description: nls.localize('colorTheme', "Specifies the color theme used in the workbench."),
// modify-by-github1s, default dark theme
// modify-by-github1s, default dark theme
default: DEFAULT_THEME_DARK_SETTING_VALUE,
enum: colorThemeSettingEnum,
enumDescriptions: colorThemeSettingEnumDescriptions,

930
yarn.lock

File diff suppressed because it is too large Load Diff