Browse Source

Reworks & reorganizes the webview code

Splits App into AppBase & AppWithConfigBase for impl of new webviews
main
Eric Amodio 5 years ago
parent
commit
1d924e2e24
182 changed files with 6882 additions and 6885 deletions
  1. +0
    -2
      .gitignore
  2. +6
    -4
      .vscodeignore
  3. +6
    -0
      package-lock.json
  4. +3
    -2
      package.json
  5. +1
    -1
      src/annotations/annotations.ts
  6. +1
    -0
      src/commands/common.ts
  7. +10
    -10
      src/container.ts
  8. +0
    -30
      src/ui/ipc.ts
  9. +0
    -4
      src/ui/settings/index.ts
  10. +0
    -39
      src/ui/welcome/app.ts
  11. +0
    -6
      src/ui/welcome/index.ts
  12. +0
    -0
      src/webviews/apps/images/settings/blame-avatars-compact.png
  13. +0
    -0
      src/webviews/apps/images/settings/blame-avatars.png
  14. +0
    -0
      src/webviews/apps/images/settings/blame-compact.png
  15. +0
    -0
      src/webviews/apps/images/settings/blame-heatmap-left.png
  16. +0
    -0
      src/webviews/apps/images/settings/blame-heatmap-right.png
  17. +0
    -0
      src/webviews/apps/images/settings/blame-highlight-gutter.png
  18. +0
    -0
      src/webviews/apps/images/settings/blame-highlight-line.png
  19. +0
    -0
      src/webviews/apps/images/settings/blame-highlight-scrollbar.png
  20. +0
    -0
      src/webviews/apps/images/settings/blame.png
  21. +0
    -0
      src/webviews/apps/images/settings/code-lens-blocks-authors.png
  22. +0
    -0
      src/webviews/apps/images/settings/code-lens-blocks-recent+authors.png
  23. +0
    -0
      src/webviews/apps/images/settings/code-lens-blocks-recent.png
  24. +0
    -0
      src/webviews/apps/images/settings/code-lens-containers-authors.png
  25. +0
    -0
      src/webviews/apps/images/settings/code-lens-containers-recent+authors.png
  26. +0
    -0
      src/webviews/apps/images/settings/code-lens-containers-recent.png
  27. +0
    -0
      src/webviews/apps/images/settings/code-lens-file-authors.png
  28. +0
    -0
      src/webviews/apps/images/settings/code-lens-file-recent+authors.png
  29. +0
    -0
      src/webviews/apps/images/settings/code-lens-file-recent.png
  30. +0
    -0
      src/webviews/apps/images/settings/code-lens.png
  31. +0
    -0
      src/webviews/apps/images/settings/current-line-blame-on-scrollable.png
  32. +0
    -0
      src/webviews/apps/images/settings/current-line-blame-on.png
  33. +0
    -0
      src/webviews/apps/images/settings/current-line-blame.png
  34. +0
    -0
      src/webviews/apps/images/settings/heatmap.png
  35. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-changes.png
  36. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-compact.png
  37. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-details+changes-avatars.png
  38. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-details+changes.png
  39. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-details-avatars.png
  40. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-details.png
  41. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations-heatmap.png
  42. +0
    -0
      src/webviews/apps/images/settings/hovers-annotations.png
  43. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-annotation-changes.png
  44. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-annotation-details+changes-avatars.png
  45. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-annotation-details+changes.png
  46. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-annotation-details-avatars.png
  47. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-annotation-details.png
  48. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-annotation.png
  49. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line-blame.png
  50. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line-changes.png
  51. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line-details+changes-avatars.png
  52. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line-details+changes.png
  53. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line-details-avatars.png
  54. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line-details.png
  55. +0
    -0
      src/webviews/apps/images/settings/hovers-currentLine-line.png
  56. +0
    -0
      src/webviews/apps/images/settings/modes-status-bar-left.png
  57. +0
    -0
      src/webviews/apps/images/settings/modes-status-bar-right.png
  58. +0
    -0
      src/webviews/apps/images/settings/recent-changes-highlight-gutter.png
  59. +0
    -0
      src/webviews/apps/images/settings/recent-changes-highlight-line.png
  60. +0
    -0
      src/webviews/apps/images/settings/recent-changes-highlight-scrollbar.png
  61. +0
    -0
      src/webviews/apps/images/settings/recent-changes.png
  62. +0
    -0
      src/webviews/apps/images/settings/status-bar-left.png
  63. +0
    -0
      src/webviews/apps/images/settings/status-bar-right.png
  64. +0
    -0
      src/webviews/apps/images/settings/status-bar.png
  65. +0
    -0
      src/webviews/apps/images/settings/view-compare-avatars.png
  66. +0
    -0
      src/webviews/apps/images/settings/view-compare-tree-compact.png
  67. +0
    -0
      src/webviews/apps/images/settings/view-compare-tree.png
  68. +0
    -0
      src/webviews/apps/images/settings/view-compare.png
  69. +0
    -0
      src/webviews/apps/images/settings/view-file-history-avatars.png
  70. +0
    -0
      src/webviews/apps/images/settings/view-file-history.png
  71. +0
    -0
      src/webviews/apps/images/settings/view-line-history-avatars.png
  72. +0
    -0
      src/webviews/apps/images/settings/view-line-history.png
  73. +0
    -0
      src/webviews/apps/images/settings/view-repositories-avatars.png
  74. +0
    -0
      src/webviews/apps/images/settings/view-repositories-tree-compact.png
  75. +0
    -0
      src/webviews/apps/images/settings/view-repositories-tree.png
  76. +0
    -0
      src/webviews/apps/images/settings/view-repositories.png
  77. +0
    -0
      src/webviews/apps/images/settings/view-search-avatars.png
  78. +0
    -0
      src/webviews/apps/images/settings/view-search-tree-compact.png
  79. +0
    -0
      src/webviews/apps/images/settings/view-search-tree.png
  80. +0
    -0
      src/webviews/apps/images/settings/view-search.png
  81. +0
    -0
      src/webviews/apps/scss/main.scss
  82. +0
    -0
      src/webviews/apps/scss/popup.scss
  83. +0
    -0
      src/webviews/apps/settings/index.html
  84. +7
    -5
      src/webviews/apps/settings/index.ts
  85. +74
    -0
      src/webviews/apps/shared/appBase.ts
  86. +56
    -162
      src/webviews/apps/shared/appWithConfigBase.ts
  87. +0
    -0
      src/webviews/apps/shared/colors.ts
  88. +0
    -0
      src/webviews/apps/shared/dom.ts
  89. +70
    -0
      src/webviews/apps/shared/theme.ts
  90. +1
    -4
      src/webviews/apps/welcome/index.html
  91. +16
    -0
      src/webviews/apps/welcome/index.ts
  92. +0
    -0
      src/webviews/apps/welcome/snow.ts
  93. +68
    -0
      src/webviews/protocol.ts
  94. +3
    -3
      src/webviews/settingsWebview.ts
  95. +64
    -31
      src/webviews/webviewBase.ts
  96. +3
    -3
      src/webviews/welcomeWebview.ts
  97. +1
    -1
      tsconfig.json
  98. +0
    -89
      tslint.json
  99. +21
    -18
      webpack.config.js
  100. +2
    -2
      webviews.tsconfig.json

+ 0
- 2
.gitignore View File

@ -2,7 +2,5 @@
.cache-loader
dist
node_modules
settings.html
welcome.html
images/settings
gitlens-*.vsix

+ 6
- 4
.vscodeignore View File

@ -2,7 +2,7 @@
.cache-loader/**
.github/**
.vscode/**
dist/ui/**
dist/webviews/main.js
emoji/**
images/docs/**
images/**/*.pdn
@ -10,13 +10,15 @@ node_modules/**
src/**
test/**
*.map
.eslintrc.json
.gitignore
.mailmap
.prettierignore
.prettierrc
CODE_OF_CONDUCT.md
CONTRIBUTING.md
generateEmojiShortcodeMap.js
package-lock.json
tsconfig.json
tslint.json
ui.tsconfig.json
webpack.config.js
webpack.config.js
webviews.tsconfig.json

+ 6
- 0
package-lock.json View File

@ -4964,6 +4964,12 @@
"uglify-js": "3.4.x"
}
},
"html-webpack-exclude-assets-plugin": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/html-webpack-exclude-assets-plugin/-/html-webpack-exclude-assets-plugin-0.0.7.tgz",
"integrity": "sha512-gaYKMGBPDts3Fb1WXyDEEcS/0TSRg2IDl3EsbQL2AkKWTqdjSKwfQ8Iz0RhPiWErJfqhq5/wkhoYyjQoG55pug==",
"dev": true
},
"html-webpack-inline-source-plugin": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/html-webpack-inline-source-plugin/-/html-webpack-inline-source-plugin-0.0.10.tgz",

+ 3
- 2
package.json View File

@ -4978,8 +4978,8 @@
"rebuild": "npm run reset && npm run build",
"reset": "npm run clean && npm install --no-save",
"watch": "webpack --watch --env.development --info-verbosity verbose",
"ui:optimize": "webpack --config-name ui --env.optimizeImages",
"ui:watch": "webpack --watch --config-name ui --env.development --info-verbosity verbose",
"webviews:optimize": "webpack --config-name webviews --env.optimizeImages",
"webviews:watch": "webpack --watch --config-name webviews --env.development --info-verbosity verbose",
"update:emoji": "pushd emoji && node ./shortcodeToEmoji.js && popd",
"postinstall": "node ./node_modules/vscode/bin/install",
"vscode:prepublish": "npm run reset && npm run bundle"
@ -5004,6 +5004,7 @@
"eslint-loader": "2.1.2",
"eslint-plugin-import": "2.16.0",
"eslint-plugin-prettiest": "0.0.1",
"html-webpack-exclude-assets-plugin": "0.0.7",
"html-webpack-inline-source-plugin": "0.0.10",
"html-webpack-plugin": "3.2.0",
"imagemin-webpack-plugin": "2.4.2",

+ 1
- 1
src/annotations/annotations.ts View File

@ -21,7 +21,7 @@ import {
GitUri
} from '../git/gitService';
import { Objects, Strings } from '../system';
import { toRgba } from '../ui/shared/colors';
import { toRgba } from '../webviews/apps/shared/colors';
export interface ComputedHeatmap {
cold: boolean;

+ 1
- 0
src/commands/common.ts View File

@ -78,6 +78,7 @@ export enum Commands {
ShowQuickStashList = 'gitlens.showQuickStashList',
ShowRepositoriesView = 'gitlens.showRepositoriesView',
ShowSearchView = 'gitlens.showSearchView',
ShowHistoryPage = 'gitlens.showHistoryPage',
ShowSettingsPage = 'gitlens.showSettingsPage',
ShowWelcomePage = 'gitlens.showWelcomePage',
StashApply = 'gitlens.stashApply',

+ 10
- 10
src/container.ts View File

@ -21,8 +21,8 @@ import { RepositoriesView } from './views/repositoriesView';
import { SearchView } from './views/searchView';
import { ViewCommands } from './views/viewCommands';
import { VslsController } from './vsls/vsls';
import { SettingsEditor } from './webviews/settingsEditor';
import { WelcomeEditor } from './webviews/welcomeEditor';
import { SettingsWebview } from './webviews/settingsWebview';
import { WelcomeWebview } from './webviews/welcomeWebview';
export class Container {
private static _configsAffectedByMode: string[] | undefined;
@ -49,8 +49,8 @@ export class Container {
context.subscriptions.push((this._statusBarController = new StatusBarController()));
context.subscriptions.push((this._codeLensController = new GitCodeLensController()));
context.subscriptions.push((this._keyboard = new Keyboard()));
context.subscriptions.push((this._settingsEditor = new SettingsEditor()));
context.subscriptions.push((this._welcomeEditor = new WelcomeEditor()));
context.subscriptions.push((this._settingsWebview = new SettingsWebview()));
context.subscriptions.push((this._welcomeWebview = new WelcomeWebview()));
if (config.views.compare.enabled) {
context.subscriptions.push((this._compareView = new CompareView()));
@ -238,9 +238,9 @@ export class Container {
return this._searchView;
}
private static _settingsEditor: SettingsEditor;
static get settingsEditor() {
return this._settingsEditor;
private static _settingsWebview: SettingsWebview;
static get settingsWebview() {
return this._settingsWebview;
}
private static _statusBarController: StatusBarController;
@ -266,9 +266,9 @@ export class Container {
return this._vsls;
}
private static _welcomeEditor: WelcomeEditor;
static get welcomeEditor() {
return this._welcomeEditor;
private static _welcomeWebview: WelcomeWebview;
static get welcomeWebview() {
return this._welcomeWebview;
}
private static applyMode(config: Config) {

+ 0
- 30
src/ui/ipc.ts View File

@ -1,30 +0,0 @@
'use strict';
import { Config } from '../config';
export interface Bootstrap {
config: Config;
}
export interface SettingsBootstrap extends Bootstrap {
scope: 'user' | 'workspace';
scopes: ['user' | 'workspace', string][];
}
export interface WelcomeBootstrap extends Bootstrap {}
export interface SaveSettingsMessage {
type: 'saveSettings';
changes: {
[key: string]: any;
};
removes: string[];
scope: 'user' | 'workspace';
uri?: string;
}
export interface SettingsChangedMessage {
type: 'settingsChanged';
config: Config;
}
export type Message = SaveSettingsMessage | SettingsChangedMessage;

+ 0
- 4
src/ui/settings/index.ts View File

@ -1,4 +0,0 @@
'use strict';
import { SettingsApp } from './app';
new SettingsApp();

+ 0
- 39
src/ui/welcome/app.ts View File

@ -1,39 +0,0 @@
'use strict';
/*global window*/
import { WelcomeBootstrap } from '../ipc';
import { App } from '../shared/app-base';
import { DOM } from '../shared/dom';
const bootstrap: WelcomeBootstrap = (window as any).bootstrap;
export class WelcomeApp extends App<WelcomeBootstrap> {
private _commandRelay: HTMLAnchorElement | null | undefined;
constructor() {
super('WelcomeApp', bootstrap);
}
protected onInitialize() {
this._commandRelay = DOM.getElementById<HTMLAnchorElement>('commandRelay');
}
protected onBind() {
const onClicked = this.onClicked.bind(this);
DOM.listenAll('button[data-href]', 'click', function(this: HTMLButtonElement) {
onClicked(this);
});
}
private onClicked(element: HTMLButtonElement) {
this.executeCommand(element.dataset.href);
}
private executeCommand(command: string | undefined) {
if (command === undefined || this._commandRelay == null) return;
this.log(`${this.appName}.executeCommand: command=${command}`);
this._commandRelay.setAttribute('href', command);
this._commandRelay.click();
}
}

+ 0
- 6
src/ui/welcome/index.ts View File

@ -1,6 +0,0 @@
'use strict';
import { WelcomeApp } from './app';
// import { Snow } from './snow';
new WelcomeApp();
// requestAnimationFrame(() => new Snow());

src/ui/images/settings/blame-avatars-compact.png → src/webviews/apps/images/settings/blame-avatars-compact.png View File


src/ui/images/settings/blame-avatars.png → src/webviews/apps/images/settings/blame-avatars.png View File


src/ui/images/settings/blame-compact.png → src/webviews/apps/images/settings/blame-compact.png View File


src/ui/images/settings/blame-heatmap-left.png → src/webviews/apps/images/settings/blame-heatmap-left.png View File


src/ui/images/settings/blame-heatmap-right.png → src/webviews/apps/images/settings/blame-heatmap-right.png View File


src/ui/images/settings/blame-highlight-gutter.png → src/webviews/apps/images/settings/blame-highlight-gutter.png View File


src/ui/images/settings/blame-highlight-line.png → src/webviews/apps/images/settings/blame-highlight-line.png View File


src/ui/images/settings/blame-highlight-scrollbar.png → src/webviews/apps/images/settings/blame-highlight-scrollbar.png View File


src/ui/images/settings/blame.png → src/webviews/apps/images/settings/blame.png View File


src/ui/images/settings/code-lens-blocks-authors.png → src/webviews/apps/images/settings/code-lens-blocks-authors.png View File


src/ui/images/settings/code-lens-blocks-recent+authors.png → src/webviews/apps/images/settings/code-lens-blocks-recent+authors.png View File


src/ui/images/settings/code-lens-blocks-recent.png → src/webviews/apps/images/settings/code-lens-blocks-recent.png View File


src/ui/images/settings/code-lens-containers-authors.png → src/webviews/apps/images/settings/code-lens-containers-authors.png View File


src/ui/images/settings/code-lens-containers-recent+authors.png → src/webviews/apps/images/settings/code-lens-containers-recent+authors.png View File


src/ui/images/settings/code-lens-containers-recent.png → src/webviews/apps/images/settings/code-lens-containers-recent.png View File


src/ui/images/settings/code-lens-file-authors.png → src/webviews/apps/images/settings/code-lens-file-authors.png View File


src/ui/images/settings/code-lens-file-recent+authors.png → src/webviews/apps/images/settings/code-lens-file-recent+authors.png View File


src/ui/images/settings/code-lens-file-recent.png → src/webviews/apps/images/settings/code-lens-file-recent.png View File


src/ui/images/settings/code-lens.png → src/webviews/apps/images/settings/code-lens.png View File


src/ui/images/settings/current-line-blame-on-scrollable.png → src/webviews/apps/images/settings/current-line-blame-on-scrollable.png View File


src/ui/images/settings/current-line-blame-on.png → src/webviews/apps/images/settings/current-line-blame-on.png View File


src/ui/images/settings/current-line-blame.png → src/webviews/apps/images/settings/current-line-blame.png View File


src/ui/images/settings/heatmap.png → src/webviews/apps/images/settings/heatmap.png View File


src/ui/images/settings/hovers-annotations-changes.png → src/webviews/apps/images/settings/hovers-annotations-changes.png View File


src/ui/images/settings/hovers-annotations-compact.png → src/webviews/apps/images/settings/hovers-annotations-compact.png View File


src/ui/images/settings/hovers-annotations-details+changes-avatars.png → src/webviews/apps/images/settings/hovers-annotations-details+changes-avatars.png View File


src/ui/images/settings/hovers-annotations-details+changes.png → src/webviews/apps/images/settings/hovers-annotations-details+changes.png View File


src/ui/images/settings/hovers-annotations-details-avatars.png → src/webviews/apps/images/settings/hovers-annotations-details-avatars.png View File


src/ui/images/settings/hovers-annotations-details.png → src/webviews/apps/images/settings/hovers-annotations-details.png View File


src/ui/images/settings/hovers-annotations-heatmap.png → src/webviews/apps/images/settings/hovers-annotations-heatmap.png View File


src/ui/images/settings/hovers-annotations.png → src/webviews/apps/images/settings/hovers-annotations.png View File


src/ui/images/settings/hovers-currentLine-annotation-changes.png → src/webviews/apps/images/settings/hovers-currentLine-annotation-changes.png View File


src/ui/images/settings/hovers-currentLine-annotation-details+changes-avatars.png → src/webviews/apps/images/settings/hovers-currentLine-annotation-details+changes-avatars.png View File


src/ui/images/settings/hovers-currentLine-annotation-details+changes.png → src/webviews/apps/images/settings/hovers-currentLine-annotation-details+changes.png View File


src/ui/images/settings/hovers-currentLine-annotation-details-avatars.png → src/webviews/apps/images/settings/hovers-currentLine-annotation-details-avatars.png View File


src/ui/images/settings/hovers-currentLine-annotation-details.png → src/webviews/apps/images/settings/hovers-currentLine-annotation-details.png View File


src/ui/images/settings/hovers-currentLine-annotation.png → src/webviews/apps/images/settings/hovers-currentLine-annotation.png View File


src/ui/images/settings/hovers-currentLine-line-blame.png → src/webviews/apps/images/settings/hovers-currentLine-line-blame.png View File


src/ui/images/settings/hovers-currentLine-line-changes.png → src/webviews/apps/images/settings/hovers-currentLine-line-changes.png View File


src/ui/images/settings/hovers-currentLine-line-details+changes-avatars.png → src/webviews/apps/images/settings/hovers-currentLine-line-details+changes-avatars.png View File


src/ui/images/settings/hovers-currentLine-line-details+changes.png → src/webviews/apps/images/settings/hovers-currentLine-line-details+changes.png View File


src/ui/images/settings/hovers-currentLine-line-details-avatars.png → src/webviews/apps/images/settings/hovers-currentLine-line-details-avatars.png View File


src/ui/images/settings/hovers-currentLine-line-details.png → src/webviews/apps/images/settings/hovers-currentLine-line-details.png View File


src/ui/images/settings/hovers-currentLine-line.png → src/webviews/apps/images/settings/hovers-currentLine-line.png View File


src/ui/images/settings/modes-status-bar-left.png → src/webviews/apps/images/settings/modes-status-bar-left.png View File


src/ui/images/settings/modes-status-bar-right.png → src/webviews/apps/images/settings/modes-status-bar-right.png View File


src/ui/images/settings/recent-changes-highlight-gutter.png → src/webviews/apps/images/settings/recent-changes-highlight-gutter.png View File


src/ui/images/settings/recent-changes-highlight-line.png → src/webviews/apps/images/settings/recent-changes-highlight-line.png View File


src/ui/images/settings/recent-changes-highlight-scrollbar.png → src/webviews/apps/images/settings/recent-changes-highlight-scrollbar.png View File


src/ui/images/settings/recent-changes.png → src/webviews/apps/images/settings/recent-changes.png View File


src/ui/images/settings/status-bar-left.png → src/webviews/apps/images/settings/status-bar-left.png View File


src/ui/images/settings/status-bar-right.png → src/webviews/apps/images/settings/status-bar-right.png View File


src/ui/images/settings/status-bar.png → src/webviews/apps/images/settings/status-bar.png View File


src/ui/images/settings/view-compare-avatars.png → src/webviews/apps/images/settings/view-compare-avatars.png View File


src/ui/images/settings/view-compare-tree-compact.png → src/webviews/apps/images/settings/view-compare-tree-compact.png View File


src/ui/images/settings/view-compare-tree.png → src/webviews/apps/images/settings/view-compare-tree.png View File


src/ui/images/settings/view-compare.png → src/webviews/apps/images/settings/view-compare.png View File


src/ui/images/settings/view-file-history-avatars.png → src/webviews/apps/images/settings/view-file-history-avatars.png View File


src/ui/images/settings/view-file-history.png → src/webviews/apps/images/settings/view-file-history.png View File


src/ui/images/settings/view-line-history-avatars.png → src/webviews/apps/images/settings/view-line-history-avatars.png View File


src/ui/images/settings/view-line-history.png → src/webviews/apps/images/settings/view-line-history.png View File


src/ui/images/settings/view-repositories-avatars.png → src/webviews/apps/images/settings/view-repositories-avatars.png View File


src/ui/images/settings/view-repositories-tree-compact.png → src/webviews/apps/images/settings/view-repositories-tree-compact.png View File


src/ui/images/settings/view-repositories-tree.png → src/webviews/apps/images/settings/view-repositories-tree.png View File


src/ui/images/settings/view-repositories.png → src/webviews/apps/images/settings/view-repositories.png View File


src/ui/images/settings/view-search-avatars.png → src/webviews/apps/images/settings/view-search-avatars.png View File


src/ui/images/settings/view-search-tree-compact.png → src/webviews/apps/images/settings/view-search-tree-compact.png View File


src/ui/images/settings/view-search-tree.png → src/webviews/apps/images/settings/view-search-tree.png View File


src/ui/images/settings/view-search.png → src/webviews/apps/images/settings/view-search.png View File


src/ui/scss/main.scss → src/webviews/apps/scss/main.scss View File


src/ui/scss/popup.scss → src/webviews/apps/scss/popup.scss View File


src/ui/settings/index.html → src/webviews/apps/settings/index.html View File


src/ui/settings/app.ts → src/webviews/apps/settings/index.ts View File

@ -1,12 +1,12 @@
'use strict';
/*global window document*/
import { SettingsBootstrap } from '../ipc';
import { App } from '../shared/app-base';
import { SettingsBootstrap } from '../../protocol';
import { AppWithConfig } from '../shared/appWithConfigBase';
import { DOM } from '../shared/dom';
const bootstrap: SettingsBootstrap = (window as any).bootstrap;
export class SettingsApp extends App<SettingsBootstrap> {
export class SettingsApp extends AppWithConfig<SettingsBootstrap> {
private _scopes: HTMLSelectElement | null = null;
constructor() {
@ -32,8 +32,8 @@ export class SettingsApp extends App {
}
}
protected onBind() {
const me = this;
protected onBind(me: this) {
super.onBind(me);
DOM.listenAll('.section__header', 'click', function(this: HTMLInputElement, e: Event) {
return me.onSectionHeaderClicked(this, e as MouseEvent);
@ -91,3 +91,5 @@ export class SettingsApp extends App {
element.classList.toggle('collapsed');
}
}
new SettingsApp();

+ 74
- 0
src/webviews/apps/shared/appBase.ts View File

@ -0,0 +1,74 @@
'use strict';
/*global window document*/
import { AppBootstrap, IpcCommandParamsOf, IpcCommandType, IpcMessage } from '../../protocol';
import { initializeAndWatchThemeColors } from './theme';
interface VsCodeApi {
postMessage(msg: {}): void;
setState(state: {}): void;
getState(): {};
}
declare function acquireVsCodeApi(): VsCodeApi;
let ipcSequence = 0;
export abstract class App<TBootstrap extends AppBootstrap> {
private readonly _api: VsCodeApi;
constructor(protected readonly appName: string, protected readonly bootstrap: TBootstrap) {
this.log(`${this.appName}.ctor`);
this._api = acquireVsCodeApi();
initializeAndWatchThemeColors();
this.log(`${this.appName}.initializing`);
this.onInitialize();
this.onBind(this);
window.addEventListener('message', this.onMessageReceived.bind(this));
this.onInitialized();
setTimeout(() => {
document.body.classList.remove('preload');
}, 500);
}
protected onInitialize() {
// virtual
}
protected onInitialized() {
// virtual
}
protected onBind(me: this) {
// virtual
}
protected onMessageReceived(e: MessageEvent) {
// virtual
}
protected log(message: string) {
console.log(message);
}
protected sendCommand<CT extends IpcCommandType>(type: CT, params: IpcCommandParamsOf<CT>): void {
return this.postMessage({ id: this.nextIpcId(), method: type.method, params: params });
}
private nextIpcId() {
if (ipcSequence === Number.MAX_SAFE_INTEGER) {
ipcSequence = 1;
}
else {
ipcSequence++;
}
return `webview:${ipcSequence}`;
}
private postMessage(e: IpcMessage) {
this._api.postMessage(e);
}
}

src/ui/shared/app-base.ts → src/webviews/apps/shared/appWithConfigBase.ts View File

@ -1,44 +1,72 @@
'use strict';
/*global window document MutationObserver*/
import { darken, lighten, opacity } from '../shared/colors';
import { Bootstrap, Message, SaveSettingsMessage } from '../ipc';
import { DOM } from '../shared/dom';
interface VsCodeApi {
postMessage(msg: {}): void;
setState(state: {}): void;
getState(): {};
}
declare function acquireVsCodeApi(): VsCodeApi;
export abstract class App<TBootstrap extends Bootstrap> {
private readonly _api: VsCodeApi;
/*global window document*/
import {
AppWithConfigBootstrap,
DidChangeConfigurationNotificationType,
IpcMessage,
onIpcNotification,
UpdateConfigurationCommandType
} from '../../protocol';
import { DOM } from './dom';
import { App } from './appBase';
export abstract class AppWithConfig<TBootstrap extends AppWithConfigBootstrap> extends App<TBootstrap> {
private _changes: { [key: string]: any } = Object.create(null);
private _updating: boolean = false;
constructor(protected readonly appName: string, protected readonly bootstrap: TBootstrap) {
this.log(`${this.appName}.ctor`);
constructor(appName: string, bootstrap: TBootstrap) {
super(appName, bootstrap);
}
protected onInitialized() {
this.setState();
}
protected onBind(me: this) {
DOM.listenAll('input[type=checkbox].setting', 'change', function(this: HTMLInputElement) {
return me.onInputChecked(this);
});
DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'blur', function(this: HTMLInputElement) {
return me.onInputBlurred(this);
});
DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'focus', function(this: HTMLInputElement) {
return me.onInputFocused(this);
});
DOM.listenAll('select.setting', 'change', function(this: HTMLSelectElement) {
return me.onInputSelected(this);
});
DOM.listenAll('[data-token]', 'mousedown', function(this: HTMLElement, e: Event) {
return me.onTokenMouseDown(this, e as MouseEvent);
});
DOM.listenAll('.popup', 'mousedown', function(this: HTMLElement, e: Event) {
return me.onPopupMouseDown(this, e as MouseEvent);
});
DOM.listenAll('a.jump-to[href^="#"]', 'click', function(this: HTMLAnchorElement, e: Event) {
return me.onJumpToLinkClicked(this, e as MouseEvent);
});
}
this._api = acquireVsCodeApi();
protected onMessageReceived(e: MessageEvent) {
const msg = e.data as IpcMessage;
this.initializeColorPalette();
this.initialize();
this.bind();
switch (msg.method) {
case DidChangeConfigurationNotificationType.method:
onIpcNotification(DidChangeConfigurationNotificationType, msg, params => {
this.bootstrap.config = params.config;
setTimeout(() => {
document.body.classList.remove('preload');
}, 500);
this.setState();
});
break;
}
}
protected applyChanges() {
const msg: SaveSettingsMessage = {
type: 'saveSettings',
this.sendCommand(UpdateConfigurationCommandType, {
changes: { ...this._changes },
removes: Object.keys(this._changes).filter(k => this._changes[k] === undefined),
scope: this.getSettingsScope()
};
this.postMessage(msg);
});
this._changes = Object.create(null);
}
@ -47,17 +75,6 @@ export abstract class App {
return 'user';
}
protected log(message: string) {
console.log(message);
}
protected onBind() {
// virtual
}
protected onInitialize() {
// virtual
}
protected onInputBlurred(element: HTMLInputElement) {
this.log(`${this.appName}.onInputBlurred: name=${element.name}, value=${element.value}`);
@ -184,17 +201,6 @@ export abstract class App {
e.preventDefault();
}
protected onMessageReceived(e: MessageEvent) {
const msg = e.data as Message;
switch (msg.type) {
case 'settingsChanged':
this.bootstrap.config = msg.config;
this.setState();
break;
}
}
protected onPopupMouseDown(element: HTMLElement, e: MouseEvent) {
// e.stopPropagation();
// e.stopImmediatePropagation();
@ -219,40 +225,6 @@ export abstract class App {
e.preventDefault();
}
protected postMessage(e: Message) {
this._api.postMessage(e);
}
private bind() {
this.onBind();
window.addEventListener('message', this.onMessageReceived.bind(this));
const me = this;
DOM.listenAll('input[type=checkbox].setting', 'change', function(this: HTMLInputElement) {
return me.onInputChecked(this);
});
DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'blur', function(this: HTMLInputElement) {
return me.onInputBlurred(this);
});
DOM.listenAll('input[type=text].setting, input:not([type]).setting', 'focus', function(this: HTMLInputElement) {
return me.onInputFocused(this);
});
DOM.listenAll('select.setting', 'change', function(this: HTMLSelectElement) {
return me.onInputSelected(this);
});
DOM.listenAll('[data-token]', 'mousedown', function(this: HTMLElement, e: Event) {
return me.onTokenMouseDown(this, e as MouseEvent);
});
DOM.listenAll('.popup', 'mousedown', function(this: HTMLElement, e: Event) {
return me.onPopupMouseDown(this, e as MouseEvent);
});
DOM.listenAll('a.jump-to[href^="#"]', 'click', function(this: HTMLAnchorElement, e: Event) {
return me.onJumpToLinkClicked(this, e as MouseEvent);
});
}
private evaluateStateExpression(expression: string, changes: { [key: string]: string | boolean }): boolean {
let state = false;
for (const expr of expression.trim().split('&')) {
@ -296,84 +268,6 @@ export abstract class App {
return get<T>(this.bootstrap.config, path);
}
private initialize() {
this.log(`${this.appName}.initialize`);
this.onInitialize();
this.setState();
}
private initializeColorPalette() {
const onColorThemeChanged = () => {
const body = document.body;
const computedStyle = window.getComputedStyle(body);
const bodyStyle = body.style;
const font = computedStyle.getPropertyValue('--vscode-font-family').trim();
if (font) {
bodyStyle.setProperty('--font-family', font);
bodyStyle.setProperty('--font-size', computedStyle.getPropertyValue('--vscode-font-size').trim());
bodyStyle.setProperty('--font-weight', computedStyle.getPropertyValue('--vscode-font-weight').trim());
}
else {
bodyStyle.setProperty(
'--font-family',
computedStyle.getPropertyValue('--vscode-editor-font-family').trim()
);
bodyStyle.setProperty(
'--font-size',
computedStyle.getPropertyValue('--vscode-editor-font-size').trim()
);
bodyStyle.setProperty(
'--font-weight',
computedStyle.getPropertyValue('--vscode-editor-font-weight').trim()
);
}
let color = computedStyle.getPropertyValue('--vscode-editor-background').trim();
bodyStyle.setProperty('--color-background', color);
bodyStyle.setProperty('--color-background--lighten-05', lighten(color, 5));
bodyStyle.setProperty('--color-background--darken-05', darken(color, 5));
bodyStyle.setProperty('--color-background--lighten-075', lighten(color, 7.5));
bodyStyle.setProperty('--color-background--darken-075', darken(color, 7.5));
bodyStyle.setProperty('--color-background--lighten-15', lighten(color, 15));
bodyStyle.setProperty('--color-background--darken-15', darken(color, 15));
bodyStyle.setProperty('--color-background--lighten-30', lighten(color, 30));
bodyStyle.setProperty('--color-background--darken-30', darken(color, 30));
color = computedStyle.getPropertyValue('--vscode-button-background').trim();
bodyStyle.setProperty('--color-button-background', color);
bodyStyle.setProperty('--color-button-background--darken-30', darken(color, 30));
color = computedStyle.getPropertyValue('--vscode-button-foreground').trim();
bodyStyle.setProperty('--color-button-foreground', color);
color = computedStyle.getPropertyValue('--vscode-editor-foreground').trim();
if (!color) {
color = computedStyle.getPropertyValue('--vscode-foreground').trim();
}
bodyStyle.setProperty('--color-foreground', color);
bodyStyle.setProperty('--color-foreground--85', opacity(color, 85));
bodyStyle.setProperty('--color-foreground--75', opacity(color, 75));
bodyStyle.setProperty('--color-foreground--50', opacity(color, 50));
color = computedStyle.getPropertyValue('--vscode-focusBorder').trim();
bodyStyle.setProperty('--color-focus-border', color);
color = computedStyle.getPropertyValue('--vscode-textLink-foreground').trim();
bodyStyle.setProperty('--color-link-foreground', color);
bodyStyle.setProperty('--color-link-foreground--darken-20', darken(color, 20));
};
const observer = new MutationObserver(onColorThemeChanged);
observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
onColorThemeChanged();
return observer;
}
private setState() {
this._updating = true;

src/ui/shared/colors.ts → src/webviews/apps/shared/colors.ts View File


src/ui/shared/dom.ts → src/webviews/apps/shared/dom.ts View File


+ 70
- 0
src/webviews/apps/shared/theme.ts View File

@ -0,0 +1,70 @@
'use strict';
/*global window document MutationObserver*/
import { darken, lighten, opacity } from './colors';
export function initializeAndWatchThemeColors() {
const onColorThemeChanged = () => {
const body = document.body;
const computedStyle = window.getComputedStyle(body);
const bodyStyle = body.style;
const font = computedStyle.getPropertyValue('--vscode-font-family').trim();
if (font) {
bodyStyle.setProperty('--font-family', font);
bodyStyle.setProperty('--font-size', computedStyle.getPropertyValue('--vscode-font-size').trim());
bodyStyle.setProperty('--font-weight', computedStyle.getPropertyValue('--vscode-font-weight').trim());
}
else {
bodyStyle.setProperty(
'--font-family',
computedStyle.getPropertyValue('--vscode-editor-font-family').trim()
);
bodyStyle.setProperty('--font-size', computedStyle.getPropertyValue('--vscode-editor-font-size').trim());
bodyStyle.setProperty(
'--font-weight',
computedStyle.getPropertyValue('--vscode-editor-font-weight').trim()
);
}
let color = computedStyle.getPropertyValue('--vscode-editor-background').trim();
bodyStyle.setProperty('--color-background', color);
bodyStyle.setProperty('--color-background--lighten-05', lighten(color, 5));
bodyStyle.setProperty('--color-background--darken-05', darken(color, 5));
bodyStyle.setProperty('--color-background--lighten-075', lighten(color, 7.5));
bodyStyle.setProperty('--color-background--darken-075', darken(color, 7.5));
bodyStyle.setProperty('--color-background--lighten-15', lighten(color, 15));
bodyStyle.setProperty('--color-background--darken-15', darken(color, 15));
bodyStyle.setProperty('--color-background--lighten-30', lighten(color, 30));
bodyStyle.setProperty('--color-background--darken-30', darken(color, 30));
color = computedStyle.getPropertyValue('--vscode-button-background').trim();
bodyStyle.setProperty('--color-button-background', color);
bodyStyle.setProperty('--color-button-background--darken-30', darken(color, 30));
color = computedStyle.getPropertyValue('--vscode-button-foreground').trim();
bodyStyle.setProperty('--color-button-foreground', color);
color = computedStyle.getPropertyValue('--vscode-editor-foreground').trim();
if (!color) {
color = computedStyle.getPropertyValue('--vscode-foreground').trim();
}
bodyStyle.setProperty('--color-foreground', color);
bodyStyle.setProperty('--color-foreground--85', opacity(color, 85));
bodyStyle.setProperty('--color-foreground--75', opacity(color, 75));
bodyStyle.setProperty('--color-foreground--50', opacity(color, 50));
color = computedStyle.getPropertyValue('--vscode-focusBorder').trim();
bodyStyle.setProperty('--color-focus-border', color);
color = computedStyle.getPropertyValue('--vscode-textLink-foreground').trim();
bodyStyle.setProperty('--color-link-foreground', color);
bodyStyle.setProperty('--color-link-foreground--darken-20', darken(color, 20));
};
const observer = new MutationObserver(onColorThemeChanged);
observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
onColorThemeChanged();
return observer;
}

src/ui/welcome/index.html → src/webviews/apps/welcome/index.html View File

@ -1132,9 +1132,7 @@
>
</li>
<li>
<a
title="Star me on GitHub"
href="https://github.com/eamodio/vscode-gitlens"
<a title="Star me on GitHub" href="https://github.com/eamodio/vscode-gitlens"
>Star me on GitHub</a
>
</li>
@ -1194,7 +1192,6 @@
</div>
</div>
</div>
<a id="commandRelay" style="display: none"></a>
<script type="text/javascript">
window.bootstrap = '{{bootstrap}}';
</script>

+ 16
- 0
src/webviews/apps/welcome/index.ts View File

@ -0,0 +1,16 @@
'use strict';
/*global window*/
import { WelcomeBootstrap } from '../../protocol';
// import { Snow } from './snow';
import { AppWithConfig } from '../shared/appWithConfigBase';
const bootstrap: WelcomeBootstrap = (window as any).bootstrap;
export class WelcomeApp extends AppWithConfig<WelcomeBootstrap> {
constructor() {
super('WelcomeApp', bootstrap);
}
}
new WelcomeApp();
// requestAnimationFrame(() => new Snow());

src/ui/welcome/snow.ts → src/webviews/apps/welcome/snow.ts View File


+ 68
- 0
src/webviews/protocol.ts View File

@ -0,0 +1,68 @@
'use strict';
import { Config } from '../config';
export interface IpcMessage {
id: string;
method: string;
params?: any;
}
export type IpcNotificationParamsOf<NT> = NT extends IpcNotificationType<infer P> ? P : never;
export class IpcNotificationType<P = any> {
constructor(public readonly method: string) {}
}
export type IpcCommandParamsOf<CT> = CT extends IpcCommandType<infer P> ? P : never;
export class IpcCommandType<P = any> {
constructor(public readonly method: string) {}
}
export function onIpcCommand<CT extends IpcCommandType>(
type: CT,
command: IpcMessage,
fn: (params: IpcCommandParamsOf<CT>) => void
) {
fn(command.params);
}
export function onIpcNotification<NT extends IpcNotificationType>(
type: NT,
notification: IpcMessage,
fn: (params: IpcNotificationParamsOf<NT>) => void
) {
fn(notification.params);
}
export interface DidChangeConfigurationNotificationParams {
config: Config;
}
export const DidChangeConfigurationNotificationType = new IpcNotificationType<DidChangeConfigurationNotificationParams>(
'configuration/didChange'
);
export interface UpdateConfigurationCommandParams {
changes: {
[key: string]: any;
};
removes: string[];
scope: 'user' | 'workspace';
uri?: string;
}
export const UpdateConfigurationCommandType = new IpcCommandType<UpdateConfigurationCommandParams>(
'configuration/update'
);
export interface AppBootstrap {}
export interface AppWithConfigBootstrap {
config: Config;
}
export interface SettingsBootstrap extends AppWithConfigBootstrap {
scope: 'user' | 'workspace';
scopes: ['user' | 'workspace', string][];
}
export interface WelcomeBootstrap extends AppWithConfigBootstrap {}
export interface HistoryBootstrap {}

src/webviews/settingsEditor.ts → src/webviews/settingsWebview.ts View File

@ -2,10 +2,10 @@
import { commands, workspace } from 'vscode';
import { Commands } from '../commands';
import { Config, configuration } from '../configuration';
import { SettingsBootstrap } from '../ui/ipc';
import { WebviewEditor } from './webviewEditor';
import { SettingsBootstrap } from './protocol';
import { WebviewBase } from './webviewBase';
export class SettingsEditor extends WebviewEditor<SettingsBootstrap> {
export class SettingsWebview extends WebviewBase<SettingsBootstrap> {
constructor() {
super();
}

src/webviews/webviewEditor.ts → src/webviews/webviewBase.ts View File

@ -1,4 +1,5 @@
'use strict';
import * as paths from 'path';
import * as fs from 'fs';
import {
ConfigurationChangeEvent,
@ -14,9 +15,18 @@ import {
import { Config, configuration } from '../configuration';
import { Container } from '../container';
import { Logger } from '../logger';
import { Message, SettingsChangedMessage } from '../ui/ipc';
import {
DidChangeConfigurationNotificationType,
IpcMessage,
IpcNotificationParamsOf,
IpcNotificationType,
onIpcCommand,
UpdateConfigurationCommandType
} from './protocol';
let ipcSequence = 0;
export abstract class WebviewEditor<TBootstrap> implements Disposable {
export abstract class WebviewBase<TBootstrap> implements Disposable {
private _disposable: Disposable | undefined;
private _disposablePanel: Disposable | undefined;
private _panel: WebviewPanel | undefined;
@ -41,7 +51,7 @@ export abstract class WebviewEditor implements Disposable {
}
private onConfigurationChanged(e: ConfigurationChangeEvent) {
this.postUpdatedConfiguration();
this.notifyDidChangeConfiguration();
}
private onPanelDisposed() {
@ -51,38 +61,48 @@ export abstract class WebviewEditor implements Disposable {
private onViewStateChanged(e: WebviewPanelOnDidChangeViewStateEvent) {
Logger.log(
'WebviewEditor.onViewStateChanged',
`Webview(${this.id}).onViewStateChanged`,
`active=${e.webviewPanel.active}, visible=${e.webviewPanel.visible}`
);
// Anytime the webview becomes active, make sure it has the most up-to-date config
if (e.webviewPanel.active) {
this.postUpdatedConfiguration();
this.notifyDidChangeConfiguration();
}
}
protected async onMessageReceived(e: Message) {
protected onMessageReceived(e: IpcMessage) {
// virtual
}
private onMessageReceivedCore(e: IpcMessage) {
if (e == null) return;
Logger.log(`WebviewEditor.onMessageReceived: type=${e.type}, data=${JSON.stringify(e)}`);
Logger.log(`Webview(${this.id}).onMessageReceived: method=${e.method}, data=${JSON.stringify(e)}`);
switch (e.type) {
case 'saveSettings': {
const target = e.scope === 'workspace' ? ConfigurationTarget.Workspace : ConfigurationTarget.Global;
switch (e.method) {
case UpdateConfigurationCommandType.method:
onIpcCommand(UpdateConfigurationCommandType, e, async params => {
const target =
params.scope === 'workspace' ? ConfigurationTarget.Workspace : ConfigurationTarget.Global;
for (const key in e.changes) {
const inspect = await configuration.inspect(key)!;
for (const key in params.changes) {
const inspect = await configuration.inspect(key)!;
const value = e.changes[key];
await configuration.update(key, value === inspect.defaultValue ? undefined : value, target);
}
const value = params.changes[key];
await configuration.update(key, value === inspect.defaultValue ? undefined : value, target);
}
for (const key of e.removes) {
await configuration.update(key, undefined, target);
}
for (const key of params.removes) {
await configuration.update(key, undefined, target);
}
});
break;
default:
this.onMessageReceived(e);
break;
}
}
}
@ -117,7 +137,7 @@ export abstract class WebviewEditor implements Disposable {
this._panel,
this._panel.onDidDispose(this.onPanelDisposed, this),
this._panel.onDidChangeViewState(this.onViewStateChanged, this),
this._panel.webview.onDidReceiveMessage(this.onMessageReceived, this)
this._panel.webview.onDidReceiveMessage(this.onMessageReceivedCore, this)
);
this._panel.webview.html = html;
@ -132,11 +152,13 @@ export abstract class WebviewEditor implements Disposable {
private _html: string | undefined;
private async getHtml(): Promise<string> {
const filename = Container.context.asAbsolutePath(paths.join('dist/webviews/', this.filename));
let content;
// When we are debugging avoid any caching so that we can change the html and have it update without reloading
if (Logger.isDebugging) {
content = await new Promise<string>((resolve, reject) => {
fs.readFile(Container.context.asAbsolutePath(this.filename), 'utf8', (err, data) => {
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
reject(err);
}
@ -149,7 +171,7 @@ export abstract class WebviewEditor implements Disposable {
else {
if (this._html !== undefined) return this._html;
const doc = await workspace.openTextDocument(Container.context.asAbsolutePath(this.filename));
const doc = await workspace.openTextDocument(filename);
content = doc.getText();
}
@ -167,18 +189,29 @@ export abstract class WebviewEditor implements Disposable {
return this._html;
}
private postMessage(message: Message) {
if (this._panel === undefined) return false;
protected notify<NT extends IpcNotificationType>(type: NT, params: IpcNotificationParamsOf<NT>): Thenable<boolean> {
return this.postMessage({ id: this.nextIpcId(), method: type.method, params: params });
}
private nextIpcId() {
if (ipcSequence === Number.MAX_SAFE_INTEGER) {
ipcSequence = 1;
}
else {
ipcSequence++;
}
return this._panel!.webview.postMessage(message);
return `host:${ipcSequence}`;
}
private postUpdatedConfiguration() {
private notifyDidChangeConfiguration() {
// Make sure to get the raw config, not from the container which has the modes mixed in
const msg: SettingsChangedMessage = {
type: 'settingsChanged',
config: configuration.get<Config>()
};
return this.postMessage(msg);
return this.notify(DidChangeConfigurationNotificationType, { config: configuration.get<Config>() });
}
private postMessage(message: IpcMessage) {
if (this._panel === undefined) return Promise.resolve(false);
return this._panel.webview.postMessage(message);
}
}

src/webviews/welcomeEditor.ts → src/webviews/welcomeWebview.ts View File

@ -2,10 +2,10 @@
import { commands } from 'vscode';
import { Commands } from '../commands';
import { Container } from '../container';
import { WelcomeBootstrap } from '../ui/ipc';
import { WebviewEditor } from './webviewEditor';
import { WelcomeBootstrap } from './protocol';
import { WebviewBase } from './webviewBase';
export class WelcomeEditor extends WebviewEditor<WelcomeBootstrap> {
export class WelcomeWebview extends WebviewBase<WelcomeBootstrap> {
constructor() {
super();
}

+ 1
- 1
tsconfig.json View File

@ -15,5 +15,5 @@
"strict": true,
"target": "es2018"
},
"exclude": ["node_modules", "test", "src/ui"]
"exclude": ["node_modules", "test", "src/webviews/apps"]
}

+ 0
- 89
tslint.json View File

@ -1,89 +0,0 @@
{
"extends": ["tslint-prettiest"],
"rules": {
"adjacent-overload-signatures": true,
"array-type": [true, "array"],
"arrow-parens": [true, "ban-single-arg-parens"],
"arrow-return-shorthand": true,
"class-name": true,
"comment-format": [true, "check-space"],
"curly": [true, "ignore-same-line"],
"eofline": true,
"interface-over-type-literal": true,
"linebreak-style": [true, "LF"],
"new-parens": true,
"no-angle-bracket-type-assertion": true,
"no-consecutive-blank-lines": [true, 1],
"no-default-export": true,
"no-duplicate-variable": true,
"no-eval": true,
"no-floating-promises": true,
"no-inferrable-types": [true, "ignore-params", "ignore-properties"],
"no-internal-module": true,
"no-irregular-whitespace": true,
"no-reference": true,
"no-string-throw": true,
"no-trailing-whitespace": true,
"no-unnecessary-callback-wrapper": true,
"no-unsafe-finally": true,
"no-unused-expression": false,
"no-var-keyword": true,
"no-var-requires": false,
"object-literal-key-quotes": [true, "as-needed"],
"one-line": [true, "check-open-brace", "check-whitespace"],
"one-variable-per-declaration": [true, "ignore-for-loop"],
"ordered-imports": [
true,
{
"import-sources-order": "case-insensitive",
"named-imports-order": "case-insensitive"
}
],
"prefer-const": true,
"prefer-for-of": true,
"prefer-method-signature": true,
"prefer-template": [true, "allow-single-concat"],
"prettiest": [true, "spaces", 4],
"quotemark": [true, "single", "avoid-escape"],
"radix": true,
"semicolon": [true, "always"],
"space-before-function-paren": [
true,
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
],
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [true, "allow-null-check"],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"use-isnan": true,
"variable-name": [true, "allow-leading-underscore", "allow-pascal-case", "ban-keywords", "check-format"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type"
]
},
"defaultSeverity": "warning"
}

+ 21
- 18
webpack.config.js View File

@ -6,6 +6,7 @@ const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CleanPlugin = require('clean-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const HtmlExcludeAssetsPlugin = require('html-webpack-exclude-assets-plugin');
const HtmlInlineSourcePlugin = require('html-webpack-inline-source-plugin');
const HtmlPlugin = require('html-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
@ -122,9 +123,9 @@ function getExtensionConfig(env) {
}
function getUIConfig(env) {
const clean = ['settings.html', 'welcome.html'];
const clean = [];
if (env.optimizeImages) {
console.log('Optimizing images (src/ui/images/settings/*.png)...');
console.log('Optimizing images (src/webviews/apps/images/settings/*.png)...');
clean.push('images/settings');
}
@ -134,11 +135,12 @@ function getUIConfig(env) {
filename: '[name].css'
}),
new HtmlPlugin({
excludeAssets: [/main\.js/],
excludeChunks: ['welcome'],
template: 'settings/index.html',
filename: path.resolve(__dirname, 'settings.html'),
filename: path.resolve(__dirname, 'dist/webviews/settings.html'),
inject: true,
inlineSource: env.production ? '.(js|css)$' : undefined,
// inlineSource: env.production ? '.(js|css)$' : undefined,
minify: env.production
? {
removeComments: true,
@ -153,11 +155,12 @@ function getUIConfig(env) {
: false
}),
new HtmlPlugin({
excludeAssets: [/main\.js/],
excludeChunks: ['settings'],
template: 'welcome/index.html',
filename: path.resolve(__dirname, 'welcome.html'),
filename: path.resolve(__dirname, 'dist/webviews/welcome.html'),
inject: true,
inlineSource: env.production ? '.(js|css)$' : undefined,
// inlineSource: env.production ? '.(js|css)$' : undefined,
minify: env.production
? {
removeComments: true,
@ -171,12 +174,13 @@ function getUIConfig(env) {
}
: false
}),
new HtmlExcludeAssetsPlugin(),
new HtmlInlineSourcePlugin(),
new ImageminPlugin({
disable: !env.optimizeImages,
externalImages: {
context: path.resolve(__dirname, 'src/ui/images'),
sources: glob.sync('src/ui/images/settings/*.png'),
context: path.resolve(__dirname, 'src/webviews/apps/images'),
sources: glob.sync('src/webviews/apps/images/settings/*.png'),
destination: path.resolve(__dirname, 'images')
},
cacheFolder: path.resolve(__dirname, '.cache-images'),
@ -192,20 +196,19 @@ function getUIConfig(env) {
];
return {
name: 'ui',
context: path.resolve(__dirname, 'src/ui'),
// This is ugly having main.scss on both bundles, but if it is added separately it will generate a js bundle :(
name: 'webviews',
context: path.resolve(__dirname, 'src/webviews/apps'),
entry: {
settings: ['./settings/index.ts', './scss/main.scss'],
welcome: ['./welcome/index.ts', './scss/main.scss']
// main: ['./scss/main.scss']
main: ['./scss/main.scss'],
settings: ['./settings/index.ts'],
welcome: ['./welcome/index.ts']
},
mode: env.production ? 'production' : 'development',
devtool: env.production ? undefined : 'eval-source-map',
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist/ui'),
publicPath: '{{root}}/dist/ui/'
path: path.resolve(__dirname, 'dist/webviews'),
publicPath: '{{root}}/dist/webviews/'
},
module: {
rules: [
@ -228,7 +231,7 @@ function getUIConfig(env) {
use: {
loader: 'ts-loader',
options: {
configFile: 'ui.tsconfig.json'
configFile: 'webviews.tsconfig.json'
}
},
exclude: /node_modules|\.d\.ts$/
@ -259,7 +262,7 @@ function getUIConfig(env) {
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
modules: [path.resolve(__dirname, 'src/ui'), 'node_modules']
modules: [path.resolve(__dirname, 'src/webviews/apps'), 'node_modules']
},
plugins: plugins,
stats: {

ui.tsconfig.json → webviews.tsconfig.json View File

@ -8,13 +8,13 @@
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": false,
"outDir": "dist/ui",
"outDir": "dist/webviews",
"rootDir": "src",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "es2018"
},
"include": ["src/config.ts", "src/ui/**/*"],
"include": ["src/config.ts", "src/webviews/protocol.ts", "src/webviews/apps/**/*"],
"exclude": ["node_modules"]
}

Loading…
Cancel
Save