Merge from vscode 718331d6f3ebd1b571530ab499edb266ddd493d5

This commit is contained in:
ADS Merger
2020-02-08 04:50:58 +00:00
parent 8c61538a27
commit 2af13c18d2
752 changed files with 16458 additions and 10063 deletions

View File

@@ -120,6 +120,6 @@ export const isWebKit = (userAgent.indexOf('AppleWebKit') >= 0);
export const isChrome = (userAgent.indexOf('Chrome') >= 0);
export const isSafari = (!isChrome && (userAgent.indexOf('Safari') >= 0));
export const isWebkitWebView = (!isChrome && !isSafari && isWebKit);
export const isIPad = (userAgent.indexOf('iPad') >= 0);
export const isIPad = (userAgent.indexOf('iPad') >= 0 || (isSafari && navigator.maxTouchPoints > 0));
export const isEdgeWebView = isEdge && (userAgent.indexOf('WebView/') >= 0);
export const isStandalone = (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches);

View File

@@ -1313,7 +1313,22 @@ export function asCSSUrl(uri: URI): string {
return `url('${asDomUri(uri).toString(true).replace(/'/g, '%27')}')`;
}
export function triggerDownload(uri: URI, name: string): void {
export function triggerDownload(dataOrUri: Uint8Array | URI, name: string): void {
// If the data is provided as Buffer, we create a
// blog URL out of it to produce a valid link
let url: string;
if (URI.isUri(dataOrUri)) {
url = dataOrUri.toString(true);
} else {
const blob = new Blob([dataOrUri]);
url = URL.createObjectURL(blob);
// Ensure to free the data from DOM eventually
setTimeout(() => URL.revokeObjectURL(url));
}
// In order to download from the browser, the only way seems
// to be creating a <a> element with download attribute that
// points to the file to download.
@@ -1321,7 +1336,7 @@ export function triggerDownload(uri: URI, name: string): void {
const anchor = document.createElement('a');
document.body.appendChild(anchor);
anchor.download = name;
anchor.href = uri.toString(true);
anchor.href = url;
anchor.click();
// Ensure to remove the element from DOM eventually

View File

@@ -28,6 +28,7 @@ export class FastDomNode<T extends HTMLElement> {
private _backgroundColor: string;
private _layerHint: boolean;
private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint';
private _boxShadow: string;
constructor(domNode: T) {
this.domNode = domNode;
@@ -51,6 +52,7 @@ export class FastDomNode<T extends HTMLElement> {
this._backgroundColor = '';
this._layerHint = false;
this._contain = 'none';
this._boxShadow = '';
}
public setMaxWidth(maxWidth: number): void {
@@ -218,6 +220,14 @@ export class FastDomNode<T extends HTMLElement> {
this.domNode.style.transform = this._layerHint ? 'translate3d(0px, 0px, 0px)' : '';
}
public setBoxShadow(boxShadow: string): void {
if (this._boxShadow === boxShadow) {
return;
}
this._boxShadow = boxShadow;
this.domNode.style.boxShadow = boxShadow;
}
public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {
if (this._contain === contain) {
return;

View File

@@ -88,7 +88,7 @@ export class MenuBar extends Disposable {
private numMenusShown: number = 0;
private menuStyle: IMenuStyles | undefined;
private overflowLayoutScheduled: IDisposable | null = null;
private overflowLayoutScheduled: IDisposable | undefined = undefined;
constructor(private container: HTMLElement, private options: IMenuBarOptions = {}) {
super();
@@ -419,9 +419,8 @@ export class MenuBar extends Disposable {
DOM.removeNode(this.overflowMenu.titleElement);
DOM.removeNode(this.overflowMenu.buttonElement);
if (this.overflowLayoutScheduled) {
this.overflowLayoutScheduled = dispose(this.overflowLayoutScheduled);
}
dispose(this.overflowLayoutScheduled);
this.overflowLayoutScheduled = undefined;
}
blur(): void {
@@ -561,7 +560,7 @@ export class MenuBar extends Disposable {
if (!this.overflowLayoutScheduled) {
this.overflowLayoutScheduled = DOM.scheduleAtNextAnimationFrame(() => {
this.updateOverflowAction();
this.overflowLayoutScheduled = null;
this.overflowLayoutScheduled = undefined;
});
}

View File

@@ -287,6 +287,7 @@ export abstract class AbstractScrollableElement extends Widget {
this._options.handleMouseWheel = massagedOptions.handleMouseWheel;
this._options.mouseWheelScrollSensitivity = massagedOptions.mouseWheelScrollSensitivity;
this._options.fastScrollSensitivity = massagedOptions.fastScrollSensitivity;
this._options.scrollPredominantAxis = massagedOptions.scrollPredominantAxis;
this._setListeningToMouseWheel(this._options.handleMouseWheel);
if (!this._options.lazyRender) {
@@ -334,6 +335,14 @@ export abstract class AbstractScrollableElement extends Widget {
let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;
let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;
if (this._options.scrollPredominantAxis) {
if (Math.abs(deltaY) >= Math.abs(deltaX)) {
deltaX = 0;
} else {
deltaY = 0;
}
}
if (this._options.flipAxes) {
[deltaY, deltaX] = [deltaX, deltaY];
}
@@ -553,6 +562,7 @@ function resolveOptions(opts: ScrollableElementCreationOptions): ScrollableEleme
scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),
mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),
fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),
scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),
mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),
arrowSize: (typeof opts.arrowSize !== 'undefined' ? opts.arrowSize : 11),

View File

@@ -55,6 +55,13 @@ export interface ScrollableElementCreationOptions {
* Defaults to 5.
*/
fastScrollSensitivity?: number;
/**
* Whether the scrollable will only scroll along the predominant axis when scrolling both
* vertically and horizontally at the same time.
* Prevents horizontal drift when scrolling vertically on a trackpad.
* Defaults to true.
*/
scrollPredominantAxis?: boolean;
/**
* Height for vertical arrows (top/bottom) and width for horizontal arrows (left/right).
* Defaults to 11.
@@ -113,6 +120,7 @@ export interface ScrollableElementChangeOptions {
handleMouseWheel?: boolean;
mouseWheelScrollSensitivity?: number;
fastScrollSensitivity: number;
scrollPredominantAxis: boolean;
}
export interface ScrollableElementResolvedOptions {
@@ -125,6 +133,7 @@ export interface ScrollableElementResolvedOptions {
alwaysConsumeMouseWheel: boolean;
mouseWheelScrollSensitivity: number;
fastScrollSensitivity: number;
scrollPredominantAxis: boolean;
mouseWheelSmoothScroll: boolean;
arrowSize: number;
listenOnDomNode: HTMLElement | null;

View File

@@ -1585,7 +1585,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
}
open(elements: TRef[], browserEvent?: UIEvent): void {
const indexes = elements.map(e => this.model.getListIndex(e));
const indexes = elements.map(e => this.model.getListIndex(e)).filter(i => i >= 0);
this.view.open(indexes, browserEvent);
}

View File

@@ -562,6 +562,10 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
const node = this.getDataNode(element);
if (this.tree.hasElement(node) && !this.tree.isCollapsible(node)) {
return false;
}
if (node.refreshPromise) {
await this.root.refreshPromise;
await Event.toPromise(this._onDidRender.event);

View File

@@ -205,6 +205,10 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
this.model.setChildren(node, children, _onDidCreateNode, _onDidDeleteNode);
}
has(element: T | null): boolean {
return this.nodes.has(element);
}
getListIndex(location: T | null): number {
const node = this.getCompressedNode(location);
return this.model.getListIndex(node);
@@ -421,6 +425,10 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
this.model.setCompressionEnabled(enabled);
}
has(location: T | null): boolean {
return this.model.has(location);
}
getListIndex(location: T | null): number {
return this.model.getListIndex(location);
}

View File

@@ -199,6 +199,10 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
}
}
has(location: number[]): boolean {
return this.hasTreeNode(location);
}
getListIndex(location: number[]): number {
const { listIndex, visible, revealed } = this.getTreeNodeWithListIndex(location);
return visible && revealed ? listIndex : -1;
@@ -291,6 +295,8 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
if (isCollapsibleStateUpdate(update)) {
result = node.collapsible !== update.collapsible;
node.collapsible = update.collapsible;
} else if (!node.collapsible) {
result = false;
} else {
result = node.collapsed !== update.collapsed;
node.collapsed = update.collapsed;
@@ -516,6 +522,21 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
}
}
// cheap
private hasTreeNode(location: number[], node: IIndexTreeNode<T, TFilterData> = this.root): boolean {
if (!location || location.length === 0) {
return true;
}
const [index, ...rest] = location;
if (index < 0 || index > node.children.length) {
return false;
}
return this.hasTreeNode(rest, node.children[index]);
}
// cheap
private getTreeNode(location: number[], node: IIndexTreeNode<T, TFilterData> = this.root): IIndexTreeNode<T, TFilterData> {
if (!location || location.length === 0) {

View File

@@ -50,6 +50,10 @@ export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends
this.model.resort(element, recursive);
}
hasElement(element: T): boolean {
return this.model.has(element);
}
protected createModel(user: string, view: ISpliceable<ITreeNode<T, TFilterData>>, options: IObjectTreeOptions<T, TFilterData>): ITreeModel<T | null, TFilterData, T | null> {
return new ObjectTreeModel(user, view, options);
}

View File

@@ -195,6 +195,10 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
return this.model.getLastElementAncestor(location);
}
has(element: T | null): boolean {
return this.nodes.has(element);
}
getListIndex(element: T | null): number {
const location = this.getElementLocation(element);
return this.model.getListIndex(location);

View File

@@ -108,6 +108,8 @@ export interface ITreeModel<T, TFilterData, TRef> {
readonly onDidChangeCollapseState: Event<ICollapseStateChangeEvent<T, TFilterData>>;
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
has(location: TRef): boolean;
getListIndex(location: TRef): number;
getListRenderCount(location: TRef): number;
getNode(location?: TRef): ITreeNode<T, any>;