Merge pull request #153090 from microsoft/3wm

This commit is contained in:
Henning Dieterichs
2022-06-24 14:33:04 +02:00
committed by GitHub
4 changed files with 101 additions and 85 deletions
+96
View File
@@ -1761,3 +1761,99 @@ export function computeClippingRect(elementOrRect: HTMLElement | DOMRectReadOnly
return { top, right, bottom, left };
}
/**
* A helper function to create nested dom nodes.
*
*
* ```ts
* private readonly htmlElements = h('div.code-view', [
* h('div.title', { $: 'title' }),
* h('div.container', [
* h('div.gutter', { $: 'gutterDiv' }),
* h('div', { $: 'editor' }),
* ]),
* ]);
* private readonly editor = createEditor(this.htmlElements.editor);
* ```
*/
export function h<TTag extends string>(tag: TTag): never;
export function h<TTag extends string, TId extends string>(
tag: TTag,
attributes: { $: TId }
): Record<TId | 'root', TagToElement<TTag>>;
export function h<TTag extends string, T extends (HTMLElement | string | Record<string, HTMLElement>)[]>(
tag: TTag,
children: T
): (ArrayToObj<T> & Record<'root', TagToElement<TTag>>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never;
export function h<TTag extends string, TId extends string, T extends (HTMLElement | string | Record<string, HTMLElement>)[]>(
tag: TTag,
attributes: { $: TId },
children: T
): (ArrayToObj<T> & Record<TId, TagToElement<TTag>>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never;
export function h(tag: string, ...args: [] | [attributes: { $: string } | Record<string, any>, children?: any[]] | [children: any[]]): Record<string, HTMLElement> {
let attributes: Record<string, any>;
let children: (Record<string, HTMLElement> | HTMLElement)[] | undefined;
if (Array.isArray(args[0])) {
attributes = {};
children = args[0];
} else {
attributes = args[0] as any || {};
children = args[1];
}
const [tagName, className] = tag.split('.');
const el = document.createElement(tagName);
if (className) {
el.className = className;
}
const result: Record<string, HTMLElement> = {};
if (children) {
for (const c of children) {
if (c instanceof HTMLElement) {
el.appendChild(c);
} else if (typeof c === 'string') {
el.append(c);
} else {
Object.assign(result, c);
el.appendChild(c.root);
}
}
}
for (const [key, value] of Object.entries(attributes)) {
if (key === '$') {
result[value] = el;
continue;
}
el.setAttribute(key, value);
}
result['root'] = el;
return result;
}
type RemoveHTMLElement<T> = T extends HTMLElement ? never : T;
type ArrayToObj<T extends any[]> = UnionToIntersection<RemoveHTMLElement<T[number]>>;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type HTMLElementsByTagName = {
div: HTMLDivElement;
span: HTMLSpanElement;
a: HTMLAnchorElement;
};
type TagToElement<T> = T extends `${infer TStart}.${string}`
? TStart extends keyof HTMLElementsByTagName
? HTMLElementsByTagName[TStart]
: HTMLElement
: T extends keyof HTMLElementsByTagName
? HTMLElementsByTagName[T]
: HTMLElement;
@@ -53,87 +53,6 @@ export class ReentrancyBarrier {
}
}
export function h<TTag extends string>(tag: TTag): never;
export function h<TTag extends string, TId extends string>(
tag: TTag,
attributes: { $: TId }
): Record<TId | 'root', TagToElement<TTag>>;
export function h<TTag extends string, T extends (HTMLElement | string | Record<string, HTMLElement>)[]>(
tag: TTag,
children: T
): (ArrayToObj<T> & Record<'root', TagToElement<TTag>>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never;
export function h<TTag extends string, TId extends string, T extends (HTMLElement | string | Record<string, HTMLElement>)[]>(
tag: TTag,
attributes: { $: TId },
children: T
): (ArrayToObj<T> & Record<TId, TagToElement<TTag>>) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never;
export function h(tag: string, ...args: [] | [attributes: { $: string } | Record<string, any>, children?: any[]] | [children: any[]]): Record<string, HTMLElement> {
let attributes: Record<string, any>;
let children: (Record<string, HTMLElement> | HTMLElement)[] | undefined;
if (Array.isArray(args[0])) {
attributes = {};
children = args[0];
} else {
attributes = args[0] as any || {};
children = args[1];
}
const [tagName, className] = tag.split('.');
const el = document.createElement(tagName);
if (className) {
el.className = className;
}
const result: Record<string, HTMLElement> = {};
if (children) {
for (const c of children) {
if (c instanceof HTMLElement) {
el.appendChild(c);
} else if (typeof c === 'string') {
el.append(c);
} else {
Object.assign(result, c);
el.appendChild(c.root);
}
}
}
for (const [key, value] of Object.entries(attributes)) {
if (key === '$') {
result[value] = el;
continue;
}
el.setAttribute(key, value);
}
result['root'] = el;
return result;
}
type RemoveHTMLElement<T> = T extends HTMLElement ? never : T;
type ArrayToObj<T extends any[]> = UnionToIntersection<RemoveHTMLElement<T[number]>>;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type HTMLElementsByTagName = {
div: HTMLDivElement;
span: HTMLSpanElement;
a: HTMLAnchorElement;
};
type TagToElement<T> = T extends `${infer TStart}.${string}`
? TStart extends keyof HTMLElementsByTagName
? HTMLElementsByTagName[TStart]
: HTMLElement
: T extends keyof HTMLElementsByTagName
? HTMLElementsByTagName[T]
: HTMLElement;
export function setStyle(
element: HTMLElement,
style: {
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { h } from 'vs/base/browser/dom';
import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid';
import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { Emitter, Event } from 'vs/base/common/event';
@@ -12,7 +13,7 @@ import { ITextModel } from 'vs/editor/common/model';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { DEFAULT_EDITOR_MAX_DIMENSIONS, DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor';
import { IObservable, observableFromEvent, ObservableValue } from 'vs/workbench/contrib/audioCues/browser/observable';
import { h, setStyle } from 'vs/workbench/contrib/mergeEditor/browser/utils';
import { setStyle } from 'vs/workbench/contrib/mergeEditor/browser/utils';
import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel';
export interface ICodeEditorViewOptions {
@@ -14,7 +14,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { autorun, derivedObservable, IObservable, ITransaction, ObservableValue, transaction } from 'vs/workbench/contrib/audioCues/browser/observable';
import { InputState, ModifiedBaseRangeState } from 'vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange';
import { applyObservableDecorations, h, setFields } from 'vs/workbench/contrib/mergeEditor/browser/utils';
import { applyObservableDecorations, setFields } from 'vs/workbench/contrib/mergeEditor/browser/utils';
import { handledConflictMinimapOverViewRulerColor, unhandledConflictMinimapOverViewRulerColor } from 'vs/workbench/contrib/mergeEditor/browser/view/colors';
import { EditorGutter, IGutterItemInfo, IGutterItemView } from '../editorGutter';
import { CodeEditorView, ICodeEditorViewOptions } from './codeEditorView';
@@ -270,9 +270,9 @@ export class MergeConflictGutterItemView extends Disposable implements IGutterIt
});
}));
target.appendChild(h('div.background', [noBreakWhitespace]).root);
target.appendChild(dom.h('div.background', [noBreakWhitespace]).root);
target.appendChild(
h('div.checkbox', [h('div.checkbox-background', [checkBox.domNode])]).root
dom.h('div.checkbox', [dom.h('div.checkbox-background', [checkBox.domNode])]).root
);
}