Преглед на файлове

Adds ToC section tracking to settings page

main
Eric Amodio преди 5 години
родител
ревизия
0a39667953
променени са 8 файла, в които са добавени 215 реда и са изтрити 74 реда
  1. +19
    -0
      src/webviews/apps/scss/main.scss
  2. +5
    -0
      src/webviews/apps/scss/popup.scss
  3. +80
    -19
      src/webviews/apps/settings/index.html
  4. +72
    -1
      src/webviews/apps/settings/index.ts
  5. +11
    -9
      src/webviews/apps/shared/appBase.ts
  6. +18
    -31
      src/webviews/apps/shared/appWithConfigBase.ts
  7. +1
    -0
      src/webviews/apps/shared/theme.ts
  8. +9
    -14
      src/webviews/settingsWebview.ts

+ 19
- 0
src/webviews/apps/scss/main.scss Целия файл

@ -1082,6 +1082,25 @@ ul {
text-align: center;
}
.sidebar__jump-link {
&.active {
font-weight: 700;
&:before {
content: ' ';
border-left: 4px solid var(--color-link-foreground--darken-20);
position: absolute;
left: -1em;
height: 1em;
padding-bottom: 4px;
.vscode-light & {
border-left-color: var(--color-link-foreground--lighten-20);
}
}
}
}
.sponsor__image {
opacity: 0.8;
transition: opacity 250ms;

+ 5
- 0
src/webviews/apps/scss/popup.scss Целия файл

@ -97,4 +97,9 @@
&:after {
content: '}';
}
.vscode-light & {
background: var(--color-link-foreground--lighten-20);
border-bottom-color: var(--color-link-foreground--lighten-20);
}
}

+ 80
- 19
src/webviews/apps/settings/index.html Целия файл

@ -118,7 +118,8 @@
<option value="scm">Source Control side bar</option>
</select>
<a
class="link__learn-more jump-to"
class="link__learn-more"
data-action="jump"
title="Jump to Repositories view settings"
href="#repositories-view"
>
@ -138,7 +139,8 @@
<option value="scm">Source Control side bar</option>
</select>
<a
class="link__learn-more jump-to"
class="link__learn-more"
data-action="jump"
title="Jump to File History view settings"
href="#file-history-view"
>
@ -158,7 +160,8 @@
<option value="scm">Source Control side bar</option>
</select>
<a
class="link__learn-more jump-to"
class="link__learn-more"
data-action="jump"
title="Jump to Line History view settings"
href="#line-history-view"
>
@ -178,7 +181,8 @@
<option value="scm">Source Control side bar</option>
</select>
<a
class="link__learn-more jump-to"
class="link__learn-more"
data-action="jump"
title="Jump to Search Commits view settings"
href="#search-commits-view"
>
@ -198,7 +202,8 @@
<option value="scm">Source Control side bar</option>
</select>
<a
class="link__learn-more jump-to"
class="link__learn-more"
data-action="jump"
title="Jump to Compare view settings"
href="#compare-view"
>
@ -3109,41 +3114,82 @@
<div class="sidebar-group">
<h2>Jump to</h2>
<ul>
<li><a class="jump-to" href="#general" title="Jump to General settings">General</a></li>
<li>
<a class="jump-to" href="#current-line" title="Jump to Current Line Blame settings"
<a
class="sidebar__jump-link active"
data-action="jump"
href="#general"
title="Jump to General settings"
>General</a
>
</li>
<li>
<a
class="sidebar__jump-link"
data-action="jump"
href="#current-line"
title="Jump to Current Line Blame settings"
>Current Line Blame</a
>
</li>
<li>
<a class="jump-to" href="#blame" title="Jump to Gutter Blame settings"
<a
class="sidebar__jump-link"
data-action="jump"
href="#blame"
title="Jump to Gutter Blame settings"
>Gutter Blame</a
>
</li>
<li><a class="jump-to" href="#hovers" title="Jump to Hovers settings">Hovers</a></li>
<li>
<a class="jump-to" href="#code-lens" title="Jump to Code Lens settings"
<a
class="sidebar__jump-link"
data-action="jump"
href="#hovers"
title="Jump to Hovers settings"
>Hovers</a
>
</li>
<li>
<a
class="sidebar__jump-link"
data-action="jump"
href="#code-lens"
title="Jump to Code Lens settings"
>Code Lens</a
>
</li>
<li>
<a class="jump-to" href="#heatmap" title="Jump to Gutter Heatmap settings"
<a
class="sidebar__jump-link"
data-action="jump"
href="#heatmap"
title="Jump to Gutter Heatmap settings"
>Gutter Heatmap</a
>
</li>
<li>
<a class="jump-to" href="#recent-changes" title="Jump to Recent Changes settings"
<a
class="sidebar__jump-link"
data-action="jump"
href="#recent-changes"
title="Jump to Recent Changes settings"
>Recent Changes</a
>
</li>
<li>
<a class="jump-to" href="#status-bar" title="Jump to Status Bar Blame settings"
<a
class="sidebar__jump-link"
data-action="jump"
href="#status-bar"
title="Jump to Status Bar Blame settings"
>Status Bar Blame</a
>
</li>
<li>
<a
class="jump-to"
class="sidebar__jump-link"
data-action="jump"
href="#repositories-view"
title="Jump to Repositories view settings"
>Repositories view</a
@ -3151,7 +3197,8 @@
</li>
<li>
<a
class="jump-to"
class="sidebar__jump-link"
data-action="jump"
href="#file-history-view"
title="Jump to File History view settings"
>File History view</a
@ -3159,7 +3206,8 @@
</li>
<li>
<a
class="jump-to"
class="sidebar__jump-link"
data-action="jump"
href="#line-history-view"
title="Jump to Line History view settings"
>Line History view</a
@ -3167,18 +3215,31 @@
</li>
<li>
<a
class="jump-to"
class="sidebar__jump-link"
data-action="jump"
href="#search-commits-view"
title="Jump to Search Commits view settings"
>Search Commits view</a
>
</li>
<li>
<a class="jump-to" href="#compare-view" title="Jump to Compare view settings"
<a
class="sidebar__jump-link"
data-action="jump"
href="#compare-view"
title="Jump to Compare view settings"
>Compare view</a
>
</li>
<li><a class="jump-to" href="#modes" title="Jump to Modes settings">Modes</a></li>
<li>
<a
class="sidebar__jump-link"
data-action="jump"
href="#modes"
title="Jump to Modes settings"
>Modes</a
>
</li>
</ul>
</div>
<div class="sidebar-group">

+ 72
- 1
src/webviews/apps/settings/index.ts Целия файл

@ -1,5 +1,5 @@
'use strict';
/*global window document*/
/*global window document IntersectionObserver*/
import { SettingsBootstrap } from '../../protocol';
import { AppWithConfig } from '../shared/appWithConfigBase';
import { DOM } from '../shared/dom';
@ -8,6 +8,10 @@ const bootstrap: SettingsBootstrap = (window as any).bootstrap;
export class SettingsApp extends AppWithConfig<SettingsBootstrap> {
private _scopes: HTMLSelectElement | null = null;
private _observer: IntersectionObserver | undefined;
private _activeSection: string | undefined = 'general';
private _sections = new Map<string, boolean>();
constructor() {
super('SettingsApp', bootstrap);
@ -30,6 +34,52 @@ export class SettingsApp extends AppWithConfig {
scopes.parentElement!.classList.remove('hidden');
this._scopes = scopes;
}
let top = 83;
const header = document.querySelector('.page-header--sticky');
if (header != null) {
top = header.clientHeight;
}
this._observer = new IntersectionObserver(this.onObserver.bind(this), {
rootMargin: `-${top}px 0px 0px 0px`
});
for (const el of document.querySelectorAll('section[id]>.section__header')) {
this._sections.set(el.parentElement!.id, false);
this._observer.observe(el);
}
}
private onObserver(entries: IntersectionObserverEntry[], observer: IntersectionObserver) {
for (const entry of entries) {
this._sections.set(entry.target.parentElement!.id, entry.isIntersecting);
let nextActive: string | undefined;
for (const [id, visible] of this._sections.entries()) {
if (nextActive === undefined) {
nextActive = this._activeSection === 'modes' ? 'modes' : id;
}
if (!visible) continue;
nextActive = id;
break;
}
if (this._activeSection === nextActive) return;
if (this._activeSection !== undefined) {
this.toggleJumpLink(this._activeSection, false);
}
this._activeSection = nextActive;
if (this._activeSection !== undefined) {
this.toggleJumpLink(this._activeSection, true);
}
}
}
protected onBind(me: this) {
@ -38,6 +88,9 @@ export class SettingsApp extends AppWithConfig {
DOM.listenAll('.section__header', 'click', function(this: HTMLInputElement, e: Event) {
return me.onSectionHeaderClicked(this, e as MouseEvent);
});
DOM.listenAll('a[data-action="jump"]', 'click', function(this: HTMLAnchorElement, e: Event) {
return me.onJumpToLinkClicked(this, e as MouseEvent);
});
DOM.listenAll('[data-action]', 'click', function(this: HTMLAnchorElement, e: Event) {
return me.onActionLinkClicked(this, e as MouseEvent);
});
@ -80,6 +133,17 @@ export class SettingsApp extends AppWithConfig {
super.onInputSelected(element);
}
protected onJumpToLinkClicked(element: HTMLAnchorElement, e: MouseEvent) {
const href = element.getAttribute('href');
if (href == null) return;
const anchor = href.substr(1);
this.scrollToAnchor(anchor);
e.stopPropagation();
e.preventDefault();
}
private onSectionHeaderClicked(element: HTMLElement, e: MouseEvent) {
if (
(e.target as HTMLElement).matches('i.icon__info') ||
@ -90,6 +154,13 @@ export class SettingsApp extends AppWithConfig {
element.classList.toggle('collapsed');
}
private toggleJumpLink(anchor: string, active: boolean) {
const el = document.querySelector(`a.sidebar__jump-link[href="#${anchor}"]`);
if (el) {
el.classList.toggle('active', active);
}
}
}
new SettingsApp();

+ 11
- 9
src/webviews/apps/shared/appBase.ts Целия файл

@ -22,20 +22,22 @@ export abstract class App {
this._api = acquireVsCodeApi();
initializeAndWatchThemeColors();
this.log(`${this.appName}.initializing`);
setTimeout(() => {
this.log(`${this.appName}.initializing`);
this.onInitialize();
this.onBind(this);
this.onInitialize();
this.onBind(this);
window.addEventListener('message', this.onMessageReceived.bind(this));
window.addEventListener('message', this.onMessageReceived.bind(this));
this.sendCommand(ReadyCommandType, {});
this.sendCommand(ReadyCommandType, {});
this.onInitialized();
this.onInitialized();
setTimeout(() => {
document.body.classList.remove('preload');
}, 500);
setTimeout(() => {
document.body.classList.remove('preload');
}, 500);
}, 0);
}
protected onInitialize() {

+ 18
- 31
src/webviews/apps/shared/appWithConfigBase.ts Целия файл

@ -43,9 +43,6 @@ export abstract class AppWithConfig e
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);
});
}
protected onMessageReceived(e: MessageEvent) {
@ -184,16 +181,6 @@ export abstract class AppWithConfig e
this.applyChanges();
}
protected onJumpToLinkClicked(element: HTMLAnchorElement, e: MouseEvent) {
const href = element.getAttribute('href');
if (href == null) return;
this.scrollToAnchor(href.substr(1));
e.stopPropagation();
e.preventDefault();
}
protected onPopupMouseDown(element: HTMLElement, e: MouseEvent) {
// e.stopPropagation();
// e.stopImmediatePropagation();
@ -218,6 +205,24 @@ export abstract class AppWithConfig e
e.preventDefault();
}
protected scrollToAnchor(anchor: string) {
const el = document.getElementById(anchor);
if (el == null) return;
let height = 83;
const header = document.querySelector('.page-header--sticky');
if (header != null) {
height = header.clientHeight;
}
const top = el.getBoundingClientRect().top - document.body.getBoundingClientRect().top - height;
window.scrollTo({
top: top,
behavior: 'smooth'
});
}
private evaluateStateExpression(expression: string, changes: { [key: string]: string | boolean }): boolean {
let state = false;
for (const expr of expression.trim().split('&')) {
@ -261,24 +266,6 @@ export abstract class AppWithConfig e
return get<T>(this.bootstrap.config, path);
}
private scrollToAnchor(anchor: string) {
const el = document.getElementById(anchor);
if (el == null) return;
let height = 83;
const header = document.querySelector('.page-header--sticky');
if (header != null) {
height = header.clientHeight;
}
const top = el.getBoundingClientRect().top - document.body.getBoundingClientRect().top - height;
window.scrollTo({
top: top,
behavior: 'smooth'
});
}
private setState() {
this._updating = true;

+ 1
- 0
src/webviews/apps/shared/theme.ts Целия файл

@ -60,6 +60,7 @@ export function initializeAndWatchThemeColors() {
color = computedStyle.getPropertyValue('--vscode-textLink-foreground').trim();
bodyStyle.setProperty('--color-link-foreground', color);
bodyStyle.setProperty('--color-link-foreground--darken-20', darken(color, 20));
bodyStyle.setProperty('--color-link-foreground--lighten-20', lighten(color, 20));
};
const observer = new MutationObserver(onColorThemeChanged);

+ 9
- 14
src/webviews/settingsWebview.ts Целия файл

@ -29,25 +29,28 @@ export class SettingsWebview extends WebviewBase {
}
getBootstrap(): SettingsBootstrap {
const scopes: ['user' | 'workspace', string][] = [['user', 'User']];
if (workspace.workspaceFolders !== undefined && workspace.workspaceFolders.length) {
scopes.push(['workspace', 'Workspace']);
}
return {
// Make sure to get the raw config, not from the container which has the modes mixed in
config: configuration.get<Config>(),
scope: 'user',
scopes: this.getAvailableScopes()
scopes: scopes
};
}
registerCommands() {
return [
commands.registerCommand(`${this.id}.applyViewLayoutPreset`, args => this.applyViewLayoutPreset(args), this)
];
return [commands.registerCommand(`${this.id}.applyViewLayoutPreset`, this.applyViewLayoutPreset, this)];
}
private applyViewLayoutPreset(args: any) {
private applyViewLayoutPreset(preset: 'contextual' | 'default' | 'scm') {
let repositories;
let histories;
let compareAndSearch;
switch (args) {
switch (preset) {
case 'contextual':
repositories = ViewLocation.SourceControl;
histories = ViewLocation.Explorer;
@ -93,12 +96,4 @@ export class SettingsWebview extends WebviewBase {
ConfigurationTarget.Global
);
}
private getAvailableScopes(): ['user' | 'workspace', string][] {
const scopes: ['user' | 'workspace', string][] = [['user', 'User']];
if (workspace.workspaceFolders !== undefined && workspace.workspaceFolders.length) {
scopes.push(['workspace', 'Workspace']);
}
return scopes;
}
}

Зареждане…
Отказ
Запис