Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreadman committed Sep 15, 2023
2 parents 79729d5 + 9892b66 commit 4a81c23
Show file tree
Hide file tree
Showing 90 changed files with 2,380 additions and 692 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,15 @@ class DiagnosticsTelemetryManager extends Disposable {
this._diagnosticCodesMap.clear();
/* __GDPR__
"typescript.diagnostics" : {
"owner": "@aiday-mar",
"owner": "aiday-mar",
"diagnosticCodes" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"${include}": [
"${TypeScriptCommonProperties}"
]
}
*/
this._telemetryReporter.logTelemetry('typescript.diagnostics', {
diagnoticCodes: diagnosticCodes
diagnosticCodes: diagnosticCodes
});
}
}, 5 * 60 * 1000); // 5 minutes
Expand Down
91 changes: 67 additions & 24 deletions src/vs/base/browser/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@ import { FileAccess, RemoteAuthorities, Schemas } from 'vs/base/common/network';
import * as platform from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';

export const { registerWindow, getWindows, onDidCreateWindow } = (function () {
const windows: Window[] = [];
const onDidCreateWindow = new event.Emitter<{ window: Window; disposableStore: DisposableStore }>();
return {
onDidCreateWindow: onDidCreateWindow.event,
registerWindow(window: Window): IDisposable {
windows.push(window);
const disposableStore = new DisposableStore();
disposableStore.add(toDisposable(() => {
const index = windows.indexOf(window);
if (index !== -1) {
windows.splice(index, 1);
}
}));
onDidCreateWindow.fire({ window, disposableStore });
return disposableStore;
},
getWindows(): Window[] {
return windows;
}
};
})();

export function clearNode(node: HTMLElement): void {
while (node.firstChild) {
node.firstChild.remove();
Expand Down Expand Up @@ -282,34 +305,37 @@ export function addDisposableThrottledListener<R, E extends Event = Event>(node:
}

export function getComputedStyle(el: HTMLElement): CSSStyleDeclaration {
return document.defaultView!.getComputedStyle(el, null);
return el.ownerDocument.defaultView!.getComputedStyle(el, null);
}

export function getClientArea(element: HTMLElement): Dimension {

const elDocument = element.ownerDocument;
const elWindow = elDocument.defaultView?.window;

// Try with DOM clientWidth / clientHeight
if (element !== document.body) {
if (element !== elDocument.body) {
return new Dimension(element.clientWidth, element.clientHeight);
}

// If visual view port exits and it's on mobile, it should be used instead of window innerWidth / innerHeight, or document.body.clientWidth / document.body.clientHeight
if (platform.isIOS && window.visualViewport) {
return new Dimension(window.visualViewport.width, window.visualViewport.height);
if (platform.isIOS && elWindow?.visualViewport) {
return new Dimension(elWindow.visualViewport.width, elWindow.visualViewport.height);
}

// Try innerWidth / innerHeight
if (window.innerWidth && window.innerHeight) {
return new Dimension(window.innerWidth, window.innerHeight);
if (elWindow?.innerWidth && elWindow.innerHeight) {
return new Dimension(elWindow.innerWidth, elWindow.innerHeight);
}

// Try with document.body.clientWidth / document.body.clientHeight
if (document.body && document.body.clientWidth && document.body.clientHeight) {
return new Dimension(document.body.clientWidth, document.body.clientHeight);
if (elDocument.body && elDocument.body.clientWidth && elDocument.body.clientHeight) {
return new Dimension(elDocument.body.clientWidth, elDocument.body.clientHeight);
}

// Try with document.documentElement.clientWidth / document.documentElement.clientHeight
if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) {
return new Dimension(document.documentElement.clientWidth, document.documentElement.clientHeight);
if (elDocument.documentElement && elDocument.documentElement.clientWidth && elDocument.documentElement.clientHeight) {
return new Dimension(elDocument.documentElement.clientWidth, elDocument.documentElement.clientHeight);
}

throw new Error('Unable to figure out browser width and height');
Expand Down Expand Up @@ -431,8 +457,8 @@ export function getTopLeftOffset(element: HTMLElement): IDomPosition {

while (
(element = <HTMLElement>element.parentNode) !== null
&& element !== document.body
&& element !== document.documentElement
&& element !== element.ownerDocument.body
&& element !== element.ownerDocument.documentElement
) {
top -= element.scrollTop;
const c = isShadowRoot(element) ? null : getComputedStyle(element);
Expand Down Expand Up @@ -498,8 +524,8 @@ export function position(element: HTMLElement, top: number, right?: number, bott
export function getDomNodePagePosition(domNode: HTMLElement): IDomNodePagePosition {
const bb = domNode.getBoundingClientRect();
return {
left: bb.left + window.scrollX,
top: bb.top + window.scrollY,
left: bb.left + (domNode.ownerDocument.defaultView?.scrollX ?? 0),
top: bb.top + (domNode.ownerDocument.defaultView?.scrollY ?? 0),
width: bb.width,
height: bb.height
};
Expand All @@ -518,7 +544,7 @@ export function getDomNodeZoomLevel(domNode: HTMLElement): number {
}

testElement = testElement.parentElement;
} while (testElement !== null && testElement !== document.documentElement);
} while (testElement !== null && testElement !== testElement.ownerDocument.documentElement);

return zoom;
}
Expand Down Expand Up @@ -602,7 +628,7 @@ export function setParentFlowTo(fromChildElement: HTMLElement, toParentElement:
function getParentFlowToElement(node: HTMLElement): HTMLElement | null {
const flowToParentId = node.dataset[parentFlowToDataKey];
if (typeof flowToParentId === 'string') {
return document.getElementById(flowToParentId);
return node.ownerDocument.getElementById(flowToParentId);
}
return null;
}
Expand Down Expand Up @@ -671,7 +697,7 @@ export function isInShadowDOM(domNode: Node): boolean {

export function getShadowRoot(domNode: Node): ShadowRoot | null {
while (domNode.parentNode) {
if (domNode === document.body) {
if (domNode === domNode.ownerDocument?.body) {
// reached the body
return null;
}
Expand All @@ -680,8 +706,12 @@ export function getShadowRoot(domNode: Node): ShadowRoot | null {
return isShadowRoot(domNode) ? domNode : null;
}

/**
* Returns the active element across all child windows.
* Use this instead of `document.activeElement` to handle multiple windows.
*/
export function getActiveElement(): Element | null {
let result = document.activeElement;
let result = getActiveDocument().activeElement;

while (result?.shadowRoot) {
result = result.shadowRoot.activeElement;
Expand All @@ -690,6 +720,15 @@ export function getActiveElement(): Element | null {
return result;
}

/**
* Returns the active document across all child windows.
* Use this instead of `document` when reacting to dom events to handle multiple windows.
*/
export function getActiveDocument(): Document {
const documents = [document, ...getWindows().map(w => w.document)];
return documents.find(doc => doc.hasFocus()) ?? document;
}

export function createStyleSheet(container: HTMLElement = document.getElementsByTagName('head')[0], beforeAppend?: (style: HTMLStyleElement) => void): HTMLStyleElement {
const style = document.createElement('style');
style.type = 'text/css';
Expand Down Expand Up @@ -875,15 +914,19 @@ class FocusTracker extends Disposable implements IFocusTracker {

private _refreshStateHandler: () => void;

private static hasFocusWithin(element: HTMLElement): boolean {
const shadowRoot = getShadowRoot(element);
const activeElement = (shadowRoot ? shadowRoot.activeElement : document.activeElement);
return isAncestor(activeElement, element);
private static hasFocusWithin(element: HTMLElement | Window): boolean {
if (isHTMLElement(element)) {
const shadowRoot = getShadowRoot(element);
const activeElement = (shadowRoot ? shadowRoot.activeElement : element.ownerDocument.activeElement);
return isAncestor(activeElement, element);
} else {
return isAncestor(window.document.activeElement, window.document);
}
}

constructor(element: HTMLElement | Window) {
super();
let hasFocus = FocusTracker.hasFocusWithin(<HTMLElement>element);
let hasFocus = FocusTracker.hasFocusWithin(element);
let loosingFocus = false;

const onFocus = () => {
Expand Down Expand Up @@ -1092,7 +1135,7 @@ export function removeTabIndexAndUpdateFocus(node: HTMLElement): void {
// standard DOM behavior is to move focus to the <body> element. We
// typically never want that, rather put focus to the closest element
// in the hierarchy of the parent DOM nodes.
if (document.activeElement === node) {
if (node.ownerDocument.activeElement === node) {
const parentFocusable = findParentWithAttribute(node.parentElement, 'tabIndex');
parentFocusable?.focus();
}
Expand Down
4 changes: 2 additions & 2 deletions src/vs/base/browser/mouseEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ export class StandardMouseEvent implements IMouseEvent {
this.posy = e.pageY;
} else {
// Probably hit by MSGestureEvent
this.posx = e.clientX + document.body.scrollLeft + document.documentElement!.scrollLeft;
this.posy = e.clientY + document.body.scrollTop + document.documentElement!.scrollTop;
this.posx = e.clientX + this.target.ownerDocument.body.scrollLeft + this.target.ownerDocument.documentElement.scrollLeft;
this.posy = e.clientY + this.target.ownerDocument.body.scrollTop + this.target.ownerDocument.documentElement.scrollTop;
}

// Find the position of the iframe this code is executing in relative to the iframe where the event was captured.
Expand Down
31 changes: 25 additions & 6 deletions src/vs/base/common/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,15 @@ export class HistoryNavigator2<T> {
private head: HistoryNode<T>;
private tail: HistoryNode<T>;
private cursor: HistoryNode<T>;
private size: number;
private _size: number;
get size(): number { return this._size; }

constructor(history: readonly T[], private capacity: number = 10) {
if (history.length < 1) {
throw new Error('not supported');
}

this.size = 1;
this._size = 1;
this.head = this.tail = this.cursor = {
value: history[0],
previous: undefined,
Expand All @@ -150,20 +151,20 @@ export class HistoryNavigator2<T> {
this.tail.next = node;
this.tail = node;
this.cursor = this.tail;
this.size++;
this._size++;

if (this.valueSet.has(value)) {
this._deleteFromList(value);
} else {
this.valueSet.add(value);
}

while (this.size > this.capacity) {
while (this._size > this.capacity) {
this.valueSet.delete(this.head.value);

this.head = this.head.next!;
this.head.previous = undefined;
this.size--;
this._size--;
}
}

Expand All @@ -188,6 +189,24 @@ export class HistoryNavigator2<T> {
return oldValue;
}

prepend(value: T): void {
if (this._size === this.capacity || this.valueSet.has(value)) {
return;
}

const node: HistoryNode<T> = {
value,
previous: undefined,
next: this.head
};

this.head.previous = node;
this.head = node;
this._size++;

this.valueSet.add(value);
}

isAtEnd(): boolean {
return this.cursor === this.tail;
}
Expand Down Expand Up @@ -243,7 +262,7 @@ export class HistoryNavigator2<T> {
temp.next!.previous = temp.previous;
}

this.size--;
this._size--;
}

temp = temp.next!;
Expand Down
6 changes: 6 additions & 0 deletions src/vs/base/common/iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export namespace Iterable {
return iterable || _empty;
}

export function* reverse<T>(array: Array<T>): Iterable<T> {
for (let i = array.length - 1; i >= 0; i--) {
yield array[i];
}
}

export function isEmpty<T>(iterable: Iterable<T> | undefined | null): boolean {
return !iterable || iterable[Symbol.iterator]().next().done === true;
}
Expand Down
26 changes: 22 additions & 4 deletions src/vs/base/common/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class ResourceMapEntry<T> {
constructor(readonly uri: URI, readonly value: T) { }
}

function isEntries<T>(arg: ResourceMap<T> | ResourceMapKeyFn | readonly (readonly [URI, T])[] | undefined): arg is readonly (readonly [URI, T])[] {
return Array.isArray(arg);
}

export class ResourceMap<T> implements Map<URI, T> {

private static readonly defaultToKey = (resource: URI) => resource.toString();
Expand All @@ -63,13 +67,27 @@ export class ResourceMap<T> implements Map<URI, T> {
*/
constructor(other?: ResourceMap<T>, toKey?: ResourceMapKeyFn);

constructor(mapOrKeyFn?: ResourceMap<T> | ResourceMapKeyFn, toKey?: ResourceMapKeyFn) {
if (mapOrKeyFn instanceof ResourceMap) {
this.map = new Map(mapOrKeyFn.map);
/**
*
* @param other Another resource which this maps is created from
* @param toKey Custom uri identity function, e.g use an existing `IExtUri#getComparison`-util
*/
constructor(entries?: readonly (readonly [URI, T])[], toKey?: ResourceMapKeyFn);

constructor(arg?: ResourceMap<T> | ResourceMapKeyFn | readonly (readonly [URI, T])[], toKey?: ResourceMapKeyFn) {
if (arg instanceof ResourceMap) {
this.map = new Map(arg.map);
this.toKey = toKey ?? ResourceMap.defaultToKey;
} else if (isEntries(arg)) {
this.map = new Map();
this.toKey = toKey ?? ResourceMap.defaultToKey;

for (const [resource, value] of arg) {
this.set(resource, value);
}
} else {
this.map = new Map();
this.toKey = mapOrKeyFn ?? ResourceMap.defaultToKey;
this.toKey = arg ?? ResourceMap.defaultToKey;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/common/marshallingIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/


export const enum MarshalledId {
Uri = 1,
Regexp,
Expand All @@ -19,6 +18,7 @@ export const enum MarshalledId {
TimelineActionContext,
NotebookCellActionContext,
NotebookActionContext,
TerminalContext,
TestItemContext,
Date,
TestMessageMenuArgs,
Expand Down
Loading

0 comments on commit 4a81c23

Please sign in to comment.