提交 e7871ead 编写于 作者: R Rob Lourens

#55803 - Don't refresh a setting currently being edited

上级 03cfde3d
...@@ -920,7 +920,7 @@ class FocusTracker implements IFocusTracker { ...@@ -920,7 +920,7 @@ class FocusTracker implements IFocusTracker {
private disposables: IDisposable[] = []; private disposables: IDisposable[] = [];
constructor(element: HTMLElement | Window) { constructor(element: HTMLElement | Window) {
let hasFocus = false; let hasFocus = document.activeElement === element;
let loosingFocus = false; let loosingFocus = false;
let onFocus = () => { let onFocus = () => {
......
...@@ -82,6 +82,8 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -82,6 +82,8 @@ export class SettingsEditor2 extends BaseEditor {
private inSettingsEditorContextKey: IContextKey<boolean>; private inSettingsEditorContextKey: IContextKey<boolean>;
private searchFocusContextKey: IContextKey<boolean>; private searchFocusContextKey: IContextKey<boolean>;
private scheduledRefreshTracker: DOM.IFocusTracker;
private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g; private tagRegex = /(^|\s)@tag:("([^"]*)"|[^"]\S*)/g;
/** Don't spam warnings */ /** Don't spam warnings */
...@@ -149,7 +151,7 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -149,7 +151,7 @@ export class SettingsEditor2 extends BaseEditor {
DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600); DOM.toggleClass(this.rootElement, 'narrow', dimension.width < 600);
this.delayRefreshOnLayout.trigger(() => this.refreshTreeAndMaintainFocus()); this.delayRefreshOnLayout.trigger(() => this.refreshTree());
} }
focus(): void { focus(): void {
...@@ -214,7 +216,7 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -214,7 +216,7 @@ export class SettingsEditor2 extends BaseEditor {
this.toolbar.context = <ISettingsToolbarContext>{ target: this.settingsTargetsWidget.settingsTarget }; this.toolbar.context = <ISettingsToolbarContext>{ target: this.settingsTargetsWidget.settingsTarget };
this.settingsTreeModel.update(); this.settingsTreeModel.update();
this.refreshTreeAndMaintainFocus(); this.refreshTree();
}); });
this.createHeaderControls(headerControlsContainer); this.createHeaderControls(headerControlsContainer);
...@@ -354,7 +356,7 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -354,7 +356,7 @@ export class SettingsEditor2 extends BaseEditor {
const element = e.focus; const element = e.focus;
if (this.searchResultModel) { if (this.searchResultModel) {
this.viewState.filterToCategory = element; this.viewState.filterToCategory = element;
this.refreshTreeAndMaintainFocus(); this.refreshTree();
} }
if (element && (!e.payload || !e.payload.fromScroll)) { if (element && (!e.payload || !e.payload.fromScroll)) {
...@@ -464,7 +466,7 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -464,7 +466,7 @@ export class SettingsEditor2 extends BaseEditor {
} }
return this.configurationService.updateValue(key, value, overrides, configurationTarget) return this.configurationService.updateValue(key, value, overrides, configurationTarget)
.then(() => this.refreshTreeAndMaintainFocus()) .then(() => this.refreshTree())
.then(() => { .then(() => {
const reportModifiedProps = { const reportModifiedProps = {
key, key,
...@@ -561,6 +563,19 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -561,6 +563,19 @@ export class SettingsEditor2 extends BaseEditor {
} }
} }
private scheduleRefresh(): void {
if (this.scheduledRefreshTracker) {
return;
}
this.scheduledRefreshTracker = DOM.trackFocus(<HTMLElement>document.activeElement);
this.scheduledRefreshTracker.onDidBlur(() => {
this.scheduledRefreshTracker.dispose();
this.scheduledRefreshTracker = null;
this.refreshTree();
});
}
private onConfigUpdate(): TPromise<void> { private onConfigUpdate(): TPromise<void> {
const groups = this.defaultSettingsEditorModel.settingsGroups.slice(1); // Without commonlyUsed const groups = this.defaultSettingsEditorModel.settingsGroups.slice(1); // Without commonlyUsed
const dividedGroups = collections.groupBy(groups, g => g.contributedByExtension ? 'extension' : 'core'); const dividedGroups = collections.groupBy(groups, g => g.contributedByExtension ? 'extension' : 'core');
...@@ -589,7 +604,7 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -589,7 +604,7 @@ export class SettingsEditor2 extends BaseEditor {
if (this.settingsTreeModel) { if (this.settingsTreeModel) {
this.settingsTreeModel.update(resolvedSettingsRoot); this.settingsTreeModel.update(resolvedSettingsRoot);
return this.refreshTreeAndMaintainFocus(); return this.refreshTree();
} else { } else {
this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState, resolvedSettingsRoot); this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState, resolvedSettingsRoot);
this.settingsTree.setInput(this.settingsTreeModel.root); this.settingsTree.setInput(this.settingsTreeModel.root);
...@@ -605,39 +620,23 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -605,39 +620,23 @@ export class SettingsEditor2 extends BaseEditor {
return TPromise.wrap(null); return TPromise.wrap(null);
} }
private refreshTreeAndMaintainFocus(): TPromise<any> { private refreshTree(element?: SettingsTreeElement): TPromise<any> {
// Sort of a hack to maintain focus on the focused control across a refresh if (this.scheduledRefreshTracker) {
const focusedRowItem = DOM.findParentWithClass(<HTMLElement>document.activeElement, 'setting-item'); return TPromise.wrap(null);
const focusedRowId = focusedRowItem && focusedRowItem.id; }
const selection = focusedRowId && document.activeElement.tagName.toLowerCase() === 'input' ?
(<HTMLInputElement>document.activeElement).selectionStart : if (document.activeElement.classList.contains(SettingsRenderer.CONTROL_CLASS)) {
null; this.scheduleRefresh();
return TPromise.wrap(null);
}
return this.settingsTree.refresh() return this.settingsTree.refresh()
.then(() => { .then(() => {
if (focusedRowId) {
this.focusEditControlForRow(focusedRowId, selection);
}
})
.then(() => {
// TODO@roblou - hack
this.tocTreeModel.update(); this.tocTreeModel.update();
return this.tocTree.refresh(); return this.tocTree.refresh();
}); });
} }
private focusEditControlForRow(id: string, selection?: number): void {
const rowSelector = `.setting-item#${id}`;
const inputElementToFocus: HTMLElement = this.settingsTreeContainer.querySelector(`${rowSelector} input, ${rowSelector} select, ${rowSelector} .monaco-custom-checkbox`);
if (inputElementToFocus) {
inputElementToFocus.focus();
if (typeof selection === 'number') {
(<HTMLInputElement>inputElementToFocus).setSelectionRange(selection, selection);
}
}
}
private onSearchInputChanged(): void { private onSearchInputChanged(): void {
const query = this.searchWidget.getValue().trim(); const query = this.searchWidget.getValue().trim();
this.delayedFilterLogging.cancel(); this.delayedFilterLogging.cancel();
...@@ -788,7 +787,7 @@ export class SettingsEditor2 extends BaseEditor { ...@@ -788,7 +787,7 @@ export class SettingsEditor2 extends BaseEditor {
this.tocTreeModel.update(); this.tocTreeModel.update();
expandAll(this.tocTree); expandAll(this.tocTree);
resolve(this.refreshTreeAndMaintainFocus()); resolve(this.refreshTree());
}); });
}, () => { }, () => {
isCanceled = true; isCanceled = true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册