awa
This commit is contained in:
55
_internal/editor/esm/vs/base/browser/browser.js
Normal file
55
_internal/editor/esm/vs/base/browser/browser.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { mainWindow } from './window.js';
|
||||
class WindowManager {
|
||||
constructor() {
|
||||
// --- Zoom Factor
|
||||
this.mapWindowIdToZoomFactor = new Map();
|
||||
}
|
||||
static { this.INSTANCE = new WindowManager(); }
|
||||
getZoomFactor(targetWindow) {
|
||||
return this.mapWindowIdToZoomFactor.get(this.getWindowId(targetWindow)) ?? 1;
|
||||
}
|
||||
getWindowId(targetWindow) {
|
||||
return targetWindow.vscodeWindowId;
|
||||
}
|
||||
}
|
||||
export function addMatchMediaChangeListener(targetWindow, query, callback) {
|
||||
if (typeof query === 'string') {
|
||||
query = targetWindow.matchMedia(query);
|
||||
}
|
||||
query.addEventListener('change', callback);
|
||||
}
|
||||
/** The zoom scale for an index, e.g. 1, 1.2, 1.4 */
|
||||
export function getZoomFactor(targetWindow) {
|
||||
return WindowManager.INSTANCE.getZoomFactor(targetWindow);
|
||||
}
|
||||
const userAgent = navigator.userAgent;
|
||||
export const isFirefox = (userAgent.indexOf('Firefox') >= 0);
|
||||
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 isElectron = (userAgent.indexOf('Electron/') >= 0);
|
||||
export const isAndroid = (userAgent.indexOf('Android') >= 0);
|
||||
let standalone = false;
|
||||
if (typeof mainWindow.matchMedia === 'function') {
|
||||
const standaloneMatchMedia = mainWindow.matchMedia('(display-mode: standalone) or (display-mode: window-controls-overlay)');
|
||||
const fullScreenMatchMedia = mainWindow.matchMedia('(display-mode: fullscreen)');
|
||||
standalone = standaloneMatchMedia.matches;
|
||||
addMatchMediaChangeListener(mainWindow, standaloneMatchMedia, ({ matches }) => {
|
||||
// entering fullscreen would change standaloneMatchMedia.matches to false
|
||||
// if standalone is true (running as PWA) and entering fullscreen, skip this change
|
||||
if (standalone && fullScreenMatchMedia.matches) {
|
||||
return;
|
||||
}
|
||||
// otherwise update standalone (browser to PWA or PWA to browser)
|
||||
standalone = matches;
|
||||
});
|
||||
}
|
||||
export function isStandalone() {
|
||||
return standalone;
|
||||
}
|
||||
//# sourceMappingURL=browser.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/browser.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/browser.js.map
Normal file
File diff suppressed because one or more lines are too long
33
_internal/editor/esm/vs/base/browser/canIUse.js
Normal file
33
_internal/editor/esm/vs/base/browser/canIUse.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as browser from './browser.js';
|
||||
import { mainWindow } from './window.js';
|
||||
import * as platform from '../common/platform.js';
|
||||
/**
|
||||
* Browser feature we can support in current platform, browser and environment.
|
||||
*/
|
||||
export const BrowserFeatures = {
|
||||
clipboard: {
|
||||
writeText: (platform.isNative
|
||||
|| (document.queryCommandSupported && document.queryCommandSupported('copy'))
|
||||
|| !!(navigator && navigator.clipboard && navigator.clipboard.writeText)),
|
||||
readText: (platform.isNative
|
||||
|| !!(navigator && navigator.clipboard && navigator.clipboard.readText))
|
||||
},
|
||||
keyboard: (() => {
|
||||
if (platform.isNative || browser.isStandalone()) {
|
||||
return 0 /* KeyboardSupport.Always */;
|
||||
}
|
||||
if (navigator.keyboard || browser.isSafari) {
|
||||
return 1 /* KeyboardSupport.FullScreen */;
|
||||
}
|
||||
return 2 /* KeyboardSupport.None */;
|
||||
})(),
|
||||
// 'ontouchstart' in window always evaluates to true with typescript's modern typings. This causes `window` to be
|
||||
// `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast
|
||||
touch: 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0,
|
||||
pointerEvents: mainWindow.PointerEvent && ('ontouchstart' in mainWindow || navigator.maxTouchPoints > 0)
|
||||
};
|
||||
//# sourceMappingURL=canIUse.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/canIUse.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/canIUse.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/canIUse.ts","vs/base/browser/canIUse.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAC;AAQlD;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,SAAS,EAAE;QACV,SAAS,EAAE,CACV,QAAQ,CAAC,QAAQ;eACd,CAAC,QAAQ,CAAC,qBAAqB,IAAI,QAAQ,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;eAC1E,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CACxE;QACD,QAAQ,EAAE,CACT,QAAQ,CAAC,QAAQ;eACd,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CACvE;KACD;IACD,QAAQ,EAAE,CAAC,GAAG,EAAE;QACf,IAAI,QAAQ,CAAC,QAAQ,IAAI,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;YACjD,sCAA8B;QAC/B,CAAC;QAED,IAAU,SAAU,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnD,0CAAkC;QACnC,CAAC;QAED,oCAA4B;IAC7B,CAAC,CAAC,EAAE;IAEJ,iHAAiH;IACjH,+FAA+F;IAC/F,KAAK,EAAE,cAAc,IAAI,UAAU,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC;IACnE,aAAa,EAAE,UAAU,CAAC,YAAY,IAAI,CAAC,cAAc,IAAI,UAAU,IAAI,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC;CACxG,CAAC","file":"canIUse.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as browser from './browser.js';\nimport { mainWindow } from './window.js';\nimport * as platform from '../common/platform.js';\n\nexport const enum KeyboardSupport {\n\tAlways,\n\tFullScreen,\n\tNone\n}\n\n/**\n * Browser feature we can support in current platform, browser and environment.\n */\nexport const BrowserFeatures = {\n\tclipboard: {\n\t\twriteText: (\n\t\t\tplatform.isNative\n\t\t\t|| (document.queryCommandSupported && document.queryCommandSupported('copy'))\n\t\t\t|| !!(navigator && navigator.clipboard && navigator.clipboard.writeText)\n\t\t),\n\t\treadText: (\n\t\t\tplatform.isNative\n\t\t\t|| !!(navigator && navigator.clipboard && navigator.clipboard.readText)\n\t\t)\n\t},\n\tkeyboard: (() => {\n\t\tif (platform.isNative || browser.isStandalone()) {\n\t\t\treturn KeyboardSupport.Always;\n\t\t}\n\n\t\tif ((<any>navigator).keyboard || browser.isSafari) {\n\t\t\treturn KeyboardSupport.FullScreen;\n\t\t}\n\n\t\treturn KeyboardSupport.None;\n\t})(),\n\n\t// 'ontouchstart' in window always evaluates to true with typescript's modern typings. This causes `window` to be\n\t// `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast\n\ttouch: 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0,\n\tpointerEvents: mainWindow.PointerEvent && ('ontouchstart' in mainWindow || navigator.maxTouchPoints > 0)\n};\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport * as browser from './browser.js';\nimport { mainWindow } from './window.js';\nimport * as platform from '../common/platform.js';\n\nexport const enum KeyboardSupport {\n\tAlways,\n\tFullScreen,\n\tNone\n}\n\n/**\n * Browser feature we can support in current platform, browser and environment.\n */\nexport const BrowserFeatures = {\n\tclipboard: {\n\t\twriteText: (\n\t\t\tplatform.isNative\n\t\t\t|| (document.queryCommandSupported && document.queryCommandSupported('copy'))\n\t\t\t|| !!(navigator && navigator.clipboard && navigator.clipboard.writeText)\n\t\t),\n\t\treadText: (\n\t\t\tplatform.isNative\n\t\t\t|| !!(navigator && navigator.clipboard && navigator.clipboard.readText)\n\t\t)\n\t},\n\tkeyboard: (() => {\n\t\tif (platform.isNative || browser.isStandalone()) {\n\t\t\treturn KeyboardSupport.Always;\n\t\t}\n\n\t\tif ((<any>navigator).keyboard || browser.isSafari) {\n\t\t\treturn KeyboardSupport.FullScreen;\n\t\t}\n\n\t\treturn KeyboardSupport.None;\n\t})(),\n\n\t// 'ontouchstart' in window always evaluates to true with typescript's modern typings. This causes `window` to be\n\t// `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast\n\ttouch: 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0,\n\tpointerEvents: mainWindow.PointerEvent && ('ontouchstart' in mainWindow || navigator.maxTouchPoints > 0)\n};\n"]}
|
||||
6
_internal/editor/esm/vs/base/browser/contextmenu.js
Normal file
6
_internal/editor/esm/vs/base/browser/contextmenu.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export {};
|
||||
//# sourceMappingURL=contextmenu.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/contextmenu.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/contextmenu.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/contextmenu.ts","vs/base/browser/contextmenu.ts"],"names":[],"mappings":"AAAA;;;gGAGgG","file":"contextmenu.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { StandardMouseEvent } from './mouseEvent.js';\nimport { IActionViewItemOptions } from './ui/actionbar/actionViewItems.js';\nimport { IActionViewItem } from './ui/actionbar/actionbar.js';\nimport { AnchorAlignment, AnchorAxisAlignment, IAnchor } from './ui/contextview/contextview.js';\nimport { IAction, IActionRunner } from '../common/actions.js';\nimport { ResolvedKeybinding } from '../common/keybindings.js';\nimport { OmitOptional } from '../common/types.js';\n\nexport interface IContextMenuEvent {\n}\n\n/**\n * A specific context menu location to position the menu at.\n * Uses some TypeScript type tricks to prevent allowing to\n * pass in a `MouseEvent` and force people to use `StandardMouseEvent`.\n */\ntype ContextMenuLocation = OmitOptional<IAnchor> & { getModifierState?: never };\n\nexport interface IContextMenuDelegate {\n\t/**\n\t * The anchor where to position the context view.\n\t * Use a `HTMLElement` to position the view at the element,\n\t * a `StandardMouseEvent` to position it at the mouse position\n\t * or an `ContextMenuLocation` to position it at a specific location.\n\t */\n\tgetAnchor(): HTMLElement | StandardMouseEvent | ContextMenuLocation;\n\tgetActions(): readonly IAction[];\n\tgetActionViewItem?(action: IAction, options: IActionViewItemOptions): IActionViewItem | undefined;\n\tgetActionsContext?(event?: IContextMenuEvent): unknown;\n\tgetKeyBinding?(action: IAction): ResolvedKeybinding | undefined;\n\tgetMenuClassName?(): string;\n\tonHide?(didCancel: boolean): void;\n\tactionRunner?: IActionRunner;\n\tskipTelemetry?: boolean;\n\tautoSelectFirstItem?: boolean;\n\tanchorAlignment?: AnchorAlignment;\n\tanchorAxisAlignment?: AnchorAxisAlignment;\n\tdomForShadowRoot?: HTMLElement;\n\t/**\n\t * custom context menus with higher layers are rendered higher in z-index order\n\t */\n\tlayer?: number;\n}\n\nexport interface IContextMenuProvider {\n\tshowContextMenu(delegate: IContextMenuDelegate): void;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { StandardMouseEvent } from './mouseEvent.js';\nimport { IActionViewItemOptions } from './ui/actionbar/actionViewItems.js';\nimport { IActionViewItem } from './ui/actionbar/actionbar.js';\nimport { AnchorAlignment, AnchorAxisAlignment, IAnchor } from './ui/contextview/contextview.js';\nimport { IAction, IActionRunner } from '../common/actions.js';\nimport { ResolvedKeybinding } from '../common/keybindings.js';\nimport { OmitOptional } from '../common/types.js';\n\nexport interface IContextMenuEvent {\n}\n\n/**\n * A specific context menu location to position the menu at.\n * Uses some TypeScript type tricks to prevent allowing to\n * pass in a `MouseEvent` and force people to use `StandardMouseEvent`.\n */\ntype ContextMenuLocation = OmitOptional<IAnchor> & { getModifierState?: never };\n\nexport interface IContextMenuDelegate {\n\t/**\n\t * The anchor where to position the context view.\n\t * Use a `HTMLElement` to position the view at the element,\n\t * a `StandardMouseEvent` to position it at the mouse position\n\t * or an `ContextMenuLocation` to position it at a specific location.\n\t */\n\tgetAnchor(): HTMLElement | StandardMouseEvent | ContextMenuLocation;\n\tgetActions(): readonly IAction[];\n\tgetActionViewItem?(action: IAction, options: IActionViewItemOptions): IActionViewItem | undefined;\n\tgetActionsContext?(event?: IContextMenuEvent): unknown;\n\tgetKeyBinding?(action: IAction): ResolvedKeybinding | undefined;\n\tgetMenuClassName?(): string;\n\tonHide?(didCancel: boolean): void;\n\tactionRunner?: IActionRunner;\n\tskipTelemetry?: boolean;\n\tautoSelectFirstItem?: boolean;\n\tanchorAlignment?: AnchorAlignment;\n\tanchorAxisAlignment?: AnchorAxisAlignment;\n\tdomForShadowRoot?: HTMLElement;\n\t/**\n\t * custom context menus with higher layers are rendered higher in z-index order\n\t */\n\tlayer?: number;\n}\n\nexport interface IContextMenuProvider {\n\tshowContextMenu(delegate: IContextMenuDelegate): void;\n}\n"]}
|
||||
67
_internal/editor/esm/vs/base/browser/cssValue.js
Normal file
67
_internal/editor/esm/vs/base/browser/cssValue.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { FileAccess } from '../common/network.js';
|
||||
function asFragment(raw) {
|
||||
return raw;
|
||||
}
|
||||
export function asCssValueWithDefault(cssPropertyValue, dflt) {
|
||||
if (cssPropertyValue !== undefined) {
|
||||
const variableMatch = cssPropertyValue.match(/^\s*var\((.+)\)$/);
|
||||
if (variableMatch) {
|
||||
const varArguments = variableMatch[1].split(',', 2);
|
||||
if (varArguments.length === 2) {
|
||||
dflt = asCssValueWithDefault(varArguments[1].trim(), dflt);
|
||||
}
|
||||
return `var(${varArguments[0]}, ${dflt})`;
|
||||
}
|
||||
return cssPropertyValue;
|
||||
}
|
||||
return dflt;
|
||||
}
|
||||
export function identValue(value) {
|
||||
const out = value.replaceAll(/[^_\-a-z0-9]/gi, '');
|
||||
if (out !== value) {
|
||||
console.warn(`CSS ident value ${value} modified to ${out} to be safe for CSS`);
|
||||
}
|
||||
return asFragment(out);
|
||||
}
|
||||
export function stringValue(value) {
|
||||
return asFragment(`'${value.replaceAll(/'/g, '\\000027')}'`);
|
||||
}
|
||||
/**
|
||||
* returns url('...')
|
||||
*/
|
||||
export function asCSSUrl(uri) {
|
||||
if (!uri) {
|
||||
return asFragment(`url('')`);
|
||||
}
|
||||
return inline `url('${asFragment(CSS.escape(FileAccess.uriToBrowserUri(uri).toString(true)))}')`;
|
||||
}
|
||||
export function className(value, escapingExpected = false) {
|
||||
const out = CSS.escape(value);
|
||||
if (!escapingExpected && out !== value) {
|
||||
console.warn(`CSS class name ${value} modified to ${out} to be safe for CSS`);
|
||||
}
|
||||
return asFragment(out);
|
||||
}
|
||||
/**
|
||||
* Template string tag that that constructs a CSS fragment.
|
||||
*
|
||||
* All expressions in the template must be css safe values.
|
||||
*/
|
||||
export function inline(strings, ...values) {
|
||||
return asFragment(strings.reduce((result, str, i) => {
|
||||
const value = values[i] || '';
|
||||
return result + str + value;
|
||||
}, ''));
|
||||
}
|
||||
export class Builder {
|
||||
constructor() {
|
||||
this._parts = [];
|
||||
}
|
||||
push(...parts) {
|
||||
this._parts.push(...parts);
|
||||
}
|
||||
join(joiner = '\n') {
|
||||
return asFragment(this._parts.join(joiner));
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=cssValue.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/cssValue.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/cssValue.js.map
Normal file
File diff suppressed because one or more lines are too long
27
_internal/editor/esm/vs/base/browser/dnd.js
Normal file
27
_internal/editor/esm/vs/base/browser/dnd.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Mimes } from '../common/mime.js';
|
||||
// Common data transfers
|
||||
export const DataTransfers = {
|
||||
/**
|
||||
* Application specific resource transfer type
|
||||
*/
|
||||
RESOURCES: 'ResourceURLs',
|
||||
/**
|
||||
* Browser specific transfer type to download
|
||||
*/
|
||||
DOWNLOAD_URL: 'DownloadURL',
|
||||
/**
|
||||
* Browser specific transfer type for files
|
||||
*/
|
||||
FILES: 'Files',
|
||||
/**
|
||||
* Typically transfer type for copy/paste transfers.
|
||||
*/
|
||||
TEXT: Mimes.text,
|
||||
/**
|
||||
* Internal type used to pass around text/uri-list data.
|
||||
*
|
||||
* This is needed to work around https://bugs.chromium.org/p/chromium/issues/detail?id=239745.
|
||||
*/
|
||||
INTERNAL_URI_LIST: 'application/vnd.code.uri-list',
|
||||
};
|
||||
//# sourceMappingURL=dnd.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/dnd.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/dnd.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/dnd.ts","vs/base/browser/dnd.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,wBAAwB;AACxB,MAAM,CAAC,MAAM,aAAa,GAAG;IAE5B;;OAEG;IACH,SAAS,EAAE,cAAc;IAEzB;;OAEG;IACH,YAAY,EAAE,aAAa;IAE3B;;OAEG;IACH,KAAK,EAAE,OAAO;IAEd;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC,IAAI;IAEhB;;;;OAIG;IACH,iBAAiB,EAAE,+BAA+B;CAClD,CAAC","file":"dnd.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["\nimport { Mimes } from '../common/mime.js';\n\n// Common data transfers\nexport const DataTransfers = {\n\n\t/**\n\t * Application specific resource transfer type\n\t */\n\tRESOURCES: 'ResourceURLs',\n\n\t/**\n\t * Browser specific transfer type to download\n\t */\n\tDOWNLOAD_URL: 'DownloadURL',\n\n\t/**\n\t * Browser specific transfer type for files\n\t */\n\tFILES: 'Files',\n\n\t/**\n\t * Typically transfer type for copy/paste transfers.\n\t */\n\tTEXT: Mimes.text,\n\n\t/**\n\t * Internal type used to pass around text/uri-list data.\n\t *\n\t * This is needed to work around https://bugs.chromium.org/p/chromium/issues/detail?id=239745.\n\t */\n\tINTERNAL_URI_LIST: 'application/vnd.code.uri-list',\n};\n\nexport interface IDragAndDropData {\n\tupdate(dataTransfer: DataTransfer): void;\n\tgetData(): unknown;\n}\n","\nimport { Mimes } from '../common/mime.js';\n\n// Common data transfers\nexport const DataTransfers = {\n\n\t/**\n\t * Application specific resource transfer type\n\t */\n\tRESOURCES: 'ResourceURLs',\n\n\t/**\n\t * Browser specific transfer type to download\n\t */\n\tDOWNLOAD_URL: 'DownloadURL',\n\n\t/**\n\t * Browser specific transfer type for files\n\t */\n\tFILES: 'Files',\n\n\t/**\n\t * Typically transfer type for copy/paste transfers.\n\t */\n\tTEXT: Mimes.text,\n\n\t/**\n\t * Internal type used to pass around text/uri-list data.\n\t *\n\t * This is needed to work around https://bugs.chromium.org/p/chromium/issues/detail?id=239745.\n\t */\n\tINTERNAL_URI_LIST: 'application/vnd.code.uri-list',\n};\n\nexport interface IDragAndDropData {\n\tupdate(dataTransfer: DataTransfer): void;\n\tgetData(): unknown;\n}\n"]}
|
||||
1477
_internal/editor/esm/vs/base/browser/dom.js
Normal file
1477
_internal/editor/esm/vs/base/browser/dom.js
Normal file
File diff suppressed because it is too large
Load Diff
1
_internal/editor/esm/vs/base/browser/dom.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/dom.js.map
Normal file
File diff suppressed because one or more lines are too long
303
_internal/editor/esm/vs/base/browser/domSanitize.js
Normal file
303
_internal/editor/esm/vs/base/browser/domSanitize.js
Normal file
@@ -0,0 +1,303 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Schemas } from '../common/network.js';
|
||||
import { reset } from './dom.js';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import dompurify from './dompurify/dompurify.js';
|
||||
/**
|
||||
* List of safe, non-input html tags.
|
||||
*/
|
||||
export const basicMarkupHtmlTags = Object.freeze([
|
||||
'a',
|
||||
'abbr',
|
||||
'b',
|
||||
'bdo',
|
||||
'blockquote',
|
||||
'br',
|
||||
'caption',
|
||||
'cite',
|
||||
'code',
|
||||
'col',
|
||||
'colgroup',
|
||||
'dd',
|
||||
'del',
|
||||
'details',
|
||||
'dfn',
|
||||
'div',
|
||||
'dl',
|
||||
'dt',
|
||||
'em',
|
||||
'figcaption',
|
||||
'figure',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'hr',
|
||||
'i',
|
||||
'img',
|
||||
'ins',
|
||||
'kbd',
|
||||
'label',
|
||||
'li',
|
||||
'mark',
|
||||
'ol',
|
||||
'p',
|
||||
'pre',
|
||||
'q',
|
||||
'rp',
|
||||
'rt',
|
||||
'ruby',
|
||||
's',
|
||||
'samp',
|
||||
'small',
|
||||
'small',
|
||||
'source',
|
||||
'span',
|
||||
'strike',
|
||||
'strong',
|
||||
'sub',
|
||||
'summary',
|
||||
'sup',
|
||||
'table',
|
||||
'tbody',
|
||||
'td',
|
||||
'tfoot',
|
||||
'th',
|
||||
'thead',
|
||||
'time',
|
||||
'tr',
|
||||
'tt',
|
||||
'u',
|
||||
'ul',
|
||||
'var',
|
||||
'video',
|
||||
'wbr',
|
||||
]);
|
||||
export const defaultAllowedAttrs = Object.freeze([
|
||||
'href',
|
||||
'target',
|
||||
'src',
|
||||
'alt',
|
||||
'title',
|
||||
'for',
|
||||
'name',
|
||||
'role',
|
||||
'tabindex',
|
||||
'x-dispatch',
|
||||
'required',
|
||||
'checked',
|
||||
'placeholder',
|
||||
'type',
|
||||
'start',
|
||||
'width',
|
||||
'height',
|
||||
'align',
|
||||
]);
|
||||
const fakeRelativeUrlProtocol = 'vscode-relative-path';
|
||||
function validateLink(value, allowedProtocols) {
|
||||
if (allowedProtocols.override === '*') {
|
||||
return true; // allow all protocols
|
||||
}
|
||||
try {
|
||||
const url = new URL(value, fakeRelativeUrlProtocol + '://');
|
||||
if (allowedProtocols.override.includes(url.protocol.replace(/:$/, ''))) {
|
||||
return true;
|
||||
}
|
||||
if (allowedProtocols.allowRelativePaths
|
||||
&& url.protocol === fakeRelativeUrlProtocol + ':'
|
||||
&& !value.trim().toLowerCase().startsWith(fakeRelativeUrlProtocol)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Hooks dompurify using `afterSanitizeAttributes` to check that all `href` and `src`
|
||||
* attributes are valid.
|
||||
*/
|
||||
function hookDomPurifyHrefAndSrcSanitizer(allowedLinkProtocols, allowedMediaProtocols) {
|
||||
dompurify.addHook('afterSanitizeAttributes', (node) => {
|
||||
// check all href/src attributes for validity
|
||||
for (const attr of ['href', 'src']) {
|
||||
if (node.hasAttribute(attr)) {
|
||||
const attrValue = node.getAttribute(attr);
|
||||
if (attr === 'href') {
|
||||
if (!attrValue.startsWith('#') && !validateLink(attrValue, allowedLinkProtocols)) {
|
||||
node.removeAttribute(attr);
|
||||
}
|
||||
}
|
||||
else { // 'src'
|
||||
if (!validateLink(attrValue, allowedMediaProtocols)) {
|
||||
node.removeAttribute(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const defaultDomPurifyConfig = Object.freeze({
|
||||
ALLOWED_TAGS: [...basicMarkupHtmlTags],
|
||||
ALLOWED_ATTR: [...defaultAllowedAttrs],
|
||||
// We sanitize the src/href attributes later if needed
|
||||
ALLOW_UNKNOWN_PROTOCOLS: true,
|
||||
});
|
||||
/**
|
||||
* Sanitizes an html string.
|
||||
*
|
||||
* @param untrusted The HTML string to sanitize.
|
||||
* @param config Optional configuration for sanitization. If not provided, defaults to a safe configuration.
|
||||
*
|
||||
* @returns A sanitized string of html.
|
||||
*/
|
||||
export function sanitizeHtml(untrusted, config) {
|
||||
return doSanitizeHtml(untrusted, config, 'trusted');
|
||||
}
|
||||
function doSanitizeHtml(untrusted, config, outputType) {
|
||||
try {
|
||||
const resolvedConfig = { ...defaultDomPurifyConfig };
|
||||
if (config?.allowedTags) {
|
||||
if (config.allowedTags.override) {
|
||||
resolvedConfig.ALLOWED_TAGS = [...config.allowedTags.override];
|
||||
}
|
||||
if (config.allowedTags.augment) {
|
||||
resolvedConfig.ALLOWED_TAGS = [...(resolvedConfig.ALLOWED_TAGS ?? []), ...config.allowedTags.augment];
|
||||
}
|
||||
}
|
||||
let resolvedAttributes = [...defaultAllowedAttrs];
|
||||
if (config?.allowedAttributes) {
|
||||
if (config.allowedAttributes.override) {
|
||||
resolvedAttributes = [...config.allowedAttributes.override];
|
||||
}
|
||||
if (config.allowedAttributes.augment) {
|
||||
resolvedAttributes = [...resolvedAttributes, ...config.allowedAttributes.augment];
|
||||
}
|
||||
}
|
||||
// All attr names are lower-case in the sanitizer hooks
|
||||
resolvedAttributes = resolvedAttributes.map((attr) => {
|
||||
if (typeof attr === 'string') {
|
||||
return attr.toLowerCase();
|
||||
}
|
||||
return {
|
||||
attributeName: attr.attributeName.toLowerCase(),
|
||||
shouldKeep: attr.shouldKeep,
|
||||
};
|
||||
});
|
||||
const allowedAttrNames = new Set(resolvedAttributes.map(attr => typeof attr === 'string' ? attr : attr.attributeName));
|
||||
const allowedAttrPredicates = new Map();
|
||||
for (const attr of resolvedAttributes) {
|
||||
if (typeof attr === 'string') {
|
||||
// New string attribute value clears previously set predicates
|
||||
allowedAttrPredicates.delete(attr);
|
||||
}
|
||||
else {
|
||||
allowedAttrPredicates.set(attr.attributeName, attr);
|
||||
}
|
||||
}
|
||||
resolvedConfig.ALLOWED_ATTR = Array.from(allowedAttrNames);
|
||||
hookDomPurifyHrefAndSrcSanitizer({
|
||||
override: config?.allowedLinkProtocols?.override ?? [Schemas.http, Schemas.https],
|
||||
allowRelativePaths: config?.allowRelativeLinkPaths ?? false
|
||||
}, {
|
||||
override: config?.allowedMediaProtocols?.override ?? [Schemas.http, Schemas.https],
|
||||
allowRelativePaths: config?.allowRelativeMediaPaths ?? false
|
||||
});
|
||||
if (config?.replaceWithPlaintext) {
|
||||
dompurify.addHook('uponSanitizeElement', replaceWithPlainTextHook);
|
||||
}
|
||||
if (allowedAttrPredicates.size) {
|
||||
dompurify.addHook('uponSanitizeAttribute', (node, e) => {
|
||||
const predicate = allowedAttrPredicates.get(e.attrName);
|
||||
if (predicate) {
|
||||
const result = predicate.shouldKeep(node, e);
|
||||
if (typeof result === 'string') {
|
||||
e.keepAttr = true;
|
||||
e.attrValue = result;
|
||||
}
|
||||
else {
|
||||
e.keepAttr = result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
e.keepAttr = allowedAttrNames.has(e.attrName);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (outputType === 'dom') {
|
||||
return dompurify.sanitize(untrusted, {
|
||||
...resolvedConfig,
|
||||
RETURN_DOM_FRAGMENT: true
|
||||
});
|
||||
}
|
||||
else {
|
||||
return dompurify.sanitize(untrusted, {
|
||||
...resolvedConfig,
|
||||
RETURN_TRUSTED_TYPE: true
|
||||
});
|
||||
}
|
||||
}
|
||||
finally {
|
||||
dompurify.removeAllHooks();
|
||||
}
|
||||
}
|
||||
const selfClosingTags = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
|
||||
function replaceWithPlainTextHook(element, data, _config) {
|
||||
if (!data.allowedTags[data.tagName] && data.tagName !== 'body') {
|
||||
const replacement = convertTagToPlaintext(element);
|
||||
if (element.nodeType === Node.COMMENT_NODE) {
|
||||
// Workaround for https://github.com/cure53/DOMPurify/issues/1005
|
||||
// The comment will be deleted in the next phase. However if we try to remove it now, it will cause
|
||||
// an exception. Instead we insert the text node before the comment.
|
||||
element.parentElement?.insertBefore(replacement, element);
|
||||
}
|
||||
else {
|
||||
element.parentElement?.replaceChild(replacement, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
export function convertTagToPlaintext(element) {
|
||||
let startTagText;
|
||||
let endTagText;
|
||||
if (element.nodeType === Node.COMMENT_NODE) {
|
||||
startTagText = `<!--${element.textContent}-->`;
|
||||
}
|
||||
else {
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
const isSelfClosing = selfClosingTags.includes(tagName);
|
||||
const attrString = element.attributes.length ?
|
||||
' ' + Array.from(element.attributes)
|
||||
.map(attr => `${attr.name}="${attr.value}"`)
|
||||
.join(' ')
|
||||
: '';
|
||||
startTagText = `<${tagName}${attrString}>`;
|
||||
if (!isSelfClosing) {
|
||||
endTagText = `</${tagName}>`;
|
||||
}
|
||||
}
|
||||
const fragment = document.createDocumentFragment();
|
||||
const textNode = element.ownerDocument.createTextNode(startTagText);
|
||||
fragment.appendChild(textNode);
|
||||
while (element.firstChild) {
|
||||
fragment.appendChild(element.firstChild);
|
||||
}
|
||||
const endTagTextNode = endTagText ? element.ownerDocument.createTextNode(endTagText) : undefined;
|
||||
if (endTagTextNode) {
|
||||
fragment.appendChild(endTagTextNode);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
/**
|
||||
* Sanitizes the given `value` and reset the given `node` with it.
|
||||
*/
|
||||
export function safeSetInnerHtml(node, untrusted, config) {
|
||||
const fragment = doSanitizeHtml(untrusted, config, 'dom');
|
||||
reset(node, fragment);
|
||||
}
|
||||
//# sourceMappingURL=domSanitize.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/domSanitize.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/domSanitize.js.map
Normal file
File diff suppressed because one or more lines are too long
142
_internal/editor/esm/vs/base/browser/domStylesheets.js
Normal file
142
_internal/editor/esm/vs/base/browser/domStylesheets.js
Normal file
@@ -0,0 +1,142 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { DisposableStore, toDisposable } from '../common/lifecycle.js';
|
||||
import { autorun } from '../common/observable.js';
|
||||
import { isFirefox } from './browser.js';
|
||||
import { getWindows, sharedMutationObserver } from './dom.js';
|
||||
import { mainWindow } from './window.js';
|
||||
const globalStylesheets = new Map();
|
||||
/**
|
||||
* A version of createStyleSheet which has a unified API to initialize/set the style content.
|
||||
*/
|
||||
export function createStyleSheet2() {
|
||||
return new WrappedStyleElement();
|
||||
}
|
||||
class WrappedStyleElement {
|
||||
constructor() {
|
||||
this._currentCssStyle = '';
|
||||
this._styleSheet = undefined;
|
||||
}
|
||||
setStyle(cssStyle) {
|
||||
if (cssStyle === this._currentCssStyle) {
|
||||
return;
|
||||
}
|
||||
this._currentCssStyle = cssStyle;
|
||||
if (!this._styleSheet) {
|
||||
this._styleSheet = createStyleSheet(mainWindow.document.head, (s) => s.textContent = cssStyle);
|
||||
}
|
||||
else {
|
||||
this._styleSheet.textContent = cssStyle;
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
if (this._styleSheet) {
|
||||
this._styleSheet.remove();
|
||||
this._styleSheet = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
export function createStyleSheet(container = mainWindow.document.head, beforeAppend, disposableStore) {
|
||||
const style = document.createElement('style');
|
||||
style.type = 'text/css';
|
||||
style.media = 'screen';
|
||||
beforeAppend?.(style);
|
||||
container.appendChild(style);
|
||||
if (disposableStore) {
|
||||
disposableStore.add(toDisposable(() => style.remove()));
|
||||
}
|
||||
// With <head> as container, the stylesheet becomes global and is tracked
|
||||
// to support auxiliary windows to clone the stylesheet.
|
||||
if (container === mainWindow.document.head) {
|
||||
const globalStylesheetClones = new Set();
|
||||
globalStylesheets.set(style, globalStylesheetClones);
|
||||
if (disposableStore) {
|
||||
disposableStore.add(toDisposable(() => globalStylesheets.delete(style)));
|
||||
}
|
||||
for (const { window: targetWindow, disposables } of getWindows()) {
|
||||
if (targetWindow === mainWindow) {
|
||||
continue; // main window is already tracked
|
||||
}
|
||||
const cloneDisposable = disposables.add(cloneGlobalStyleSheet(style, globalStylesheetClones, targetWindow));
|
||||
disposableStore?.add(cloneDisposable);
|
||||
}
|
||||
}
|
||||
return style;
|
||||
}
|
||||
function cloneGlobalStyleSheet(globalStylesheet, globalStylesheetClones, targetWindow) {
|
||||
const disposables = new DisposableStore();
|
||||
const clone = globalStylesheet.cloneNode(true);
|
||||
targetWindow.document.head.appendChild(clone);
|
||||
disposables.add(toDisposable(() => clone.remove()));
|
||||
for (const rule of getDynamicStyleSheetRules(globalStylesheet)) {
|
||||
clone.sheet?.insertRule(rule.cssText, clone.sheet?.cssRules.length);
|
||||
}
|
||||
disposables.add(sharedMutationObserver.observe(globalStylesheet, disposables, { childList: true, subtree: isFirefox, characterData: isFirefox })(() => {
|
||||
clone.textContent = globalStylesheet.textContent;
|
||||
}));
|
||||
globalStylesheetClones.add(clone);
|
||||
disposables.add(toDisposable(() => globalStylesheetClones.delete(clone)));
|
||||
return disposables;
|
||||
}
|
||||
let _sharedStyleSheet = null;
|
||||
function getSharedStyleSheet() {
|
||||
if (!_sharedStyleSheet) {
|
||||
_sharedStyleSheet = createStyleSheet();
|
||||
}
|
||||
return _sharedStyleSheet;
|
||||
}
|
||||
function getDynamicStyleSheetRules(style) {
|
||||
if (style?.sheet?.rules) {
|
||||
// Chrome, IE
|
||||
return style.sheet.rules;
|
||||
}
|
||||
if (style?.sheet?.cssRules) {
|
||||
// FF
|
||||
return style.sheet.cssRules;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
export function createCSSRule(selector, cssText, style = getSharedStyleSheet()) {
|
||||
if (!style || !cssText) {
|
||||
return;
|
||||
}
|
||||
style.sheet?.insertRule(`${selector} {${cssText}}`, 0);
|
||||
// Apply rule also to all cloned global stylesheets
|
||||
for (const clonedGlobalStylesheet of globalStylesheets.get(style) ?? []) {
|
||||
createCSSRule(selector, cssText, clonedGlobalStylesheet);
|
||||
}
|
||||
}
|
||||
export function removeCSSRulesContainingSelector(ruleName, style = getSharedStyleSheet()) {
|
||||
if (!style) {
|
||||
return;
|
||||
}
|
||||
const rules = getDynamicStyleSheetRules(style);
|
||||
const toDelete = [];
|
||||
for (let i = 0; i < rules.length; i++) {
|
||||
const rule = rules[i];
|
||||
if (isCSSStyleRule(rule) && rule.selectorText.indexOf(ruleName) !== -1) {
|
||||
toDelete.push(i);
|
||||
}
|
||||
}
|
||||
for (let i = toDelete.length - 1; i >= 0; i--) {
|
||||
style.sheet?.deleteRule(toDelete[i]);
|
||||
}
|
||||
// Remove rules also from all cloned global stylesheets
|
||||
for (const clonedGlobalStylesheet of globalStylesheets.get(style) ?? []) {
|
||||
removeCSSRulesContainingSelector(ruleName, clonedGlobalStylesheet);
|
||||
}
|
||||
}
|
||||
function isCSSStyleRule(rule) {
|
||||
return typeof rule.selectorText === 'string';
|
||||
}
|
||||
export function createStyleSheetFromObservable(css) {
|
||||
const store = new DisposableStore();
|
||||
const w = store.add(createStyleSheet2());
|
||||
store.add(autorun(reader => {
|
||||
w.setStyle(css.read(reader));
|
||||
}));
|
||||
return store;
|
||||
}
|
||||
//# sourceMappingURL=domStylesheets.js.map
|
||||
File diff suppressed because one or more lines are too long
1554
_internal/editor/esm/vs/base/browser/dompurify/dompurify.js
Normal file
1554
_internal/editor/esm/vs/base/browser/dompurify/dompurify.js
Normal file
File diff suppressed because it is too large
Load Diff
21
_internal/editor/esm/vs/base/browser/event.js
Normal file
21
_internal/editor/esm/vs/base/browser/event.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Emitter } from '../common/event.js';
|
||||
export class DomEmitter {
|
||||
get event() {
|
||||
return this.emitter.event;
|
||||
}
|
||||
constructor(element, type, useCapture) {
|
||||
const fn = (e) => this.emitter.fire(e);
|
||||
this.emitter = new Emitter({
|
||||
onWillAddFirstListener: () => element.addEventListener(type, fn, useCapture),
|
||||
onDidRemoveLastListener: () => element.removeEventListener(type, fn, useCapture)
|
||||
});
|
||||
}
|
||||
dispose() {
|
||||
this.emitter.dispose();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=event.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/event.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/event.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/event.ts","vs/base/browser/event.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,OAAO,EAAsB,MAAM,oBAAoB,CAAC;AAgBjE,MAAM,OAAO,UAAU;IAItB,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3B,CAAC;IAKD,YAAY,OAAqB,EAAE,IAAO,EAAE,UAAoB;QAC/D,MAAM,EAAE,GAAG,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAmB,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC;YAC1B,sBAAsB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,EAAE,UAAU,CAAC;YAC5E,uBAAuB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,EAAE,UAAU,CAAC;SAChF,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACN,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;CACD","file":"event.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GestureEvent } from './touch.js';\nimport { Emitter, Event as BaseEvent } from '../common/event.js';\nimport { IDisposable } from '../common/lifecycle.js';\n\nexport type EventHandler = HTMLElement | HTMLDocument | Window;\n\nexport interface DOMEventMap extends HTMLElementEventMap, DocumentEventMap, WindowEventMap {\n\t'-monaco-gesturetap': GestureEvent;\n\t'-monaco-gesturechange': GestureEvent;\n\t'-monaco-gesturestart': GestureEvent;\n\t'-monaco-gesturesend': GestureEvent;\n\t'-monaco-gesturecontextmenu': GestureEvent;\n\t'compositionstart': CompositionEvent;\n\t'compositionupdate': CompositionEvent;\n\t'compositionend': CompositionEvent;\n}\n\nexport class DomEmitter<K extends keyof DOMEventMap> implements IDisposable {\n\n\tprivate readonly emitter: Emitter<DOMEventMap[K]>;\n\n\tget event(): BaseEvent<DOMEventMap[K]> {\n\t\treturn this.emitter.event;\n\t}\n\n\tconstructor(element: Window & typeof globalThis, type: WindowEventMap, useCapture?: boolean);\n\tconstructor(element: Document, type: DocumentEventMap, useCapture?: boolean);\n\tconstructor(element: EventHandler, type: K, useCapture?: boolean);\n\tconstructor(element: EventHandler, type: K, useCapture?: boolean) {\n\t\tconst fn = (e: Event) => this.emitter.fire(e as DOMEventMap[K]);\n\t\tthis.emitter = new Emitter({\n\t\t\tonWillAddFirstListener: () => element.addEventListener(type, fn, useCapture),\n\t\t\tonDidRemoveLastListener: () => element.removeEventListener(type, fn, useCapture)\n\t\t});\n\t}\n\n\tdispose(): void {\n\t\tthis.emitter.dispose();\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { GestureEvent } from './touch.js';\nimport { Emitter, Event as BaseEvent } from '../common/event.js';\nimport { IDisposable } from '../common/lifecycle.js';\n\nexport type EventHandler = HTMLElement | HTMLDocument | Window;\n\nexport interface DOMEventMap extends HTMLElementEventMap, DocumentEventMap, WindowEventMap {\n\t'-monaco-gesturetap': GestureEvent;\n\t'-monaco-gesturechange': GestureEvent;\n\t'-monaco-gesturestart': GestureEvent;\n\t'-monaco-gesturesend': GestureEvent;\n\t'-monaco-gesturecontextmenu': GestureEvent;\n\t'compositionstart': CompositionEvent;\n\t'compositionupdate': CompositionEvent;\n\t'compositionend': CompositionEvent;\n}\n\nexport class DomEmitter<K extends keyof DOMEventMap> implements IDisposable {\n\n\tprivate readonly emitter: Emitter<DOMEventMap[K]>;\n\n\tget event(): BaseEvent<DOMEventMap[K]> {\n\t\treturn this.emitter.event;\n\t}\n\n\tconstructor(element: Window & typeof globalThis, type: WindowEventMap, useCapture?: boolean);\n\tconstructor(element: Document, type: DocumentEventMap, useCapture?: boolean);\n\tconstructor(element: EventHandler, type: K, useCapture?: boolean);\n\tconstructor(element: EventHandler, type: K, useCapture?: boolean) {\n\t\tconst fn = (e: Event) => this.emitter.fire(e as DOMEventMap[K]);\n\t\tthis.emitter = new Emitter({\n\t\t\tonWillAddFirstListener: () => element.addEventListener(type, fn, useCapture),\n\t\t\tonDidRemoveLastListener: () => element.removeEventListener(type, fn, useCapture)\n\t\t});\n\t}\n\n\tdispose(): void {\n\t\tthis.emitter.dispose();\n\t}\n}\n"]}
|
||||
254
_internal/editor/esm/vs/base/browser/fastDomNode.js
Normal file
254
_internal/editor/esm/vs/base/browser/fastDomNode.js
Normal file
@@ -0,0 +1,254 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export class FastDomNode {
|
||||
constructor(domNode) {
|
||||
this.domNode = domNode;
|
||||
this._maxWidth = '';
|
||||
this._width = '';
|
||||
this._height = '';
|
||||
this._top = '';
|
||||
this._left = '';
|
||||
this._bottom = '';
|
||||
this._right = '';
|
||||
this._paddingLeft = '';
|
||||
this._fontFamily = '';
|
||||
this._fontWeight = '';
|
||||
this._fontSize = '';
|
||||
this._fontStyle = '';
|
||||
this._fontFeatureSettings = '';
|
||||
this._fontVariationSettings = '';
|
||||
this._textDecoration = '';
|
||||
this._lineHeight = '';
|
||||
this._letterSpacing = '';
|
||||
this._className = '';
|
||||
this._display = '';
|
||||
this._position = '';
|
||||
this._visibility = '';
|
||||
this._color = '';
|
||||
this._backgroundColor = '';
|
||||
this._layerHint = false;
|
||||
this._contain = 'none';
|
||||
this._boxShadow = '';
|
||||
}
|
||||
focus() {
|
||||
this.domNode.focus();
|
||||
}
|
||||
setMaxWidth(_maxWidth) {
|
||||
const maxWidth = numberAsPixels(_maxWidth);
|
||||
if (this._maxWidth === maxWidth) {
|
||||
return;
|
||||
}
|
||||
this._maxWidth = maxWidth;
|
||||
this.domNode.style.maxWidth = this._maxWidth;
|
||||
}
|
||||
setWidth(_width) {
|
||||
const width = numberAsPixels(_width);
|
||||
if (this._width === width) {
|
||||
return;
|
||||
}
|
||||
this._width = width;
|
||||
this.domNode.style.width = this._width;
|
||||
}
|
||||
setHeight(_height) {
|
||||
const height = numberAsPixels(_height);
|
||||
if (this._height === height) {
|
||||
return;
|
||||
}
|
||||
this._height = height;
|
||||
this.domNode.style.height = this._height;
|
||||
}
|
||||
setTop(_top) {
|
||||
const top = numberAsPixels(_top);
|
||||
if (this._top === top) {
|
||||
return;
|
||||
}
|
||||
this._top = top;
|
||||
this.domNode.style.top = this._top;
|
||||
}
|
||||
setLeft(_left) {
|
||||
const left = numberAsPixels(_left);
|
||||
if (this._left === left) {
|
||||
return;
|
||||
}
|
||||
this._left = left;
|
||||
this.domNode.style.left = this._left;
|
||||
}
|
||||
setBottom(_bottom) {
|
||||
const bottom = numberAsPixels(_bottom);
|
||||
if (this._bottom === bottom) {
|
||||
return;
|
||||
}
|
||||
this._bottom = bottom;
|
||||
this.domNode.style.bottom = this._bottom;
|
||||
}
|
||||
setRight(_right) {
|
||||
const right = numberAsPixels(_right);
|
||||
if (this._right === right) {
|
||||
return;
|
||||
}
|
||||
this._right = right;
|
||||
this.domNode.style.right = this._right;
|
||||
}
|
||||
setPaddingLeft(_paddingLeft) {
|
||||
const paddingLeft = numberAsPixels(_paddingLeft);
|
||||
if (this._paddingLeft === paddingLeft) {
|
||||
return;
|
||||
}
|
||||
this._paddingLeft = paddingLeft;
|
||||
this.domNode.style.paddingLeft = this._paddingLeft;
|
||||
}
|
||||
setFontFamily(fontFamily) {
|
||||
if (this._fontFamily === fontFamily) {
|
||||
return;
|
||||
}
|
||||
this._fontFamily = fontFamily;
|
||||
this.domNode.style.fontFamily = this._fontFamily;
|
||||
}
|
||||
setFontWeight(fontWeight) {
|
||||
if (this._fontWeight === fontWeight) {
|
||||
return;
|
||||
}
|
||||
this._fontWeight = fontWeight;
|
||||
this.domNode.style.fontWeight = this._fontWeight;
|
||||
}
|
||||
setFontSize(_fontSize) {
|
||||
const fontSize = numberAsPixels(_fontSize);
|
||||
if (this._fontSize === fontSize) {
|
||||
return;
|
||||
}
|
||||
this._fontSize = fontSize;
|
||||
this.domNode.style.fontSize = this._fontSize;
|
||||
}
|
||||
setFontStyle(fontStyle) {
|
||||
if (this._fontStyle === fontStyle) {
|
||||
return;
|
||||
}
|
||||
this._fontStyle = fontStyle;
|
||||
this.domNode.style.fontStyle = this._fontStyle;
|
||||
}
|
||||
setFontFeatureSettings(fontFeatureSettings) {
|
||||
if (this._fontFeatureSettings === fontFeatureSettings) {
|
||||
return;
|
||||
}
|
||||
this._fontFeatureSettings = fontFeatureSettings;
|
||||
this.domNode.style.fontFeatureSettings = this._fontFeatureSettings;
|
||||
}
|
||||
setFontVariationSettings(fontVariationSettings) {
|
||||
if (this._fontVariationSettings === fontVariationSettings) {
|
||||
return;
|
||||
}
|
||||
this._fontVariationSettings = fontVariationSettings;
|
||||
this.domNode.style.fontVariationSettings = this._fontVariationSettings;
|
||||
}
|
||||
setTextDecoration(textDecoration) {
|
||||
if (this._textDecoration === textDecoration) {
|
||||
return;
|
||||
}
|
||||
this._textDecoration = textDecoration;
|
||||
this.domNode.style.textDecoration = this._textDecoration;
|
||||
}
|
||||
setLineHeight(_lineHeight) {
|
||||
const lineHeight = numberAsPixels(_lineHeight);
|
||||
if (this._lineHeight === lineHeight) {
|
||||
return;
|
||||
}
|
||||
this._lineHeight = lineHeight;
|
||||
this.domNode.style.lineHeight = this._lineHeight;
|
||||
}
|
||||
setLetterSpacing(_letterSpacing) {
|
||||
const letterSpacing = numberAsPixels(_letterSpacing);
|
||||
if (this._letterSpacing === letterSpacing) {
|
||||
return;
|
||||
}
|
||||
this._letterSpacing = letterSpacing;
|
||||
this.domNode.style.letterSpacing = this._letterSpacing;
|
||||
}
|
||||
setClassName(className) {
|
||||
if (this._className === className) {
|
||||
return;
|
||||
}
|
||||
this._className = className;
|
||||
this.domNode.className = this._className;
|
||||
}
|
||||
toggleClassName(className, shouldHaveIt) {
|
||||
this.domNode.classList.toggle(className, shouldHaveIt);
|
||||
this._className = this.domNode.className;
|
||||
}
|
||||
setDisplay(display) {
|
||||
if (this._display === display) {
|
||||
return;
|
||||
}
|
||||
this._display = display;
|
||||
this.domNode.style.display = this._display;
|
||||
}
|
||||
setPosition(position) {
|
||||
if (this._position === position) {
|
||||
return;
|
||||
}
|
||||
this._position = position;
|
||||
this.domNode.style.position = this._position;
|
||||
}
|
||||
setVisibility(visibility) {
|
||||
if (this._visibility === visibility) {
|
||||
return;
|
||||
}
|
||||
this._visibility = visibility;
|
||||
this.domNode.style.visibility = this._visibility;
|
||||
}
|
||||
setColor(color) {
|
||||
if (this._color === color) {
|
||||
return;
|
||||
}
|
||||
this._color = color;
|
||||
this.domNode.style.color = this._color;
|
||||
}
|
||||
setBackgroundColor(backgroundColor) {
|
||||
if (this._backgroundColor === backgroundColor) {
|
||||
return;
|
||||
}
|
||||
this._backgroundColor = backgroundColor;
|
||||
this.domNode.style.backgroundColor = this._backgroundColor;
|
||||
}
|
||||
setLayerHinting(layerHint) {
|
||||
if (this._layerHint === layerHint) {
|
||||
return;
|
||||
}
|
||||
this._layerHint = layerHint;
|
||||
this.domNode.style.transform = this._layerHint ? 'translate3d(0px, 0px, 0px)' : '';
|
||||
}
|
||||
setBoxShadow(boxShadow) {
|
||||
if (this._boxShadow === boxShadow) {
|
||||
return;
|
||||
}
|
||||
this._boxShadow = boxShadow;
|
||||
this.domNode.style.boxShadow = boxShadow;
|
||||
}
|
||||
setContain(contain) {
|
||||
if (this._contain === contain) {
|
||||
return;
|
||||
}
|
||||
this._contain = contain;
|
||||
this.domNode.style.contain = this._contain;
|
||||
}
|
||||
setAttribute(name, value) {
|
||||
this.domNode.setAttribute(name, value);
|
||||
}
|
||||
removeAttribute(name) {
|
||||
this.domNode.removeAttribute(name);
|
||||
}
|
||||
appendChild(child) {
|
||||
this.domNode.appendChild(child.domNode);
|
||||
}
|
||||
removeChild(child) {
|
||||
this.domNode.removeChild(child.domNode);
|
||||
}
|
||||
}
|
||||
function numberAsPixels(value) {
|
||||
return (typeof value === 'number' ? `${value}px` : value);
|
||||
}
|
||||
export function createFastDomNode(domNode) {
|
||||
return new FastDomNode(domNode);
|
||||
}
|
||||
//# sourceMappingURL=fastDomNode.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/fastDomNode.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/fastDomNode.js.map
Normal file
File diff suppressed because one or more lines are too long
41
_internal/editor/esm/vs/base/browser/fonts.js
Normal file
41
_internal/editor/esm/vs/base/browser/fonts.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { mainWindow } from './window.js';
|
||||
import { isElectron, isMacintosh, isWindows } from '../common/platform.js';
|
||||
/**
|
||||
* The best font-family to be used in CSS based on the platform:
|
||||
* - Windows: Segoe preferred, fallback to sans-serif
|
||||
* - macOS: standard system font, fallback to sans-serif
|
||||
* - Linux: standard system font preferred, fallback to Ubuntu fonts
|
||||
*
|
||||
* Note: this currently does not adjust for different locales.
|
||||
*/
|
||||
export const DEFAULT_FONT_FAMILY = isWindows ? '"Segoe WPC", "Segoe UI", sans-serif' : isMacintosh ? '-apple-system, BlinkMacSystemFont, sans-serif' : 'system-ui, "Ubuntu", "Droid Sans", sans-serif';
|
||||
export const getFonts = async () => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
const fonts = await mainWindow.queryLocalFonts();
|
||||
const fontsArray = [...fonts];
|
||||
const families = fontsArray.map(font => font.family);
|
||||
return families;
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Failed to query fonts: ${error}`);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
export const getFontSnippets = async () => {
|
||||
if (!isElectron) {
|
||||
return [];
|
||||
}
|
||||
const fonts = await getFonts();
|
||||
const snippets = fonts.map(font => {
|
||||
return {
|
||||
body: `${font}`
|
||||
};
|
||||
});
|
||||
return snippets;
|
||||
};
|
||||
//# sourceMappingURL=fonts.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/fonts.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/fonts.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/fonts.ts","vs/base/browser/fonts.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE3E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,+CAA+C,CAAC,CAAC,CAAC,+CAA+C,CAAC;AAMvM,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAuB,EAAE;IACrD,IAAI,CAAC;QACJ,aAAa;QACb,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,eAAe,EAAgB,CAAC;QAC/D,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;QACjD,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC,CAAC;AAGF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,IAAmC,EAAE;IACxE,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,EAAE,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAyB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACvD,OAAO;YACN,IAAI,EAAE,GAAG,IAAI,EAAE;SACf,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC","file":"fonts.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { mainWindow } from './window.js';\nimport { IJSONSchemaSnippet } from '../common/jsonSchema.js';\nimport { isElectron, isMacintosh, isWindows } from '../common/platform.js';\n\n/**\n * The best font-family to be used in CSS based on the platform:\n * - Windows: Segoe preferred, fallback to sans-serif\n * - macOS: standard system font, fallback to sans-serif\n * - Linux: standard system font preferred, fallback to Ubuntu fonts\n *\n * Note: this currently does not adjust for different locales.\n */\nexport const DEFAULT_FONT_FAMILY = isWindows ? '\"Segoe WPC\", \"Segoe UI\", sans-serif' : isMacintosh ? '-apple-system, BlinkMacSystemFont, sans-serif' : 'system-ui, \"Ubuntu\", \"Droid Sans\", sans-serif';\n\ninterface FontData {\n\treadonly family: string;\n}\n\nexport const getFonts = async (): Promise<string[]> => {\n\ttry {\n\t\t// @ts-ignore\n\t\tconst fonts = await mainWindow.queryLocalFonts() as FontData[];\n\t\tconst fontsArray = [...fonts];\n\t\tconst families = fontsArray.map(font => font.family);\n\t\treturn families;\n\t} catch (error) {\n\t\tconsole.error(`Failed to query fonts: ${error}`);\n\t\treturn [];\n\t}\n};\n\n\nexport const getFontSnippets = async (): Promise<IJSONSchemaSnippet[]> => {\n\tif (!isElectron) {\n\t\treturn [];\n\t}\n\tconst fonts = await getFonts();\n\tconst snippets: IJSONSchemaSnippet[] = fonts.map(font => {\n\t\treturn {\n\t\t\tbody: `${font}`\n\t\t};\n\t});\n\treturn snippets;\n};\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { mainWindow } from './window.js';\nimport { IJSONSchemaSnippet } from '../common/jsonSchema.js';\nimport { isElectron, isMacintosh, isWindows } from '../common/platform.js';\n\n/**\n * The best font-family to be used in CSS based on the platform:\n * - Windows: Segoe preferred, fallback to sans-serif\n * - macOS: standard system font, fallback to sans-serif\n * - Linux: standard system font preferred, fallback to Ubuntu fonts\n *\n * Note: this currently does not adjust for different locales.\n */\nexport const DEFAULT_FONT_FAMILY = isWindows ? '\"Segoe WPC\", \"Segoe UI\", sans-serif' : isMacintosh ? '-apple-system, BlinkMacSystemFont, sans-serif' : 'system-ui, \"Ubuntu\", \"Droid Sans\", sans-serif';\n\ninterface FontData {\n\treadonly family: string;\n}\n\nexport const getFonts = async (): Promise<string[]> => {\n\ttry {\n\t\t// @ts-ignore\n\t\tconst fonts = await mainWindow.queryLocalFonts() as FontData[];\n\t\tconst fontsArray = [...fonts];\n\t\tconst families = fontsArray.map(font => font.family);\n\t\treturn families;\n\t} catch (error) {\n\t\tconsole.error(`Failed to query fonts: ${error}`);\n\t\treturn [];\n\t}\n};\n\n\nexport const getFontSnippets = async (): Promise<IJSONSchemaSnippet[]> => {\n\tif (!isElectron) {\n\t\treturn [];\n\t}\n\tconst fonts = await getFonts();\n\tconst snippets: IJSONSchemaSnippet[] = fonts.map(font => {\n\t\treturn {\n\t\t\tbody: `${font}`\n\t\t};\n\t});\n\treturn snippets;\n};\n"]}
|
||||
161
_internal/editor/esm/vs/base/browser/formattedTextRenderer.js
Normal file
161
_internal/editor/esm/vs/base/browser/formattedTextRenderer.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as DOM from './dom.js';
|
||||
export function renderText(text, _options, target) {
|
||||
const element = target ?? document.createElement('div');
|
||||
element.textContent = text;
|
||||
return element;
|
||||
}
|
||||
export function renderFormattedText(formattedText, options, target) {
|
||||
const element = target ?? document.createElement('div');
|
||||
element.textContent = '';
|
||||
_renderFormattedText(element, parseFormattedText(formattedText, !!options?.renderCodeSegments), options?.actionHandler, options?.renderCodeSegments);
|
||||
return element;
|
||||
}
|
||||
class StringStream {
|
||||
constructor(source) {
|
||||
this.source = source;
|
||||
this.index = 0;
|
||||
}
|
||||
eos() {
|
||||
return this.index >= this.source.length;
|
||||
}
|
||||
next() {
|
||||
const next = this.peek();
|
||||
this.advance();
|
||||
return next;
|
||||
}
|
||||
peek() {
|
||||
return this.source[this.index];
|
||||
}
|
||||
advance() {
|
||||
this.index++;
|
||||
}
|
||||
}
|
||||
function _renderFormattedText(element, treeNode, actionHandler, renderCodeSegments) {
|
||||
let child;
|
||||
if (treeNode.type === 2 /* FormatType.Text */) {
|
||||
child = document.createTextNode(treeNode.content || '');
|
||||
}
|
||||
else if (treeNode.type === 3 /* FormatType.Bold */) {
|
||||
child = document.createElement('b');
|
||||
}
|
||||
else if (treeNode.type === 4 /* FormatType.Italics */) {
|
||||
child = document.createElement('i');
|
||||
}
|
||||
else if (treeNode.type === 7 /* FormatType.Code */ && renderCodeSegments) {
|
||||
child = document.createElement('code');
|
||||
}
|
||||
else if (treeNode.type === 5 /* FormatType.Action */ && actionHandler) {
|
||||
const a = document.createElement('a');
|
||||
actionHandler.disposables.add(DOM.addStandardDisposableListener(a, 'click', (event) => {
|
||||
actionHandler.callback(String(treeNode.index), event);
|
||||
}));
|
||||
child = a;
|
||||
}
|
||||
else if (treeNode.type === 8 /* FormatType.NewLine */) {
|
||||
child = document.createElement('br');
|
||||
}
|
||||
else if (treeNode.type === 1 /* FormatType.Root */) {
|
||||
child = element;
|
||||
}
|
||||
if (child && element !== child) {
|
||||
element.appendChild(child);
|
||||
}
|
||||
if (child && Array.isArray(treeNode.children)) {
|
||||
treeNode.children.forEach((nodeChild) => {
|
||||
_renderFormattedText(child, nodeChild, actionHandler, renderCodeSegments);
|
||||
});
|
||||
}
|
||||
}
|
||||
function parseFormattedText(content, parseCodeSegments) {
|
||||
const root = {
|
||||
type: 1 /* FormatType.Root */,
|
||||
children: []
|
||||
};
|
||||
let actionViewItemIndex = 0;
|
||||
let current = root;
|
||||
const stack = [];
|
||||
const stream = new StringStream(content);
|
||||
while (!stream.eos()) {
|
||||
let next = stream.next();
|
||||
const isEscapedFormatType = (next === '\\' && formatTagType(stream.peek(), parseCodeSegments) !== 0 /* FormatType.Invalid */);
|
||||
if (isEscapedFormatType) {
|
||||
next = stream.next(); // unread the backslash if it escapes a format tag type
|
||||
}
|
||||
if (!isEscapedFormatType && isFormatTag(next, parseCodeSegments) && next === stream.peek()) {
|
||||
stream.advance();
|
||||
if (current.type === 2 /* FormatType.Text */) {
|
||||
current = stack.pop();
|
||||
}
|
||||
const type = formatTagType(next, parseCodeSegments);
|
||||
if (current.type === type || (current.type === 5 /* FormatType.Action */ && type === 6 /* FormatType.ActionClose */)) {
|
||||
current = stack.pop();
|
||||
}
|
||||
else {
|
||||
const newCurrent = {
|
||||
type: type,
|
||||
children: []
|
||||
};
|
||||
if (type === 5 /* FormatType.Action */) {
|
||||
newCurrent.index = actionViewItemIndex;
|
||||
actionViewItemIndex++;
|
||||
}
|
||||
current.children.push(newCurrent);
|
||||
stack.push(current);
|
||||
current = newCurrent;
|
||||
}
|
||||
}
|
||||
else if (next === '\n') {
|
||||
if (current.type === 2 /* FormatType.Text */) {
|
||||
current = stack.pop();
|
||||
}
|
||||
current.children.push({
|
||||
type: 8 /* FormatType.NewLine */
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (current.type !== 2 /* FormatType.Text */) {
|
||||
const textCurrent = {
|
||||
type: 2 /* FormatType.Text */,
|
||||
content: next
|
||||
};
|
||||
current.children.push(textCurrent);
|
||||
stack.push(current);
|
||||
current = textCurrent;
|
||||
}
|
||||
else {
|
||||
current.content += next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current.type === 2 /* FormatType.Text */) {
|
||||
current = stack.pop();
|
||||
}
|
||||
if (stack.length) {
|
||||
// incorrectly formatted string literal
|
||||
}
|
||||
return root;
|
||||
}
|
||||
function isFormatTag(char, supportCodeSegments) {
|
||||
return formatTagType(char, supportCodeSegments) !== 0 /* FormatType.Invalid */;
|
||||
}
|
||||
function formatTagType(char, supportCodeSegments) {
|
||||
switch (char) {
|
||||
case '*':
|
||||
return 3 /* FormatType.Bold */;
|
||||
case '_':
|
||||
return 4 /* FormatType.Italics */;
|
||||
case '[':
|
||||
return 5 /* FormatType.Action */;
|
||||
case ']':
|
||||
return 6 /* FormatType.ActionClose */;
|
||||
case '`':
|
||||
return supportCodeSegments ? 7 /* FormatType.Code */ : 0 /* FormatType.Invalid */;
|
||||
default:
|
||||
return 0 /* FormatType.Invalid */;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=formattedTextRenderer.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from './dom.js';
|
||||
import { DisposableStore, toDisposable } from '../common/lifecycle.js';
|
||||
export class GlobalPointerMoveMonitor {
|
||||
constructor() {
|
||||
this._hooks = new DisposableStore();
|
||||
this._pointerMoveCallback = null;
|
||||
this._onStopCallback = null;
|
||||
}
|
||||
dispose() {
|
||||
this.stopMonitoring(false);
|
||||
this._hooks.dispose();
|
||||
}
|
||||
stopMonitoring(invokeStopCallback, browserEvent) {
|
||||
if (!this.isMonitoring()) {
|
||||
// Not monitoring
|
||||
return;
|
||||
}
|
||||
// Unhook
|
||||
this._hooks.clear();
|
||||
this._pointerMoveCallback = null;
|
||||
const onStopCallback = this._onStopCallback;
|
||||
this._onStopCallback = null;
|
||||
if (invokeStopCallback && onStopCallback) {
|
||||
onStopCallback(browserEvent);
|
||||
}
|
||||
}
|
||||
isMonitoring() {
|
||||
return !!this._pointerMoveCallback;
|
||||
}
|
||||
startMonitoring(initialElement, pointerId, initialButtons, pointerMoveCallback, onStopCallback) {
|
||||
if (this.isMonitoring()) {
|
||||
this.stopMonitoring(false);
|
||||
}
|
||||
this._pointerMoveCallback = pointerMoveCallback;
|
||||
this._onStopCallback = onStopCallback;
|
||||
let eventSource = initialElement;
|
||||
try {
|
||||
initialElement.setPointerCapture(pointerId);
|
||||
this._hooks.add(toDisposable(() => {
|
||||
try {
|
||||
initialElement.releasePointerCapture(pointerId);
|
||||
}
|
||||
catch (err) {
|
||||
// See https://github.com/microsoft/vscode/issues/161731
|
||||
//
|
||||
// `releasePointerCapture` sometimes fails when being invoked with the exception:
|
||||
// DOMException: Failed to execute 'releasePointerCapture' on 'Element':
|
||||
// No active pointer with the given id is found.
|
||||
//
|
||||
// There's no need to do anything in case of failure
|
||||
}
|
||||
}));
|
||||
}
|
||||
catch (err) {
|
||||
// See https://github.com/microsoft/vscode/issues/144584
|
||||
// See https://github.com/microsoft/vscode/issues/146947
|
||||
// `setPointerCapture` sometimes fails when being invoked
|
||||
// from a `mousedown` listener on macOS and Windows
|
||||
// and it always fails on Linux with the exception:
|
||||
// DOMException: Failed to execute 'setPointerCapture' on 'Element':
|
||||
// No active pointer with the given id is found.
|
||||
// In case of failure, we bind the listeners on the window
|
||||
eventSource = dom.getWindow(initialElement);
|
||||
}
|
||||
this._hooks.add(dom.addDisposableListener(eventSource, dom.EventType.POINTER_MOVE, (e) => {
|
||||
if (e.buttons !== initialButtons) {
|
||||
// Buttons state has changed in the meantime
|
||||
this.stopMonitoring(true);
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
this._pointerMoveCallback(e);
|
||||
}));
|
||||
this._hooks.add(dom.addDisposableListener(eventSource, dom.EventType.POINTER_UP, (e) => this.stopMonitoring(true)));
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=globalPointerMoveMonitor.js.map
|
||||
File diff suppressed because one or more lines are too long
6
_internal/editor/esm/vs/base/browser/history.js
Normal file
6
_internal/editor/esm/vs/base/browser/history.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export {};
|
||||
//# sourceMappingURL=history.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/history.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/history.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/history.ts","vs/base/browser/history.ts"],"names":[],"mappings":"AAAA;;;gGAGgG","file":"history.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Event } from '../common/event.js';\n\nexport interface IHistoryNavigationWidget {\n\n\treadonly element: HTMLElement;\n\n\tshowPreviousValue(): void;\n\n\tshowNextValue(): void;\n\n\tonDidFocus: Event<void>;\n\n\tonDidBlur: Event<void>;\n\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Event } from '../common/event.js';\n\nexport interface IHistoryNavigationWidget {\n\n\treadonly element: HTMLElement;\n\n\tshowPreviousValue(): void;\n\n\tshowNextValue(): void;\n\n\tonDidFocus: Event<void>;\n\n\tonDidBlur: Event<void>;\n\n}\n"]}
|
||||
86
_internal/editor/esm/vs/base/browser/iframe.js
Normal file
86
_internal/editor/esm/vs/base/browser/iframe.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const sameOriginWindowChainCache = new WeakMap();
|
||||
function getParentWindowIfSameOrigin(w) {
|
||||
if (!w.parent || w.parent === w) {
|
||||
return null;
|
||||
}
|
||||
// Cannot really tell if we have access to the parent window unless we try to access something in it
|
||||
try {
|
||||
const location = w.location;
|
||||
const parentLocation = w.parent.location;
|
||||
if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
return null;
|
||||
}
|
||||
return w.parent;
|
||||
}
|
||||
export class IframeUtils {
|
||||
/**
|
||||
* Returns a chain of embedded windows with the same origin (which can be accessed programmatically).
|
||||
* Having a chain of length 1 might mean that the current execution environment is running outside of an iframe or inside an iframe embedded in a window with a different origin.
|
||||
*/
|
||||
static getSameOriginWindowChain(targetWindow) {
|
||||
let windowChainCache = sameOriginWindowChainCache.get(targetWindow);
|
||||
if (!windowChainCache) {
|
||||
windowChainCache = [];
|
||||
sameOriginWindowChainCache.set(targetWindow, windowChainCache);
|
||||
let w = targetWindow;
|
||||
let parent;
|
||||
do {
|
||||
parent = getParentWindowIfSameOrigin(w);
|
||||
if (parent) {
|
||||
windowChainCache.push({
|
||||
window: new WeakRef(w),
|
||||
iframeElement: w.frameElement || null
|
||||
});
|
||||
}
|
||||
else {
|
||||
windowChainCache.push({
|
||||
window: new WeakRef(w),
|
||||
iframeElement: null
|
||||
});
|
||||
}
|
||||
w = parent;
|
||||
} while (w);
|
||||
}
|
||||
return windowChainCache.slice(0);
|
||||
}
|
||||
/**
|
||||
* Returns the position of `childWindow` relative to `ancestorWindow`
|
||||
*/
|
||||
static getPositionOfChildWindowRelativeToAncestorWindow(childWindow, ancestorWindow) {
|
||||
if (!ancestorWindow || childWindow === ancestorWindow) {
|
||||
return {
|
||||
top: 0,
|
||||
left: 0
|
||||
};
|
||||
}
|
||||
let top = 0, left = 0;
|
||||
const windowChain = this.getSameOriginWindowChain(childWindow);
|
||||
for (const windowChainEl of windowChain) {
|
||||
const windowInChain = windowChainEl.window.deref();
|
||||
top += windowInChain?.scrollY ?? 0;
|
||||
left += windowInChain?.scrollX ?? 0;
|
||||
if (windowInChain === ancestorWindow) {
|
||||
break;
|
||||
}
|
||||
if (!windowChainEl.iframeElement) {
|
||||
break;
|
||||
}
|
||||
const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();
|
||||
top += boundingRect.top;
|
||||
left += boundingRect.left;
|
||||
}
|
||||
return {
|
||||
top: top,
|
||||
left: left
|
||||
};
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=iframe.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/iframe.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/iframe.js.map
Normal file
File diff suppressed because one or more lines are too long
123
_internal/editor/esm/vs/base/browser/keyboardEvent.js
Normal file
123
_internal/editor/esm/vs/base/browser/keyboardEvent.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as browser from './browser.js';
|
||||
import { EVENT_KEY_CODE_MAP, KeyCodeUtils } from '../common/keyCodes.js';
|
||||
import { KeyCodeChord } from '../common/keybindings.js';
|
||||
import * as platform from '../common/platform.js';
|
||||
function extractKeyCode(e) {
|
||||
if (e.charCode) {
|
||||
// "keypress" events mostly
|
||||
const char = String.fromCharCode(e.charCode).toUpperCase();
|
||||
return KeyCodeUtils.fromString(char);
|
||||
}
|
||||
const keyCode = e.keyCode;
|
||||
// browser quirks
|
||||
if (keyCode === 3) {
|
||||
return 7 /* KeyCode.PauseBreak */;
|
||||
}
|
||||
else if (browser.isFirefox) {
|
||||
switch (keyCode) {
|
||||
case 59: return 85 /* KeyCode.Semicolon */;
|
||||
case 60:
|
||||
if (platform.isLinux) {
|
||||
return 97 /* KeyCode.IntlBackslash */;
|
||||
}
|
||||
break;
|
||||
case 61: return 86 /* KeyCode.Equal */;
|
||||
// based on: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#numpad_keys
|
||||
case 107: return 109 /* KeyCode.NumpadAdd */;
|
||||
case 109: return 111 /* KeyCode.NumpadSubtract */;
|
||||
case 173: return 88 /* KeyCode.Minus */;
|
||||
case 224:
|
||||
if (platform.isMacintosh) {
|
||||
return 57 /* KeyCode.Meta */;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (browser.isWebKit) {
|
||||
if (platform.isMacintosh && keyCode === 93) {
|
||||
// the two meta keys in the Mac have different key codes (91 and 93)
|
||||
return 57 /* KeyCode.Meta */;
|
||||
}
|
||||
else if (!platform.isMacintosh && keyCode === 92) {
|
||||
return 57 /* KeyCode.Meta */;
|
||||
}
|
||||
}
|
||||
// cross browser keycodes:
|
||||
return EVENT_KEY_CODE_MAP[keyCode] || 0 /* KeyCode.Unknown */;
|
||||
}
|
||||
const ctrlKeyMod = (platform.isMacintosh ? 256 /* KeyMod.WinCtrl */ : 2048 /* KeyMod.CtrlCmd */);
|
||||
const altKeyMod = 512 /* KeyMod.Alt */;
|
||||
const shiftKeyMod = 1024 /* KeyMod.Shift */;
|
||||
const metaKeyMod = (platform.isMacintosh ? 2048 /* KeyMod.CtrlCmd */ : 256 /* KeyMod.WinCtrl */);
|
||||
export class StandardKeyboardEvent {
|
||||
constructor(source) {
|
||||
this._standardKeyboardEventBrand = true;
|
||||
const e = source;
|
||||
this.browserEvent = e;
|
||||
this.target = e.target;
|
||||
this.ctrlKey = e.ctrlKey;
|
||||
this.shiftKey = e.shiftKey;
|
||||
this.altKey = e.altKey;
|
||||
this.metaKey = e.metaKey;
|
||||
this.altGraphKey = e.getModifierState?.('AltGraph');
|
||||
this.keyCode = extractKeyCode(e);
|
||||
this.code = e.code;
|
||||
// console.info(e.type + ": keyCode: " + e.keyCode + ", which: " + e.which + ", charCode: " + e.charCode + ", detail: " + e.detail + " ====> " + this.keyCode + ' -- ' + KeyCode[this.keyCode]);
|
||||
this.ctrlKey = this.ctrlKey || this.keyCode === 5 /* KeyCode.Ctrl */;
|
||||
this.altKey = this.altKey || this.keyCode === 6 /* KeyCode.Alt */;
|
||||
this.shiftKey = this.shiftKey || this.keyCode === 4 /* KeyCode.Shift */;
|
||||
this.metaKey = this.metaKey || this.keyCode === 57 /* KeyCode.Meta */;
|
||||
this._asKeybinding = this._computeKeybinding();
|
||||
this._asKeyCodeChord = this._computeKeyCodeChord();
|
||||
// console.log(`code: ${e.code}, keyCode: ${e.keyCode}, key: ${e.key}`);
|
||||
}
|
||||
preventDefault() {
|
||||
if (this.browserEvent && this.browserEvent.preventDefault) {
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
}
|
||||
stopPropagation() {
|
||||
if (this.browserEvent && this.browserEvent.stopPropagation) {
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
}
|
||||
toKeyCodeChord() {
|
||||
return this._asKeyCodeChord;
|
||||
}
|
||||
equals(other) {
|
||||
return this._asKeybinding === other;
|
||||
}
|
||||
_computeKeybinding() {
|
||||
let key = 0 /* KeyCode.Unknown */;
|
||||
if (this.keyCode !== 5 /* KeyCode.Ctrl */ && this.keyCode !== 4 /* KeyCode.Shift */ && this.keyCode !== 6 /* KeyCode.Alt */ && this.keyCode !== 57 /* KeyCode.Meta */) {
|
||||
key = this.keyCode;
|
||||
}
|
||||
let result = 0;
|
||||
if (this.ctrlKey) {
|
||||
result |= ctrlKeyMod;
|
||||
}
|
||||
if (this.altKey) {
|
||||
result |= altKeyMod;
|
||||
}
|
||||
if (this.shiftKey) {
|
||||
result |= shiftKeyMod;
|
||||
}
|
||||
if (this.metaKey) {
|
||||
result |= metaKeyMod;
|
||||
}
|
||||
result |= key;
|
||||
return result;
|
||||
}
|
||||
_computeKeyCodeChord() {
|
||||
let key = 0 /* KeyCode.Unknown */;
|
||||
if (this.keyCode !== 5 /* KeyCode.Ctrl */ && this.keyCode !== 4 /* KeyCode.Shift */ && this.keyCode !== 6 /* KeyCode.Alt */ && this.keyCode !== 57 /* KeyCode.Meta */) {
|
||||
key = this.keyCode;
|
||||
}
|
||||
return new KeyCodeChord(this.ctrlKey, this.shiftKey, this.altKey, this.metaKey, key);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=keyboardEvent.js.map
|
||||
File diff suppressed because one or more lines are too long
837
_internal/editor/esm/vs/base/browser/markdownRenderer.js
Normal file
837
_internal/editor/esm/vs/base/browser/markdownRenderer.js
Normal file
@@ -0,0 +1,837 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { onUnexpectedError } from '../common/errors.js';
|
||||
import { escapeDoubleQuotes, parseHrefAndDimensions, removeMarkdownEscapes } from '../common/htmlContent.js';
|
||||
import { markdownEscapeEscapedIcons } from '../common/iconLabels.js';
|
||||
import { defaultGenerator } from '../common/idGenerator.js';
|
||||
import { Lazy } from '../common/lazy.js';
|
||||
import { DisposableStore } from '../common/lifecycle.js';
|
||||
import * as marked from '../common/marked/marked.js';
|
||||
import { parse } from '../common/marshalling.js';
|
||||
import { FileAccess, Schemas } from '../common/network.js';
|
||||
import { cloneAndChange } from '../common/objects.js';
|
||||
import { dirname, resolvePath } from '../common/resources.js';
|
||||
import { escape } from '../common/strings.js';
|
||||
import { URI } from '../common/uri.js';
|
||||
import * as DOM from './dom.js';
|
||||
import * as domSanitize from './domSanitize.js';
|
||||
import { convertTagToPlaintext } from './domSanitize.js';
|
||||
import { StandardKeyboardEvent } from './keyboardEvent.js';
|
||||
import { StandardMouseEvent } from './mouseEvent.js';
|
||||
import { renderLabelWithIcons } from './ui/iconLabel/iconLabels.js';
|
||||
const defaultMarkedRenderers = Object.freeze({
|
||||
image: ({ href, title, text }) => {
|
||||
let dimensions = [];
|
||||
let attributes = [];
|
||||
if (href) {
|
||||
({ href, dimensions } = parseHrefAndDimensions(href));
|
||||
attributes.push(`src="${escapeDoubleQuotes(href)}"`);
|
||||
}
|
||||
if (text) {
|
||||
attributes.push(`alt="${escapeDoubleQuotes(text)}"`);
|
||||
}
|
||||
if (title) {
|
||||
attributes.push(`title="${escapeDoubleQuotes(title)}"`);
|
||||
}
|
||||
if (dimensions.length) {
|
||||
attributes = attributes.concat(dimensions);
|
||||
}
|
||||
return '<img ' + attributes.join(' ') + '>';
|
||||
},
|
||||
paragraph({ tokens }) {
|
||||
return `<p>${this.parser.parseInline(tokens)}</p>`;
|
||||
},
|
||||
link({ href, title, tokens }) {
|
||||
let text = this.parser.parseInline(tokens);
|
||||
if (typeof href !== 'string') {
|
||||
return '';
|
||||
}
|
||||
// Remove markdown escapes. Workaround for https://github.com/chjj/marked/issues/829
|
||||
if (href === text) { // raw link case
|
||||
text = removeMarkdownEscapes(text);
|
||||
}
|
||||
title = typeof title === 'string' ? escapeDoubleQuotes(removeMarkdownEscapes(title)) : '';
|
||||
href = removeMarkdownEscapes(href);
|
||||
// HTML Encode href
|
||||
href = href.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
return `<a href="${href}" title="${title || href}" draggable="false">${text}</a>`;
|
||||
},
|
||||
});
|
||||
/**
|
||||
* Low-level way create a html element from a markdown string.
|
||||
*
|
||||
* **Note** that for most cases you should be using {@link import('../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js').MarkdownRenderer MarkdownRenderer}
|
||||
* which comes with support for pretty code block rendering and which uses the default way of handling links.
|
||||
*/
|
||||
export function renderMarkdown(markdown, options = {}, target) {
|
||||
const disposables = new DisposableStore();
|
||||
let isDisposed = false;
|
||||
const markedInstance = new marked.Marked(...(options.markedExtensions ?? []));
|
||||
const { renderer, codeBlocks, syncCodeBlocks } = createMarkdownRenderer(markedInstance, options, markdown);
|
||||
const value = preprocessMarkdownString(markdown);
|
||||
let renderedMarkdown;
|
||||
if (options.fillInIncompleteTokens) {
|
||||
// The defaults are applied by parse but not lexer()/parser(), and they need to be present
|
||||
const opts = {
|
||||
...markedInstance.defaults,
|
||||
...options.markedOptions,
|
||||
renderer
|
||||
};
|
||||
const tokens = markedInstance.lexer(value, opts);
|
||||
const newTokens = fillInIncompleteTokens(tokens);
|
||||
renderedMarkdown = markedInstance.parser(newTokens, opts);
|
||||
}
|
||||
else {
|
||||
renderedMarkdown = markedInstance.parse(value, { ...options?.markedOptions, renderer, async: false });
|
||||
}
|
||||
// Rewrite theme icons
|
||||
if (markdown.supportThemeIcons) {
|
||||
const elements = renderLabelWithIcons(renderedMarkdown);
|
||||
renderedMarkdown = elements.map(e => typeof e === 'string' ? e : e.outerHTML).join('');
|
||||
}
|
||||
const renderedContent = document.createElement('div');
|
||||
const sanitizerConfig = getDomSanitizerConfig(markdown, options.sanitizerConfig ?? {});
|
||||
domSanitize.safeSetInnerHtml(renderedContent, renderedMarkdown, sanitizerConfig);
|
||||
// Rewrite links and images before potentially inserting them into the real dom
|
||||
rewriteRenderedLinks(markdown, options, renderedContent);
|
||||
let outElement;
|
||||
if (target) {
|
||||
outElement = target;
|
||||
DOM.reset(target, ...renderedContent.children);
|
||||
}
|
||||
else {
|
||||
outElement = renderedContent;
|
||||
}
|
||||
if (codeBlocks.length > 0) {
|
||||
Promise.all(codeBlocks).then((tuples) => {
|
||||
if (isDisposed) {
|
||||
return;
|
||||
}
|
||||
const renderedElements = new Map(tuples);
|
||||
const placeholderElements = outElement.querySelectorAll(`div[data-code]`);
|
||||
for (const placeholderElement of placeholderElements) {
|
||||
const renderedElement = renderedElements.get(placeholderElement.dataset['code'] ?? '');
|
||||
if (renderedElement) {
|
||||
DOM.reset(placeholderElement, renderedElement);
|
||||
}
|
||||
}
|
||||
options.asyncRenderCallback?.();
|
||||
});
|
||||
}
|
||||
else if (syncCodeBlocks.length > 0) {
|
||||
const renderedElements = new Map(syncCodeBlocks);
|
||||
const placeholderElements = outElement.querySelectorAll(`div[data-code]`);
|
||||
for (const placeholderElement of placeholderElements) {
|
||||
const renderedElement = renderedElements.get(placeholderElement.dataset['code'] ?? '');
|
||||
if (renderedElement) {
|
||||
DOM.reset(placeholderElement, renderedElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Signal size changes for image tags
|
||||
if (options.asyncRenderCallback) {
|
||||
for (const img of outElement.getElementsByTagName('img')) {
|
||||
const listener = disposables.add(DOM.addDisposableListener(img, 'load', () => {
|
||||
listener.dispose();
|
||||
options.asyncRenderCallback();
|
||||
}));
|
||||
}
|
||||
}
|
||||
// Add event listeners for links
|
||||
if (options.actionHandler) {
|
||||
const clickCb = (e) => {
|
||||
const mouseEvent = new StandardMouseEvent(DOM.getWindow(outElement), e);
|
||||
if (!mouseEvent.leftButton && !mouseEvent.middleButton) {
|
||||
return;
|
||||
}
|
||||
activateLink(markdown, options, mouseEvent);
|
||||
};
|
||||
disposables.add(DOM.addDisposableListener(outElement, 'click', clickCb));
|
||||
disposables.add(DOM.addDisposableListener(outElement, 'auxclick', clickCb));
|
||||
disposables.add(DOM.addDisposableListener(outElement, 'keydown', (e) => {
|
||||
const keyboardEvent = new StandardKeyboardEvent(e);
|
||||
if (!keyboardEvent.equals(10 /* KeyCode.Space */) && !keyboardEvent.equals(3 /* KeyCode.Enter */)) {
|
||||
return;
|
||||
}
|
||||
activateLink(markdown, options, keyboardEvent);
|
||||
}));
|
||||
}
|
||||
// Remove/disable inputs
|
||||
for (const input of [...outElement.getElementsByTagName('input')]) {
|
||||
if (input.attributes.getNamedItem('type')?.value === 'checkbox') {
|
||||
input.setAttribute('disabled', '');
|
||||
}
|
||||
else {
|
||||
if (options.sanitizerConfig?.replaceWithPlaintext) {
|
||||
const replacement = convertTagToPlaintext(input);
|
||||
input.parentElement?.replaceChild(replacement, input);
|
||||
}
|
||||
else {
|
||||
input.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
element: outElement,
|
||||
dispose: () => {
|
||||
isDisposed = true;
|
||||
disposables.dispose();
|
||||
}
|
||||
};
|
||||
}
|
||||
function rewriteRenderedLinks(markdown, options, root) {
|
||||
for (const el of root.querySelectorAll('img, audio, video, source')) {
|
||||
const src = el.getAttribute('src'); // Get the raw 'src' attribute value as text, not the resolved 'src'
|
||||
if (src) {
|
||||
let href = src;
|
||||
try {
|
||||
if (markdown.baseUri) { // absolute or relative local path, or file: uri
|
||||
href = resolveWithBaseUri(URI.from(markdown.baseUri), href);
|
||||
}
|
||||
}
|
||||
catch (err) { }
|
||||
el.setAttribute('src', massageHref(markdown, href, true));
|
||||
if (options.sanitizerConfig?.remoteImageIsAllowed) {
|
||||
const uri = URI.parse(href);
|
||||
if (uri.scheme !== Schemas.file && uri.scheme !== Schemas.data && !options.sanitizerConfig.remoteImageIsAllowed(uri)) {
|
||||
el.replaceWith(DOM.$('', undefined, el.outerHTML));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const el of root.querySelectorAll('a')) {
|
||||
const href = el.getAttribute('href'); // Get the raw 'href' attribute value as text, not the resolved 'href'
|
||||
el.setAttribute('href', ''); // Clear out href. We use the `data-href` for handling clicks instead
|
||||
if (!href
|
||||
|| /^data:|javascript:/i.test(href)
|
||||
|| (/^command:/i.test(href) && !markdown.isTrusted)
|
||||
|| /^command:(\/\/\/)?_workbench\.downloadResource/i.test(href)) {
|
||||
// drop the link
|
||||
el.replaceWith(...el.childNodes);
|
||||
}
|
||||
else {
|
||||
let resolvedHref = massageHref(markdown, href, false);
|
||||
if (markdown.baseUri) {
|
||||
resolvedHref = resolveWithBaseUri(URI.from(markdown.baseUri), href);
|
||||
}
|
||||
el.dataset.href = resolvedHref;
|
||||
}
|
||||
}
|
||||
}
|
||||
function createMarkdownRenderer(marked, options, markdown) {
|
||||
const renderer = new marked.Renderer(options.markedOptions);
|
||||
renderer.image = defaultMarkedRenderers.image;
|
||||
renderer.link = defaultMarkedRenderers.link;
|
||||
renderer.paragraph = defaultMarkedRenderers.paragraph;
|
||||
// Will collect [id, renderedElement] tuples
|
||||
const codeBlocks = [];
|
||||
const syncCodeBlocks = [];
|
||||
if (options.codeBlockRendererSync) {
|
||||
renderer.code = ({ text, lang, raw }) => {
|
||||
const id = defaultGenerator.nextId();
|
||||
const value = options.codeBlockRendererSync(postProcessCodeBlockLanguageId(lang), text, raw);
|
||||
syncCodeBlocks.push([id, value]);
|
||||
return `<div class="code" data-code="${id}">${escape(text)}</div>`;
|
||||
};
|
||||
}
|
||||
else if (options.codeBlockRenderer) {
|
||||
renderer.code = ({ text, lang }) => {
|
||||
const id = defaultGenerator.nextId();
|
||||
const value = options.codeBlockRenderer(postProcessCodeBlockLanguageId(lang), text);
|
||||
codeBlocks.push(value.then(element => [id, element]));
|
||||
return `<div class="code" data-code="${id}">${escape(text)}</div>`;
|
||||
};
|
||||
}
|
||||
if (!markdown.supportHtml) {
|
||||
// Note: we always pass the output through dompurify after this so that we don't rely on
|
||||
// marked for real sanitization.
|
||||
renderer.html = ({ text }) => {
|
||||
if (options.sanitizerConfig?.replaceWithPlaintext) {
|
||||
return escape(text);
|
||||
}
|
||||
const match = markdown.isTrusted ? text.match(/^(<span[^>]+>)|(<\/\s*span>)$/) : undefined;
|
||||
return match ? text : '';
|
||||
};
|
||||
}
|
||||
return { renderer, codeBlocks, syncCodeBlocks };
|
||||
}
|
||||
function preprocessMarkdownString(markdown) {
|
||||
let value = markdown.value;
|
||||
// values that are too long will freeze the UI
|
||||
if (value.length > 100_000) {
|
||||
value = `${value.substr(0, 100_000)}…`;
|
||||
}
|
||||
// escape theme icons
|
||||
if (markdown.supportThemeIcons) {
|
||||
value = markdownEscapeEscapedIcons(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function activateLink(mdStr, options, event) {
|
||||
const target = event.target.closest('a[data-href]');
|
||||
if (!DOM.isHTMLElement(target)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let href = target.dataset['href'];
|
||||
if (href) {
|
||||
if (mdStr.baseUri) {
|
||||
href = resolveWithBaseUri(URI.from(mdStr.baseUri), href);
|
||||
}
|
||||
options.actionHandler?.(href, mdStr);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
onUnexpectedError(err);
|
||||
}
|
||||
finally {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
function uriMassage(markdown, part) {
|
||||
let data;
|
||||
try {
|
||||
data = parse(decodeURIComponent(part));
|
||||
}
|
||||
catch (e) {
|
||||
// ignore
|
||||
}
|
||||
if (!data) {
|
||||
return part;
|
||||
}
|
||||
data = cloneAndChange(data, value => {
|
||||
if (markdown.uris && markdown.uris[value]) {
|
||||
return URI.revive(markdown.uris[value]);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
return encodeURIComponent(JSON.stringify(data));
|
||||
}
|
||||
function massageHref(markdown, href, isDomUri) {
|
||||
const data = markdown.uris && markdown.uris[href];
|
||||
let uri = URI.revive(data);
|
||||
if (isDomUri) {
|
||||
if (href.startsWith(Schemas.data + ':')) {
|
||||
return href;
|
||||
}
|
||||
if (!uri) {
|
||||
uri = URI.parse(href);
|
||||
}
|
||||
// this URI will end up as "src"-attribute of a dom node
|
||||
// and because of that special rewriting needs to be done
|
||||
// so that the URI uses a protocol that's understood by
|
||||
// browsers (like http or https)
|
||||
return FileAccess.uriToBrowserUri(uri).toString(true);
|
||||
}
|
||||
if (!uri) {
|
||||
return href;
|
||||
}
|
||||
if (URI.parse(href).toString() === uri.toString()) {
|
||||
return href; // no transformation performed
|
||||
}
|
||||
if (uri.query) {
|
||||
uri = uri.with({ query: uriMassage(markdown, uri.query) });
|
||||
}
|
||||
return uri.toString();
|
||||
}
|
||||
function postProcessCodeBlockLanguageId(lang) {
|
||||
if (!lang) {
|
||||
return '';
|
||||
}
|
||||
const parts = lang.split(/[\s+|:|,|\{|\?]/, 1);
|
||||
if (parts.length) {
|
||||
return parts[0];
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
function resolveWithBaseUri(baseUri, href) {
|
||||
const hasScheme = /^\w[\w\d+.-]*:/.test(href);
|
||||
if (hasScheme) {
|
||||
return href;
|
||||
}
|
||||
if (baseUri.path.endsWith('/')) {
|
||||
return resolvePath(baseUri, href).toString();
|
||||
}
|
||||
else {
|
||||
return resolvePath(dirname(baseUri), href).toString();
|
||||
}
|
||||
}
|
||||
function sanitizeRenderedMarkdown(renderedMarkdown, originalMdStrConfig, options = {}) {
|
||||
const sanitizerConfig = getDomSanitizerConfig(originalMdStrConfig, options);
|
||||
return domSanitize.sanitizeHtml(renderedMarkdown, sanitizerConfig);
|
||||
}
|
||||
export const allowedMarkdownHtmlTags = Object.freeze([
|
||||
...domSanitize.basicMarkupHtmlTags,
|
||||
'input', // Allow inputs for rendering checkboxes. Other types of inputs are removed and the inputs are always disabled
|
||||
]);
|
||||
export const allowedMarkdownHtmlAttributes = Object.freeze([
|
||||
'align',
|
||||
'autoplay',
|
||||
'alt',
|
||||
'colspan',
|
||||
'controls',
|
||||
'draggable',
|
||||
'height',
|
||||
'href',
|
||||
'loop',
|
||||
'muted',
|
||||
'playsinline',
|
||||
'poster',
|
||||
'rowspan',
|
||||
'src',
|
||||
'target',
|
||||
'title',
|
||||
'type',
|
||||
'width',
|
||||
'start',
|
||||
// Input (For disabled inputs)
|
||||
'checked',
|
||||
'disabled',
|
||||
'value',
|
||||
// Custom markdown attributes
|
||||
'data-code',
|
||||
'data-href',
|
||||
// Only allow very specific styles
|
||||
{
|
||||
attributeName: 'style',
|
||||
shouldKeep: (element, data) => {
|
||||
if (element.tagName === 'SPAN') {
|
||||
if (data.attrName === 'style') {
|
||||
return /^(color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z0-9]+)+\));)?(background-color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z0-9]+)+\));)?(border-radius:[0-9]+px;)?$/.test(data.attrValue);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// Only allow codicons for classes
|
||||
{
|
||||
attributeName: 'class',
|
||||
shouldKeep: (element, data) => {
|
||||
if (element.tagName === 'SPAN') {
|
||||
if (data.attrName === 'class') {
|
||||
return /^codicon codicon-[a-z\-]+( codicon-modifier-[a-z\-]+)?$/.test(data.attrValue);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
]);
|
||||
function getDomSanitizerConfig(mdStrConfig, options) {
|
||||
const isTrusted = mdStrConfig.isTrusted ?? false;
|
||||
const allowedLinkSchemes = [
|
||||
Schemas.http,
|
||||
Schemas.https,
|
||||
Schemas.mailto,
|
||||
Schemas.file,
|
||||
Schemas.vscodeFileResource,
|
||||
Schemas.vscodeRemote,
|
||||
Schemas.vscodeRemoteResource,
|
||||
Schemas.vscodeNotebookCell
|
||||
];
|
||||
if (isTrusted) {
|
||||
allowedLinkSchemes.push(Schemas.command);
|
||||
}
|
||||
if (options.allowedLinkSchemes?.augment) {
|
||||
allowedLinkSchemes.push(...options.allowedLinkSchemes.augment);
|
||||
}
|
||||
return {
|
||||
// allowedTags should included everything that markdown renders to.
|
||||
// Since we have our own sanitize function for marked, it's possible we missed some tag so let dompurify make sure.
|
||||
// HTML tags that can result from markdown are from reading https://spec.commonmark.org/0.29/
|
||||
// HTML table tags that can result from markdown are from https://github.github.com/gfm/#tables-extension-
|
||||
allowedTags: {
|
||||
override: options.allowedTags?.override ?? allowedMarkdownHtmlTags
|
||||
},
|
||||
allowedAttributes: {
|
||||
override: options.allowedAttributes?.override ?? allowedMarkdownHtmlAttributes,
|
||||
},
|
||||
allowedLinkProtocols: {
|
||||
override: allowedLinkSchemes,
|
||||
},
|
||||
allowRelativeLinkPaths: !!mdStrConfig.baseUri,
|
||||
allowedMediaProtocols: {
|
||||
override: [
|
||||
Schemas.http,
|
||||
Schemas.https,
|
||||
Schemas.data,
|
||||
Schemas.file,
|
||||
Schemas.vscodeFileResource,
|
||||
Schemas.vscodeRemote,
|
||||
Schemas.vscodeRemoteResource,
|
||||
]
|
||||
},
|
||||
replaceWithPlaintext: options.replaceWithPlaintext,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Renders `str` as plaintext, stripping out Markdown syntax if it's a {@link IMarkdownString}.
|
||||
*
|
||||
* For example `# Header` would be output as `Header`.
|
||||
*/
|
||||
export function renderAsPlaintext(str, options) {
|
||||
if (typeof str === 'string') {
|
||||
return str;
|
||||
}
|
||||
// values that are too long will freeze the UI
|
||||
let value = str.value ?? '';
|
||||
if (value.length > 100_000) {
|
||||
value = `${value.substr(0, 100_000)}…`;
|
||||
}
|
||||
const html = marked.parse(value, { async: false, renderer: options?.includeCodeBlocksFences ? plainTextWithCodeBlocksRenderer.value : plainTextRenderer.value });
|
||||
return sanitizeRenderedMarkdown(html, { isTrusted: false }, {})
|
||||
.toString()
|
||||
.replace(/&(#\d+|[a-zA-Z]+);/g, m => unescapeInfo.get(m) ?? m)
|
||||
.trim();
|
||||
}
|
||||
const unescapeInfo = new Map([
|
||||
['"', '"'],
|
||||
[' ', ' '],
|
||||
['&', '&'],
|
||||
[''', '\''],
|
||||
['<', '<'],
|
||||
['>', '>'],
|
||||
]);
|
||||
function createPlainTextRenderer() {
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.code = ({ text }) => {
|
||||
return escape(text);
|
||||
};
|
||||
renderer.blockquote = ({ text }) => {
|
||||
return text + '\n';
|
||||
};
|
||||
renderer.html = (_) => {
|
||||
return '';
|
||||
};
|
||||
renderer.heading = function ({ tokens }) {
|
||||
return this.parser.parseInline(tokens) + '\n';
|
||||
};
|
||||
renderer.hr = () => {
|
||||
return '';
|
||||
};
|
||||
renderer.list = function ({ items }) {
|
||||
return items.map(x => this.listitem(x)).join('\n') + '\n';
|
||||
};
|
||||
renderer.listitem = ({ text }) => {
|
||||
return text + '\n';
|
||||
};
|
||||
renderer.paragraph = function ({ tokens }) {
|
||||
return this.parser.parseInline(tokens) + '\n';
|
||||
};
|
||||
renderer.table = function ({ header, rows }) {
|
||||
return header.map(cell => this.tablecell(cell)).join(' ') + '\n' + rows.map(cells => cells.map(cell => this.tablecell(cell)).join(' ')).join('\n') + '\n';
|
||||
};
|
||||
renderer.tablerow = ({ text }) => {
|
||||
return text;
|
||||
};
|
||||
renderer.tablecell = function ({ tokens }) {
|
||||
return this.parser.parseInline(tokens);
|
||||
};
|
||||
renderer.strong = ({ text }) => {
|
||||
return text;
|
||||
};
|
||||
renderer.em = ({ text }) => {
|
||||
return text;
|
||||
};
|
||||
renderer.codespan = ({ text }) => {
|
||||
return escape(text);
|
||||
};
|
||||
renderer.br = (_) => {
|
||||
return '\n';
|
||||
};
|
||||
renderer.del = ({ text }) => {
|
||||
return text;
|
||||
};
|
||||
renderer.image = (_) => {
|
||||
return '';
|
||||
};
|
||||
renderer.text = ({ text }) => {
|
||||
return text;
|
||||
};
|
||||
renderer.link = ({ text }) => {
|
||||
return text;
|
||||
};
|
||||
return renderer;
|
||||
}
|
||||
const plainTextRenderer = new Lazy(createPlainTextRenderer);
|
||||
const plainTextWithCodeBlocksRenderer = new Lazy(() => {
|
||||
const renderer = createPlainTextRenderer();
|
||||
renderer.code = ({ text }) => {
|
||||
return `\n\`\`\`\n${escape(text)}\n\`\`\`\n`;
|
||||
};
|
||||
return renderer;
|
||||
});
|
||||
function mergeRawTokenText(tokens) {
|
||||
let mergedTokenText = '';
|
||||
tokens.forEach(token => {
|
||||
mergedTokenText += token.raw;
|
||||
});
|
||||
return mergedTokenText;
|
||||
}
|
||||
function completeSingleLinePattern(token) {
|
||||
if (!token.tokens) {
|
||||
return undefined;
|
||||
}
|
||||
for (let i = token.tokens.length - 1; i >= 0; i--) {
|
||||
const subtoken = token.tokens[i];
|
||||
if (subtoken.type === 'text') {
|
||||
const lines = subtoken.raw.split('\n');
|
||||
const lastLine = lines[lines.length - 1];
|
||||
if (lastLine.includes('`')) {
|
||||
return completeCodespan(token);
|
||||
}
|
||||
else if (lastLine.includes('**')) {
|
||||
return completeDoublestar(token);
|
||||
}
|
||||
else if (lastLine.match(/\*\w/)) {
|
||||
return completeStar(token);
|
||||
}
|
||||
else if (lastLine.match(/(^|\s)__\w/)) {
|
||||
return completeDoubleUnderscore(token);
|
||||
}
|
||||
else if (lastLine.match(/(^|\s)_\w/)) {
|
||||
return completeUnderscore(token);
|
||||
}
|
||||
else if (
|
||||
// Text with start of link target
|
||||
hasLinkTextAndStartOfLinkTarget(lastLine) ||
|
||||
// This token doesn't have the link text, eg if it contains other markdown constructs that are in other subtokens.
|
||||
// But some preceding token does have an unbalanced [ at least
|
||||
hasStartOfLinkTargetAndNoLinkText(lastLine) && token.tokens.slice(0, i).some(t => t.type === 'text' && t.raw.match(/\[[^\]]*$/))) {
|
||||
const nextTwoSubTokens = token.tokens.slice(i + 1);
|
||||
// A markdown link can look like
|
||||
// [link text](https://microsoft.com "more text")
|
||||
// Where "more text" is a title for the link or an argument to a vscode command link
|
||||
if (
|
||||
// If the link was parsed as a link, then look for a link token and a text token with a quote
|
||||
nextTwoSubTokens[0]?.type === 'link' && nextTwoSubTokens[1]?.type === 'text' && nextTwoSubTokens[1].raw.match(/^ *"[^"]*$/) ||
|
||||
// And if the link was not parsed as a link (eg command link), just look for a single quote in this token
|
||||
lastLine.match(/^[^"]* +"[^"]*$/)) {
|
||||
return completeLinkTargetArg(token);
|
||||
}
|
||||
return completeLinkTarget(token);
|
||||
}
|
||||
// Contains the start of link text, and no following tokens contain the link target
|
||||
else if (lastLine.match(/(^|\s)\[\w*[^\]]*$/)) {
|
||||
return completeLinkText(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function hasLinkTextAndStartOfLinkTarget(str) {
|
||||
return !!str.match(/(^|\s)\[.*\]\(\w*/);
|
||||
}
|
||||
function hasStartOfLinkTargetAndNoLinkText(str) {
|
||||
return !!str.match(/^[^\[]*\]\([^\)]*$/);
|
||||
}
|
||||
function completeListItemPattern(list) {
|
||||
// Patch up this one list item
|
||||
const lastListItem = list.items[list.items.length - 1];
|
||||
const lastListSubToken = lastListItem.tokens ? lastListItem.tokens[lastListItem.tokens.length - 1] : undefined;
|
||||
/*
|
||||
Example list token structures:
|
||||
|
||||
list
|
||||
list_item
|
||||
text
|
||||
text
|
||||
codespan
|
||||
link
|
||||
list_item
|
||||
text
|
||||
code // Complete indented codeblock
|
||||
list_item
|
||||
text
|
||||
space
|
||||
text
|
||||
text // Incomplete indented codeblock
|
||||
list_item
|
||||
text
|
||||
list // Nested list
|
||||
list_item
|
||||
text
|
||||
text
|
||||
|
||||
Contrast with paragraph:
|
||||
paragraph
|
||||
text
|
||||
codespan
|
||||
*/
|
||||
const listEndsInHeading = (list) => {
|
||||
// A list item can be rendered as a heading for some reason when it has a subitem where we haven't rendered the text yet like this:
|
||||
// 1. list item
|
||||
// -
|
||||
const lastItem = list.items.at(-1);
|
||||
const lastToken = lastItem?.tokens.at(-1);
|
||||
return lastToken?.type === 'heading' || lastToken?.type === 'list' && listEndsInHeading(lastToken);
|
||||
};
|
||||
let newToken;
|
||||
if (lastListSubToken?.type === 'text' && !('inRawBlock' in lastListItem)) { // Why does Tag have a type of 'text'
|
||||
newToken = completeSingleLinePattern(lastListSubToken);
|
||||
}
|
||||
else if (listEndsInHeading(list)) {
|
||||
const newList = marked.lexer(list.raw.trim() + ' ')[0];
|
||||
if (newList.type !== 'list') {
|
||||
// Something went wrong
|
||||
return;
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
if (!newToken || newToken.type !== 'paragraph') { // 'text' item inside the list item turns into paragraph
|
||||
// Nothing to fix, or not a pattern we were expecting
|
||||
return;
|
||||
}
|
||||
const previousListItemsText = mergeRawTokenText(list.items.slice(0, -1));
|
||||
// Grabbing the `- ` or `1. ` or `* ` off the list item because I can't find a better way to do this
|
||||
const lastListItemLead = lastListItem.raw.match(/^(\s*(-|\d+\.|\*) +)/)?.[0];
|
||||
if (!lastListItemLead) {
|
||||
// Is badly formatted
|
||||
return;
|
||||
}
|
||||
const newListItemText = lastListItemLead +
|
||||
mergeRawTokenText(lastListItem.tokens.slice(0, -1)) +
|
||||
newToken.raw;
|
||||
const newList = marked.lexer(previousListItemsText + newListItemText)[0];
|
||||
if (newList.type !== 'list') {
|
||||
// Something went wrong
|
||||
return;
|
||||
}
|
||||
return newList;
|
||||
}
|
||||
function completeHeading(token, fullRawText) {
|
||||
if (token.raw.match(/-\s*$/)) {
|
||||
return marked.lexer(fullRawText + ' ');
|
||||
}
|
||||
}
|
||||
const maxIncompleteTokensFixRounds = 3;
|
||||
export function fillInIncompleteTokens(tokens) {
|
||||
for (let i = 0; i < maxIncompleteTokensFixRounds; i++) {
|
||||
const newTokens = fillInIncompleteTokensOnce(tokens);
|
||||
if (newTokens) {
|
||||
tokens = newTokens;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
function fillInIncompleteTokensOnce(tokens) {
|
||||
let i;
|
||||
let newTokens;
|
||||
for (i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
if (token.type === 'paragraph' && token.raw.match(/(\n|^)\|/)) {
|
||||
newTokens = completeTable(tokens.slice(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
const lastToken = tokens.at(-1);
|
||||
if (!newTokens && lastToken?.type === 'list') {
|
||||
const newListToken = completeListItemPattern(lastToken);
|
||||
if (newListToken) {
|
||||
newTokens = [newListToken];
|
||||
i = tokens.length - 1;
|
||||
}
|
||||
}
|
||||
if (!newTokens && lastToken?.type === 'paragraph') {
|
||||
// Only operates on a single token, because any newline that follows this should break these patterns
|
||||
const newToken = completeSingleLinePattern(lastToken);
|
||||
if (newToken) {
|
||||
newTokens = [newToken];
|
||||
i = tokens.length - 1;
|
||||
}
|
||||
}
|
||||
if (newTokens) {
|
||||
const newTokensList = [
|
||||
...tokens.slice(0, i),
|
||||
...newTokens
|
||||
];
|
||||
newTokensList.links = tokens.links;
|
||||
return newTokensList;
|
||||
}
|
||||
if (lastToken?.type === 'heading') {
|
||||
const completeTokens = completeHeading(lastToken, mergeRawTokenText(tokens));
|
||||
if (completeTokens) {
|
||||
return completeTokens;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function completeCodespan(token) {
|
||||
return completeWithString(token, '`');
|
||||
}
|
||||
function completeStar(tokens) {
|
||||
return completeWithString(tokens, '*');
|
||||
}
|
||||
function completeUnderscore(tokens) {
|
||||
return completeWithString(tokens, '_');
|
||||
}
|
||||
function completeLinkTarget(tokens) {
|
||||
return completeWithString(tokens, ')', false);
|
||||
}
|
||||
function completeLinkTargetArg(tokens) {
|
||||
return completeWithString(tokens, '")', false);
|
||||
}
|
||||
function completeLinkText(tokens) {
|
||||
return completeWithString(tokens, '](https://microsoft.com)', false);
|
||||
}
|
||||
function completeDoublestar(tokens) {
|
||||
return completeWithString(tokens, '**');
|
||||
}
|
||||
function completeDoubleUnderscore(tokens) {
|
||||
return completeWithString(tokens, '__');
|
||||
}
|
||||
function completeWithString(tokens, closingString, shouldTrim = true) {
|
||||
const mergedRawText = mergeRawTokenText(Array.isArray(tokens) ? tokens : [tokens]);
|
||||
// If it was completed correctly, this should be a single token.
|
||||
// Expecting either a Paragraph or a List
|
||||
const trimmedRawText = shouldTrim ? mergedRawText.trimEnd() : mergedRawText;
|
||||
return marked.lexer(trimmedRawText + closingString)[0];
|
||||
}
|
||||
function completeTable(tokens) {
|
||||
const mergedRawText = mergeRawTokenText(tokens);
|
||||
const lines = mergedRawText.split('\n');
|
||||
let numCols; // The number of line1 col headers
|
||||
let hasSeparatorRow = false;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
if (typeof numCols === 'undefined' && line.match(/^\s*\|/)) {
|
||||
const line1Matches = line.match(/(\|[^\|]+)(?=\||$)/g);
|
||||
if (line1Matches) {
|
||||
numCols = line1Matches.length;
|
||||
}
|
||||
}
|
||||
else if (typeof numCols === 'number') {
|
||||
if (line.match(/^\s*\|/)) {
|
||||
if (i !== lines.length - 1) {
|
||||
// We got the line1 header row, and the line2 separator row, but there are more lines, and it wasn't parsed as a table!
|
||||
// That's strange and means that the table is probably malformed in the source, so I won't try to patch it up.
|
||||
return undefined;
|
||||
}
|
||||
// Got a line2 separator row- partial or complete, doesn't matter, we'll replace it with a correct one
|
||||
hasSeparatorRow = true;
|
||||
}
|
||||
else {
|
||||
// The line after the header row isn't a valid separator row, so the table is malformed, don't fix it up
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof numCols === 'number' && numCols > 0) {
|
||||
const prefixText = hasSeparatorRow ? lines.slice(0, -1).join('\n') : mergedRawText;
|
||||
const line1EndsInPipe = !!prefixText.match(/\|\s*$/);
|
||||
const newRawText = prefixText + (line1EndsInPipe ? '' : '|') + `\n|${' --- |'.repeat(numCols)}`;
|
||||
return marked.lexer(newRawText);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
//# sourceMappingURL=markdownRenderer.js.map
|
||||
File diff suppressed because one or more lines are too long
148
_internal/editor/esm/vs/base/browser/mouseEvent.js
Normal file
148
_internal/editor/esm/vs/base/browser/mouseEvent.js
Normal file
@@ -0,0 +1,148 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as browser from './browser.js';
|
||||
import { IframeUtils } from './iframe.js';
|
||||
import * as platform from '../common/platform.js';
|
||||
export class StandardMouseEvent {
|
||||
constructor(targetWindow, e) {
|
||||
this.timestamp = Date.now();
|
||||
this.browserEvent = e;
|
||||
this.leftButton = e.button === 0;
|
||||
this.middleButton = e.button === 1;
|
||||
this.rightButton = e.button === 2;
|
||||
this.buttons = e.buttons;
|
||||
this.defaultPrevented = e.defaultPrevented;
|
||||
this.target = e.target;
|
||||
this.detail = e.detail || 1;
|
||||
if (e.type === 'dblclick') {
|
||||
this.detail = 2;
|
||||
}
|
||||
this.ctrlKey = e.ctrlKey;
|
||||
this.shiftKey = e.shiftKey;
|
||||
this.altKey = e.altKey;
|
||||
this.metaKey = e.metaKey;
|
||||
if (typeof e.pageX === 'number') {
|
||||
this.posx = e.pageX;
|
||||
this.posy = e.pageY;
|
||||
}
|
||||
else {
|
||||
// Probably hit by MSGestureEvent
|
||||
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.
|
||||
const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(targetWindow, e.view);
|
||||
this.posx -= iframeOffsets.left;
|
||||
this.posy -= iframeOffsets.top;
|
||||
}
|
||||
preventDefault() {
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
stopPropagation() {
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
}
|
||||
export class StandardWheelEvent {
|
||||
constructor(e, deltaX = 0, deltaY = 0) {
|
||||
this.browserEvent = e || null;
|
||||
this.target = e ? (e.target || e.targetNode || e.srcElement) : null;
|
||||
this.deltaY = deltaY;
|
||||
this.deltaX = deltaX;
|
||||
let shouldFactorDPR = false;
|
||||
if (browser.isChrome) {
|
||||
// Chrome version >= 123 contains the fix to factor devicePixelRatio into the wheel event.
|
||||
// See https://chromium.googlesource.com/chromium/src.git/+/be51b448441ff0c9d1f17e0f25c4bf1ab3f11f61
|
||||
const chromeVersionMatch = navigator.userAgent.match(/Chrome\/(\d+)/);
|
||||
const chromeMajorVersion = chromeVersionMatch ? parseInt(chromeVersionMatch[1]) : 123;
|
||||
shouldFactorDPR = chromeMajorVersion <= 122;
|
||||
}
|
||||
if (e) {
|
||||
// Old (deprecated) wheel events
|
||||
const e1 = e;
|
||||
const e2 = e;
|
||||
const devicePixelRatio = e.view?.devicePixelRatio || 1;
|
||||
// vertical delta scroll
|
||||
if (typeof e1.wheelDeltaY !== 'undefined') {
|
||||
if (shouldFactorDPR) {
|
||||
// Refs https://github.com/microsoft/vscode/issues/146403#issuecomment-1854538928
|
||||
this.deltaY = e1.wheelDeltaY / (120 * devicePixelRatio);
|
||||
}
|
||||
else {
|
||||
this.deltaY = e1.wheelDeltaY / 120;
|
||||
}
|
||||
}
|
||||
else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {
|
||||
this.deltaY = -e2.detail / 3;
|
||||
}
|
||||
else if (e.type === 'wheel') {
|
||||
// Modern wheel event
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent
|
||||
const ev = e;
|
||||
if (ev.deltaMode === ev.DOM_DELTA_LINE) {
|
||||
// the deltas are expressed in lines
|
||||
if (browser.isFirefox && !platform.isMacintosh) {
|
||||
this.deltaY = -e.deltaY / 3;
|
||||
}
|
||||
else {
|
||||
this.deltaY = -e.deltaY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.deltaY = -e.deltaY / 40;
|
||||
}
|
||||
}
|
||||
// horizontal delta scroll
|
||||
if (typeof e1.wheelDeltaX !== 'undefined') {
|
||||
if (browser.isSafari && platform.isWindows) {
|
||||
this.deltaX = -(e1.wheelDeltaX / 120);
|
||||
}
|
||||
else if (shouldFactorDPR) {
|
||||
// Refs https://github.com/microsoft/vscode/issues/146403#issuecomment-1854538928
|
||||
this.deltaX = e1.wheelDeltaX / (120 * devicePixelRatio);
|
||||
}
|
||||
else {
|
||||
this.deltaX = e1.wheelDeltaX / 120;
|
||||
}
|
||||
}
|
||||
else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {
|
||||
this.deltaX = -e.detail / 3;
|
||||
}
|
||||
else if (e.type === 'wheel') {
|
||||
// Modern wheel event
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent
|
||||
const ev = e;
|
||||
if (ev.deltaMode === ev.DOM_DELTA_LINE) {
|
||||
// the deltas are expressed in lines
|
||||
if (browser.isFirefox && !platform.isMacintosh) {
|
||||
this.deltaX = -e.deltaX / 3;
|
||||
}
|
||||
else {
|
||||
this.deltaX = -e.deltaX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.deltaX = -e.deltaX / 40;
|
||||
}
|
||||
}
|
||||
// Assume a vertical scroll if nothing else worked
|
||||
if (this.deltaY === 0 && this.deltaX === 0 && e.wheelDelta) {
|
||||
if (shouldFactorDPR) {
|
||||
// Refs https://github.com/microsoft/vscode/issues/146403#issuecomment-1854538928
|
||||
this.deltaY = e.wheelDelta / (120 * devicePixelRatio);
|
||||
}
|
||||
else {
|
||||
this.deltaY = e.wheelDelta / 120;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
preventDefault() {
|
||||
this.browserEvent?.preventDefault();
|
||||
}
|
||||
stopPropagation() {
|
||||
this.browserEvent?.stopPropagation();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=mouseEvent.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/mouseEvent.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/mouseEvent.js.map
Normal file
File diff suppressed because one or more lines are too long
221
_internal/editor/esm/vs/base/browser/performance.js
Normal file
221
_internal/editor/esm/vs/base/browser/performance.js
Normal file
@@ -0,0 +1,221 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export var inputLatency;
|
||||
(function (inputLatency) {
|
||||
const totalKeydownTime = { total: 0, min: Number.MAX_VALUE, max: 0 };
|
||||
const totalInputTime = { ...totalKeydownTime };
|
||||
const totalRenderTime = { ...totalKeydownTime };
|
||||
const totalInputLatencyTime = { ...totalKeydownTime };
|
||||
let measurementsCount = 0;
|
||||
const state = {
|
||||
keydown: 0 /* EventPhase.Before */,
|
||||
input: 0 /* EventPhase.Before */,
|
||||
render: 0 /* EventPhase.Before */,
|
||||
};
|
||||
/**
|
||||
* Record the start of the keydown event.
|
||||
*/
|
||||
function onKeyDown() {
|
||||
/** Direct Check C. See explanation in {@link recordIfFinished} */
|
||||
recordIfFinished();
|
||||
performance.mark('inputlatency/start');
|
||||
performance.mark('keydown/start');
|
||||
state.keydown = 1 /* EventPhase.InProgress */;
|
||||
queueMicrotask(markKeyDownEnd);
|
||||
}
|
||||
inputLatency.onKeyDown = onKeyDown;
|
||||
/**
|
||||
* Mark the end of the keydown event.
|
||||
*/
|
||||
function markKeyDownEnd() {
|
||||
if (state.keydown === 1 /* EventPhase.InProgress */) {
|
||||
performance.mark('keydown/end');
|
||||
state.keydown = 2 /* EventPhase.Finished */;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Record the start of the beforeinput event.
|
||||
*/
|
||||
function onBeforeInput() {
|
||||
performance.mark('input/start');
|
||||
state.input = 1 /* EventPhase.InProgress */;
|
||||
/** Schedule Task A. See explanation in {@link recordIfFinished} */
|
||||
scheduleRecordIfFinishedTask();
|
||||
}
|
||||
inputLatency.onBeforeInput = onBeforeInput;
|
||||
/**
|
||||
* Record the start of the input event.
|
||||
*/
|
||||
function onInput() {
|
||||
if (state.input === 0 /* EventPhase.Before */) {
|
||||
// it looks like we didn't receive a `beforeinput`
|
||||
onBeforeInput();
|
||||
}
|
||||
queueMicrotask(markInputEnd);
|
||||
}
|
||||
inputLatency.onInput = onInput;
|
||||
function markInputEnd() {
|
||||
if (state.input === 1 /* EventPhase.InProgress */) {
|
||||
performance.mark('input/end');
|
||||
state.input = 2 /* EventPhase.Finished */;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Record the start of the keyup event.
|
||||
*/
|
||||
function onKeyUp() {
|
||||
/** Direct Check D. See explanation in {@link recordIfFinished} */
|
||||
recordIfFinished();
|
||||
}
|
||||
inputLatency.onKeyUp = onKeyUp;
|
||||
/**
|
||||
* Record the start of the selectionchange event.
|
||||
*/
|
||||
function onSelectionChange() {
|
||||
/** Direct Check E. See explanation in {@link recordIfFinished} */
|
||||
recordIfFinished();
|
||||
}
|
||||
inputLatency.onSelectionChange = onSelectionChange;
|
||||
/**
|
||||
* Record the start of the animation frame performing the rendering.
|
||||
*/
|
||||
function onRenderStart() {
|
||||
// Render may be triggered during input, but we only measure the following animation frame
|
||||
if (state.keydown === 2 /* EventPhase.Finished */ && state.input === 2 /* EventPhase.Finished */ && state.render === 0 /* EventPhase.Before */) {
|
||||
// Only measure the first render after keyboard input
|
||||
performance.mark('render/start');
|
||||
state.render = 1 /* EventPhase.InProgress */;
|
||||
queueMicrotask(markRenderEnd);
|
||||
/** Schedule Task B. See explanation in {@link recordIfFinished} */
|
||||
scheduleRecordIfFinishedTask();
|
||||
}
|
||||
}
|
||||
inputLatency.onRenderStart = onRenderStart;
|
||||
/**
|
||||
* Mark the end of the animation frame performing the rendering.
|
||||
*/
|
||||
function markRenderEnd() {
|
||||
if (state.render === 1 /* EventPhase.InProgress */) {
|
||||
performance.mark('render/end');
|
||||
state.render = 2 /* EventPhase.Finished */;
|
||||
}
|
||||
}
|
||||
function scheduleRecordIfFinishedTask() {
|
||||
// Here we can safely assume that the `setTimeout` will not be
|
||||
// artificially delayed by 4ms because we schedule it from
|
||||
// event handlers
|
||||
setTimeout(recordIfFinished);
|
||||
}
|
||||
/**
|
||||
* Record the input latency sample if input handling and rendering are finished.
|
||||
*
|
||||
* The challenge here is that we want to record the latency in such a way that it includes
|
||||
* also the layout and painting work the browser does during the animation frame task.
|
||||
*
|
||||
* Simply scheduling a new task (via `setTimeout`) from the animation frame task would
|
||||
* schedule the new task at the end of the task queue (after other code that uses `setTimeout`),
|
||||
* so we need to use multiple strategies to make sure our task runs before others:
|
||||
*
|
||||
* We schedule tasks (A and B):
|
||||
* - we schedule a task A (via a `setTimeout` call) when the input starts in `markInputStart`.
|
||||
* If the animation frame task is scheduled quickly by the browser, then task A has a very good
|
||||
* chance of being the very first task after the animation frame and thus will record the input latency.
|
||||
* - however, if the animation frame task is scheduled a bit later, then task A might execute
|
||||
* before the animation frame task. We therefore schedule another task B from `markRenderStart`.
|
||||
*
|
||||
* We do direct checks in browser event handlers (C, D, E):
|
||||
* - if the browser has multiple keydown events queued up, they will be scheduled before the `setTimeout` tasks,
|
||||
* so we do a direct check in the keydown event handler (C).
|
||||
* - depending on timing, sometimes the animation frame is scheduled even before the `keyup` event, so we
|
||||
* do a direct check there too (E).
|
||||
* - the browser oftentimes emits a `selectionchange` event after an `input`, so we do a direct check there (D).
|
||||
*/
|
||||
function recordIfFinished() {
|
||||
if (state.keydown === 2 /* EventPhase.Finished */ && state.input === 2 /* EventPhase.Finished */ && state.render === 2 /* EventPhase.Finished */) {
|
||||
performance.mark('inputlatency/end');
|
||||
performance.measure('keydown', 'keydown/start', 'keydown/end');
|
||||
performance.measure('input', 'input/start', 'input/end');
|
||||
performance.measure('render', 'render/start', 'render/end');
|
||||
performance.measure('inputlatency', 'inputlatency/start', 'inputlatency/end');
|
||||
addMeasure('keydown', totalKeydownTime);
|
||||
addMeasure('input', totalInputTime);
|
||||
addMeasure('render', totalRenderTime);
|
||||
addMeasure('inputlatency', totalInputLatencyTime);
|
||||
// console.info(
|
||||
// `input latency=${performance.getEntriesByName('inputlatency')[0].duration.toFixed(1)} [` +
|
||||
// `keydown=${performance.getEntriesByName('keydown')[0].duration.toFixed(1)}, ` +
|
||||
// `input=${performance.getEntriesByName('input')[0].duration.toFixed(1)}, ` +
|
||||
// `render=${performance.getEntriesByName('render')[0].duration.toFixed(1)}` +
|
||||
// `]`
|
||||
// );
|
||||
measurementsCount++;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
function addMeasure(entryName, cumulativeMeasurement) {
|
||||
const duration = performance.getEntriesByName(entryName)[0].duration;
|
||||
cumulativeMeasurement.total += duration;
|
||||
cumulativeMeasurement.min = Math.min(cumulativeMeasurement.min, duration);
|
||||
cumulativeMeasurement.max = Math.max(cumulativeMeasurement.max, duration);
|
||||
}
|
||||
/**
|
||||
* Clear the current sample.
|
||||
*/
|
||||
function reset() {
|
||||
performance.clearMarks('keydown/start');
|
||||
performance.clearMarks('keydown/end');
|
||||
performance.clearMarks('input/start');
|
||||
performance.clearMarks('input/end');
|
||||
performance.clearMarks('render/start');
|
||||
performance.clearMarks('render/end');
|
||||
performance.clearMarks('inputlatency/start');
|
||||
performance.clearMarks('inputlatency/end');
|
||||
performance.clearMeasures('keydown');
|
||||
performance.clearMeasures('input');
|
||||
performance.clearMeasures('render');
|
||||
performance.clearMeasures('inputlatency');
|
||||
state.keydown = 0 /* EventPhase.Before */;
|
||||
state.input = 0 /* EventPhase.Before */;
|
||||
state.render = 0 /* EventPhase.Before */;
|
||||
}
|
||||
/**
|
||||
* Gets all input latency samples and clears the internal buffers to start recording a new set
|
||||
* of samples.
|
||||
*/
|
||||
function getAndClearMeasurements() {
|
||||
if (measurementsCount === 0) {
|
||||
return undefined;
|
||||
}
|
||||
// Assemble the result
|
||||
const result = {
|
||||
keydown: cumulativeToFinalMeasurement(totalKeydownTime),
|
||||
input: cumulativeToFinalMeasurement(totalInputTime),
|
||||
render: cumulativeToFinalMeasurement(totalRenderTime),
|
||||
total: cumulativeToFinalMeasurement(totalInputLatencyTime),
|
||||
sampleCount: measurementsCount
|
||||
};
|
||||
// Clear the cumulative measurements
|
||||
clearCumulativeMeasurement(totalKeydownTime);
|
||||
clearCumulativeMeasurement(totalInputTime);
|
||||
clearCumulativeMeasurement(totalRenderTime);
|
||||
clearCumulativeMeasurement(totalInputLatencyTime);
|
||||
measurementsCount = 0;
|
||||
return result;
|
||||
}
|
||||
inputLatency.getAndClearMeasurements = getAndClearMeasurements;
|
||||
function cumulativeToFinalMeasurement(cumulative) {
|
||||
return {
|
||||
average: cumulative.total / measurementsCount,
|
||||
max: cumulative.max,
|
||||
min: cumulative.min,
|
||||
};
|
||||
}
|
||||
function clearCumulativeMeasurement(cumulative) {
|
||||
cumulative.total = 0;
|
||||
cumulative.min = Number.MAX_VALUE;
|
||||
cumulative.max = 0;
|
||||
}
|
||||
})(inputLatency || (inputLatency = {}));
|
||||
//# sourceMappingURL=performance.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/performance.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/performance.js.map
Normal file
File diff suppressed because one or more lines are too long
86
_internal/editor/esm/vs/base/browser/pixelRatio.js
Normal file
86
_internal/editor/esm/vs/base/browser/pixelRatio.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { getWindowId, onDidUnregisterWindow } from './dom.js';
|
||||
import { Emitter, Event } from '../common/event.js';
|
||||
import { Disposable, markAsSingleton } from '../common/lifecycle.js';
|
||||
/**
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#monitoring_screen_resolution_or_zoom_level_changes
|
||||
*/
|
||||
class DevicePixelRatioMonitor extends Disposable {
|
||||
constructor(targetWindow) {
|
||||
super();
|
||||
this._onDidChange = this._register(new Emitter());
|
||||
this.onDidChange = this._onDidChange.event;
|
||||
this._listener = () => this._handleChange(targetWindow, true);
|
||||
this._mediaQueryList = null;
|
||||
this._handleChange(targetWindow, false);
|
||||
}
|
||||
_handleChange(targetWindow, fireEvent) {
|
||||
this._mediaQueryList?.removeEventListener('change', this._listener);
|
||||
this._mediaQueryList = targetWindow.matchMedia(`(resolution: ${targetWindow.devicePixelRatio}dppx)`);
|
||||
this._mediaQueryList.addEventListener('change', this._listener);
|
||||
if (fireEvent) {
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
}
|
||||
}
|
||||
class PixelRatioMonitorImpl extends Disposable {
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
constructor(targetWindow) {
|
||||
super();
|
||||
this._onDidChange = this._register(new Emitter());
|
||||
this.onDidChange = this._onDidChange.event;
|
||||
this._value = this._getPixelRatio(targetWindow);
|
||||
const dprMonitor = this._register(new DevicePixelRatioMonitor(targetWindow));
|
||||
this._register(dprMonitor.onDidChange(() => {
|
||||
this._value = this._getPixelRatio(targetWindow);
|
||||
this._onDidChange.fire(this._value);
|
||||
}));
|
||||
}
|
||||
_getPixelRatio(targetWindow) {
|
||||
const ctx = document.createElement('canvas').getContext('2d');
|
||||
const dpr = targetWindow.devicePixelRatio || 1;
|
||||
const bsr = ctx.webkitBackingStorePixelRatio ||
|
||||
ctx.mozBackingStorePixelRatio ||
|
||||
ctx.msBackingStorePixelRatio ||
|
||||
ctx.oBackingStorePixelRatio ||
|
||||
ctx.backingStorePixelRatio || 1;
|
||||
return dpr / bsr;
|
||||
}
|
||||
}
|
||||
class PixelRatioMonitorFacade {
|
||||
constructor() {
|
||||
this.mapWindowIdToPixelRatioMonitor = new Map();
|
||||
}
|
||||
_getOrCreatePixelRatioMonitor(targetWindow) {
|
||||
const targetWindowId = getWindowId(targetWindow);
|
||||
let pixelRatioMonitor = this.mapWindowIdToPixelRatioMonitor.get(targetWindowId);
|
||||
if (!pixelRatioMonitor) {
|
||||
pixelRatioMonitor = markAsSingleton(new PixelRatioMonitorImpl(targetWindow));
|
||||
this.mapWindowIdToPixelRatioMonitor.set(targetWindowId, pixelRatioMonitor);
|
||||
markAsSingleton(Event.once(onDidUnregisterWindow)(({ vscodeWindowId }) => {
|
||||
if (vscodeWindowId === targetWindowId) {
|
||||
pixelRatioMonitor?.dispose();
|
||||
this.mapWindowIdToPixelRatioMonitor.delete(targetWindowId);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return pixelRatioMonitor;
|
||||
}
|
||||
getInstance(targetWindow) {
|
||||
return this._getOrCreatePixelRatioMonitor(targetWindow);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the pixel ratio.
|
||||
*
|
||||
* This is useful for rendering <canvas> elements at native screen resolution or for being used as
|
||||
* a cache key when storing font measurements. Fonts might render differently depending on resolution
|
||||
* and any measurements need to be discarded for example when a window is moved from a monitor to another.
|
||||
*/
|
||||
export const PixelRatio = new PixelRatioMonitorFacade();
|
||||
//# sourceMappingURL=pixelRatio.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/pixelRatio.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/pixelRatio.js.map
Normal file
File diff suppressed because one or more lines are too long
268
_internal/editor/esm/vs/base/browser/touch.js
Normal file
268
_internal/editor/esm/vs/base/browser/touch.js
Normal file
@@ -0,0 +1,268 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
import * as DomUtils from './dom.js';
|
||||
import { mainWindow } from './window.js';
|
||||
import { memoize } from '../common/decorators.js';
|
||||
import { Event as EventUtils } from '../common/event.js';
|
||||
import { Disposable, markAsSingleton, toDisposable } from '../common/lifecycle.js';
|
||||
import { LinkedList } from '../common/linkedList.js';
|
||||
export var EventType;
|
||||
(function (EventType) {
|
||||
EventType.Tap = '-monaco-gesturetap';
|
||||
EventType.Change = '-monaco-gesturechange';
|
||||
EventType.Start = '-monaco-gesturestart';
|
||||
EventType.End = '-monaco-gesturesend';
|
||||
EventType.Contextmenu = '-monaco-gesturecontextmenu';
|
||||
})(EventType || (EventType = {}));
|
||||
export class Gesture extends Disposable {
|
||||
static { this.SCROLL_FRICTION = -0.005; }
|
||||
static { this.HOLD_DELAY = 700; }
|
||||
static { this.CLEAR_TAP_COUNT_TIME = 400; } // ms
|
||||
constructor() {
|
||||
super();
|
||||
this.dispatched = false;
|
||||
this.targets = new LinkedList();
|
||||
this.ignoreTargets = new LinkedList();
|
||||
this.activeTouches = {};
|
||||
this.handle = null;
|
||||
this._lastSetTapCountTime = 0;
|
||||
this._register(EventUtils.runAndSubscribe(DomUtils.onDidRegisterWindow, ({ window, disposables }) => {
|
||||
disposables.add(DomUtils.addDisposableListener(window.document, 'touchstart', (e) => this.onTouchStart(e), { passive: false }));
|
||||
disposables.add(DomUtils.addDisposableListener(window.document, 'touchend', (e) => this.onTouchEnd(window, e)));
|
||||
disposables.add(DomUtils.addDisposableListener(window.document, 'touchmove', (e) => this.onTouchMove(e), { passive: false }));
|
||||
}, { window: mainWindow, disposables: this._store }));
|
||||
}
|
||||
static addTarget(element) {
|
||||
if (!Gesture.isTouchDevice()) {
|
||||
return Disposable.None;
|
||||
}
|
||||
if (!Gesture.INSTANCE) {
|
||||
Gesture.INSTANCE = markAsSingleton(new Gesture());
|
||||
}
|
||||
const remove = Gesture.INSTANCE.targets.push(element);
|
||||
return toDisposable(remove);
|
||||
}
|
||||
static ignoreTarget(element) {
|
||||
if (!Gesture.isTouchDevice()) {
|
||||
return Disposable.None;
|
||||
}
|
||||
if (!Gesture.INSTANCE) {
|
||||
Gesture.INSTANCE = markAsSingleton(new Gesture());
|
||||
}
|
||||
const remove = Gesture.INSTANCE.ignoreTargets.push(element);
|
||||
return toDisposable(remove);
|
||||
}
|
||||
static isTouchDevice() {
|
||||
// `'ontouchstart' in window` always evaluates to true with typescript's modern typings. This causes `window` to be
|
||||
// `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast
|
||||
return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;
|
||||
}
|
||||
dispose() {
|
||||
if (this.handle) {
|
||||
this.handle.dispose();
|
||||
this.handle = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
onTouchStart(e) {
|
||||
const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based.
|
||||
if (this.handle) {
|
||||
this.handle.dispose();
|
||||
this.handle = null;
|
||||
}
|
||||
for (let i = 0, len = e.targetTouches.length; i < len; i++) {
|
||||
const touch = e.targetTouches.item(i);
|
||||
this.activeTouches[touch.identifier] = {
|
||||
id: touch.identifier,
|
||||
initialTarget: touch.target,
|
||||
initialTimeStamp: timestamp,
|
||||
initialPageX: touch.pageX,
|
||||
initialPageY: touch.pageY,
|
||||
rollingTimestamps: [timestamp],
|
||||
rollingPageX: [touch.pageX],
|
||||
rollingPageY: [touch.pageY]
|
||||
};
|
||||
const evt = this.newGestureEvent(EventType.Start, touch.target);
|
||||
evt.pageX = touch.pageX;
|
||||
evt.pageY = touch.pageY;
|
||||
this.dispatchEvent(evt);
|
||||
}
|
||||
if (this.dispatched) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.dispatched = false;
|
||||
}
|
||||
}
|
||||
onTouchEnd(targetWindow, e) {
|
||||
const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based.
|
||||
const activeTouchCount = Object.keys(this.activeTouches).length;
|
||||
for (let i = 0, len = e.changedTouches.length; i < len; i++) {
|
||||
const touch = e.changedTouches.item(i);
|
||||
if (!this.activeTouches.hasOwnProperty(String(touch.identifier))) {
|
||||
console.warn('move of an UNKNOWN touch', touch);
|
||||
continue;
|
||||
}
|
||||
const data = this.activeTouches[touch.identifier], holdTime = Date.now() - data.initialTimeStamp;
|
||||
if (holdTime < Gesture.HOLD_DELAY
|
||||
&& Math.abs(data.initialPageX - data.rollingPageX.at(-1)) < 30
|
||||
&& Math.abs(data.initialPageY - data.rollingPageY.at(-1)) < 30) {
|
||||
const evt = this.newGestureEvent(EventType.Tap, data.initialTarget);
|
||||
evt.pageX = data.rollingPageX.at(-1);
|
||||
evt.pageY = data.rollingPageY.at(-1);
|
||||
this.dispatchEvent(evt);
|
||||
}
|
||||
else if (holdTime >= Gesture.HOLD_DELAY
|
||||
&& Math.abs(data.initialPageX - data.rollingPageX.at(-1)) < 30
|
||||
&& Math.abs(data.initialPageY - data.rollingPageY.at(-1)) < 30) {
|
||||
const evt = this.newGestureEvent(EventType.Contextmenu, data.initialTarget);
|
||||
evt.pageX = data.rollingPageX.at(-1);
|
||||
evt.pageY = data.rollingPageY.at(-1);
|
||||
this.dispatchEvent(evt);
|
||||
}
|
||||
else if (activeTouchCount === 1) {
|
||||
const finalX = data.rollingPageX.at(-1);
|
||||
const finalY = data.rollingPageY.at(-1);
|
||||
const deltaT = data.rollingTimestamps.at(-1) - data.rollingTimestamps[0];
|
||||
const deltaX = finalX - data.rollingPageX[0];
|
||||
const deltaY = finalY - data.rollingPageY[0];
|
||||
// We need to get all the dispatch targets on the start of the inertia event
|
||||
const dispatchTo = [...this.targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));
|
||||
this.inertia(targetWindow, dispatchTo, timestamp, // time now
|
||||
Math.abs(deltaX) / deltaT, // speed
|
||||
deltaX > 0 ? 1 : -1, // x direction
|
||||
finalX, // x now
|
||||
Math.abs(deltaY) / deltaT, // y speed
|
||||
deltaY > 0 ? 1 : -1, // y direction
|
||||
finalY // y now
|
||||
);
|
||||
}
|
||||
this.dispatchEvent(this.newGestureEvent(EventType.End, data.initialTarget));
|
||||
// forget about this touch
|
||||
delete this.activeTouches[touch.identifier];
|
||||
}
|
||||
if (this.dispatched) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.dispatched = false;
|
||||
}
|
||||
}
|
||||
newGestureEvent(type, initialTarget) {
|
||||
const event = document.createEvent('CustomEvent');
|
||||
event.initEvent(type, false, true);
|
||||
event.initialTarget = initialTarget;
|
||||
event.tapCount = 0;
|
||||
return event;
|
||||
}
|
||||
dispatchEvent(event) {
|
||||
if (event.type === EventType.Tap) {
|
||||
const currentTime = (new Date()).getTime();
|
||||
let setTapCount = 0;
|
||||
if (currentTime - this._lastSetTapCountTime > Gesture.CLEAR_TAP_COUNT_TIME) {
|
||||
setTapCount = 1;
|
||||
}
|
||||
else {
|
||||
setTapCount = 2;
|
||||
}
|
||||
this._lastSetTapCountTime = currentTime;
|
||||
event.tapCount = setTapCount;
|
||||
}
|
||||
else if (event.type === EventType.Change || event.type === EventType.Contextmenu) {
|
||||
// tap is canceled by scrolling or context menu
|
||||
this._lastSetTapCountTime = 0;
|
||||
}
|
||||
if (event.initialTarget instanceof Node) {
|
||||
for (const ignoreTarget of this.ignoreTargets) {
|
||||
if (ignoreTarget.contains(event.initialTarget)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const targets = [];
|
||||
for (const target of this.targets) {
|
||||
if (target.contains(event.initialTarget)) {
|
||||
let depth = 0;
|
||||
let now = event.initialTarget;
|
||||
while (now && now !== target) {
|
||||
depth++;
|
||||
now = now.parentElement;
|
||||
}
|
||||
targets.push([depth, target]);
|
||||
}
|
||||
}
|
||||
targets.sort((a, b) => a[0] - b[0]);
|
||||
for (const [_, target] of targets) {
|
||||
target.dispatchEvent(event);
|
||||
this.dispatched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
inertia(targetWindow, dispatchTo, t1, vX, dirX, x, vY, dirY, y) {
|
||||
this.handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {
|
||||
const now = Date.now();
|
||||
// velocity: old speed + accel_over_time
|
||||
const deltaT = now - t1;
|
||||
let delta_pos_x = 0, delta_pos_y = 0;
|
||||
let stopped = true;
|
||||
vX += Gesture.SCROLL_FRICTION * deltaT;
|
||||
vY += Gesture.SCROLL_FRICTION * deltaT;
|
||||
if (vX > 0) {
|
||||
stopped = false;
|
||||
delta_pos_x = dirX * vX * deltaT;
|
||||
}
|
||||
if (vY > 0) {
|
||||
stopped = false;
|
||||
delta_pos_y = dirY * vY * deltaT;
|
||||
}
|
||||
// dispatch translation event
|
||||
const evt = this.newGestureEvent(EventType.Change);
|
||||
evt.translationX = delta_pos_x;
|
||||
evt.translationY = delta_pos_y;
|
||||
dispatchTo.forEach(d => d.dispatchEvent(evt));
|
||||
if (!stopped) {
|
||||
this.inertia(targetWindow, dispatchTo, now, vX, dirX, x + delta_pos_x, vY, dirY, y + delta_pos_y);
|
||||
}
|
||||
});
|
||||
}
|
||||
onTouchMove(e) {
|
||||
const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based.
|
||||
for (let i = 0, len = e.changedTouches.length; i < len; i++) {
|
||||
const touch = e.changedTouches.item(i);
|
||||
if (!this.activeTouches.hasOwnProperty(String(touch.identifier))) {
|
||||
console.warn('end of an UNKNOWN touch', touch);
|
||||
continue;
|
||||
}
|
||||
const data = this.activeTouches[touch.identifier];
|
||||
const evt = this.newGestureEvent(EventType.Change, data.initialTarget);
|
||||
evt.translationX = touch.pageX - data.rollingPageX.at(-1);
|
||||
evt.translationY = touch.pageY - data.rollingPageY.at(-1);
|
||||
evt.pageX = touch.pageX;
|
||||
evt.pageY = touch.pageY;
|
||||
this.dispatchEvent(evt);
|
||||
// only keep a few data points, to average the final speed
|
||||
if (data.rollingPageX.length > 3) {
|
||||
data.rollingPageX.shift();
|
||||
data.rollingPageY.shift();
|
||||
data.rollingTimestamps.shift();
|
||||
}
|
||||
data.rollingPageX.push(touch.pageX);
|
||||
data.rollingPageY.push(touch.pageY);
|
||||
data.rollingTimestamps.push(timestamp);
|
||||
}
|
||||
if (this.dispatched) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.dispatched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
memoize
|
||||
], Gesture, "isTouchDevice", null);
|
||||
//# sourceMappingURL=touch.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/touch.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/touch.js.map
Normal file
File diff suppressed because one or more lines are too long
25
_internal/editor/esm/vs/base/browser/trustedTypes.js
Normal file
25
_internal/editor/esm/vs/base/browser/trustedTypes.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { onUnexpectedError } from '../common/errors.js';
|
||||
export function createTrustedTypesPolicy(policyName, policyOptions) {
|
||||
const monacoEnvironment = globalThis.MonacoEnvironment;
|
||||
if (monacoEnvironment?.createTrustedTypesPolicy) {
|
||||
try {
|
||||
return monacoEnvironment.createTrustedTypesPolicy(policyName, policyOptions);
|
||||
}
|
||||
catch (err) {
|
||||
onUnexpectedError(err);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
try {
|
||||
return globalThis.trustedTypes?.createPolicy(policyName, policyOptions);
|
||||
}
|
||||
catch (err) {
|
||||
onUnexpectedError(err);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=trustedTypes.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/trustedTypes.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/trustedTypes.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/trustedTypes.ts","vs/base/browser/trustedTypes.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,UAAU,wBAAwB,CACvC,UAAkB,EAClB,aAAuB;IASvB,MAAM,iBAAiB,GAAoC,UAAkB,CAAC,iBAAiB,CAAC;IAEhG,IAAI,iBAAiB,EAAE,wBAAwB,EAAE,CAAC;QACjD,IAAI,CAAC;YACJ,OAAO,iBAAiB,CAAC,wBAAwB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,iBAAiB,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IACD,IAAI,CAAC;QACJ,OAAQ,UAAkB,CAAC,YAAY,EAAE,YAAY,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAClF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC","file":"trustedTypes.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { onUnexpectedError } from '../common/errors.js';\n\nexport function createTrustedTypesPolicy<Options extends TrustedTypePolicyOptions>(\n\tpolicyName: string,\n\tpolicyOptions?: Options,\n): undefined | Pick<TrustedTypePolicy<Options>, 'name' | Extract<keyof Options, keyof TrustedTypePolicyOptions>> {\n\n\tinterface IMonacoEnvironment {\n\t\tcreateTrustedTypesPolicy<Options extends TrustedTypePolicyOptions>(\n\t\t\tpolicyName: string,\n\t\t\tpolicyOptions?: Options,\n\t\t): undefined | Pick<TrustedTypePolicy<Options>, 'name' | Extract<keyof Options, keyof TrustedTypePolicyOptions>>;\n\t}\n\tconst monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment;\n\n\tif (monacoEnvironment?.createTrustedTypesPolicy) {\n\t\ttry {\n\t\t\treturn monacoEnvironment.createTrustedTypesPolicy(policyName, policyOptions);\n\t\t} catch (err) {\n\t\t\tonUnexpectedError(err);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\ttry {\n\t\treturn (globalThis as any).trustedTypes?.createPolicy(policyName, policyOptions);\n\t} catch (err) {\n\t\tonUnexpectedError(err);\n\t\treturn undefined;\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { onUnexpectedError } from '../common/errors.js';\n\nexport function createTrustedTypesPolicy<Options extends TrustedTypePolicyOptions>(\n\tpolicyName: string,\n\tpolicyOptions?: Options,\n): undefined | Pick<TrustedTypePolicy<Options>, 'name' | Extract<keyof Options, keyof TrustedTypePolicyOptions>> {\n\n\tinterface IMonacoEnvironment {\n\t\tcreateTrustedTypesPolicy<Options extends TrustedTypePolicyOptions>(\n\t\t\tpolicyName: string,\n\t\t\tpolicyOptions?: Options,\n\t\t): undefined | Pick<TrustedTypePolicy<Options>, 'name' | Extract<keyof Options, keyof TrustedTypePolicyOptions>>;\n\t}\n\tconst monacoEnvironment: IMonacoEnvironment | undefined = (globalThis as any).MonacoEnvironment;\n\n\tif (monacoEnvironment?.createTrustedTypesPolicy) {\n\t\ttry {\n\t\t\treturn monacoEnvironment.createTrustedTypesPolicy(policyName, policyOptions);\n\t\t} catch (err) {\n\t\t\tonUnexpectedError(err);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\ttry {\n\t\treturn (globalThis as any).trustedTypes?.createPolicy(policyName, policyOptions);\n\t} catch (err) {\n\t\tonUnexpectedError(err);\n\t\treturn undefined;\n\t}\n}\n"]}
|
||||
@@ -0,0 +1,374 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { isFirefox } from '../../browser.js';
|
||||
import { DataTransfers } from '../../dnd.js';
|
||||
import { addDisposableListener, EventHelper, EventType } from '../../dom.js';
|
||||
import { EventType as TouchEventType, Gesture } from '../../touch.js';
|
||||
import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
import { SelectBox } from '../selectBox/selectBox.js';
|
||||
import { Action, ActionRunner, Separator } from '../../../common/actions.js';
|
||||
import { Disposable } from '../../../common/lifecycle.js';
|
||||
import * as platform from '../../../common/platform.js';
|
||||
import * as types from '../../../common/types.js';
|
||||
import './actionbar.css';
|
||||
import * as nls from '../../../../nls.js';
|
||||
import { getBaseLayerHoverDelegate } from '../hover/hoverDelegate2.js';
|
||||
export class BaseActionViewItem extends Disposable {
|
||||
get action() {
|
||||
return this._action;
|
||||
}
|
||||
constructor(context, action, options = {}) {
|
||||
super();
|
||||
this.options = options;
|
||||
this._context = context || this;
|
||||
this._action = action;
|
||||
if (action instanceof Action) {
|
||||
this._register(action.onDidChange(event => {
|
||||
if (!this.element) {
|
||||
// we have not been rendered yet, so there
|
||||
// is no point in updating the UI
|
||||
return;
|
||||
}
|
||||
this.handleActionChangeEvent(event);
|
||||
}));
|
||||
}
|
||||
}
|
||||
handleActionChangeEvent(event) {
|
||||
if (event.enabled !== undefined) {
|
||||
this.updateEnabled();
|
||||
}
|
||||
if (event.checked !== undefined) {
|
||||
this.updateChecked();
|
||||
}
|
||||
if (event.class !== undefined) {
|
||||
this.updateClass();
|
||||
}
|
||||
if (event.label !== undefined) {
|
||||
this.updateLabel();
|
||||
this.updateTooltip();
|
||||
}
|
||||
if (event.tooltip !== undefined) {
|
||||
this.updateTooltip();
|
||||
}
|
||||
}
|
||||
get actionRunner() {
|
||||
if (!this._actionRunner) {
|
||||
this._actionRunner = this._register(new ActionRunner());
|
||||
}
|
||||
return this._actionRunner;
|
||||
}
|
||||
set actionRunner(actionRunner) {
|
||||
this._actionRunner = actionRunner;
|
||||
}
|
||||
isEnabled() {
|
||||
return this._action.enabled;
|
||||
}
|
||||
setActionContext(newContext) {
|
||||
this._context = newContext;
|
||||
}
|
||||
render(container) {
|
||||
const element = this.element = container;
|
||||
this._register(Gesture.addTarget(container));
|
||||
const enableDragging = this.options && this.options.draggable;
|
||||
if (enableDragging) {
|
||||
container.draggable = true;
|
||||
if (isFirefox) {
|
||||
// Firefox: requires to set a text data transfer to get going
|
||||
this._register(addDisposableListener(container, EventType.DRAG_START, e => e.dataTransfer?.setData(DataTransfers.TEXT, this._action.label)));
|
||||
}
|
||||
}
|
||||
this._register(addDisposableListener(element, TouchEventType.Tap, e => this.onClick(e, true))); // Preserve focus on tap #125470
|
||||
this._register(addDisposableListener(element, EventType.MOUSE_DOWN, e => {
|
||||
if (!enableDragging) {
|
||||
EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
||||
}
|
||||
if (this._action.enabled && e.button === 0) {
|
||||
element.classList.add('active');
|
||||
}
|
||||
}));
|
||||
if (platform.isMacintosh) {
|
||||
// macOS: allow to trigger the button when holding Ctrl+key and pressing the
|
||||
// main mouse button. This is for scenarios where e.g. some interaction forces
|
||||
// the Ctrl+key to be pressed and hold but the user still wants to interact
|
||||
// with the actions (for example quick access in quick navigation mode).
|
||||
this._register(addDisposableListener(element, EventType.CONTEXT_MENU, e => {
|
||||
if (e.button === 0 && e.ctrlKey === true) {
|
||||
this.onClick(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
this._register(addDisposableListener(element, EventType.CLICK, e => {
|
||||
EventHelper.stop(e, true);
|
||||
// menus do not use the click event
|
||||
if (!(this.options && this.options.isMenu)) {
|
||||
this.onClick(e);
|
||||
}
|
||||
}));
|
||||
this._register(addDisposableListener(element, EventType.DBLCLICK, e => {
|
||||
EventHelper.stop(e, true);
|
||||
}));
|
||||
[EventType.MOUSE_UP, EventType.MOUSE_OUT].forEach(event => {
|
||||
this._register(addDisposableListener(element, event, e => {
|
||||
EventHelper.stop(e);
|
||||
element.classList.remove('active');
|
||||
}));
|
||||
});
|
||||
}
|
||||
onClick(event, preserveFocus = false) {
|
||||
EventHelper.stop(event, true);
|
||||
const context = types.isUndefinedOrNull(this._context) ? this.options?.useEventAsContext ? event : { preserveFocus } : this._context;
|
||||
this.actionRunner.run(this._action, context);
|
||||
}
|
||||
// Only set the tabIndex on the element once it is about to get focused
|
||||
// That way this element wont be a tab stop when it is not needed #106441
|
||||
focus() {
|
||||
if (this.element) {
|
||||
this.element.tabIndex = 0;
|
||||
this.element.focus();
|
||||
this.element.classList.add('focused');
|
||||
}
|
||||
}
|
||||
blur() {
|
||||
if (this.element) {
|
||||
this.element.blur();
|
||||
this.element.tabIndex = -1;
|
||||
this.element.classList.remove('focused');
|
||||
}
|
||||
}
|
||||
setFocusable(focusable) {
|
||||
if (this.element) {
|
||||
this.element.tabIndex = focusable ? 0 : -1;
|
||||
}
|
||||
}
|
||||
get trapsArrowNavigation() {
|
||||
return false;
|
||||
}
|
||||
updateEnabled() {
|
||||
// implement in subclass
|
||||
}
|
||||
updateLabel() {
|
||||
// implement in subclass
|
||||
}
|
||||
getClass() {
|
||||
return this.action.class;
|
||||
}
|
||||
getTooltip() {
|
||||
return this.action.tooltip;
|
||||
}
|
||||
getHoverContents() {
|
||||
return this.getTooltip();
|
||||
}
|
||||
updateTooltip() {
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
const title = this.getHoverContents() ?? '';
|
||||
this.updateAriaLabel();
|
||||
if (!this.customHover && title !== '') {
|
||||
const hoverDelegate = this.options.hoverDelegate ?? getDefaultHoverDelegate('element');
|
||||
this.customHover = this._store.add(getBaseLayerHoverDelegate().setupManagedHover(hoverDelegate, this.element, title));
|
||||
}
|
||||
else if (this.customHover) {
|
||||
this.customHover.update(title);
|
||||
}
|
||||
}
|
||||
updateAriaLabel() {
|
||||
if (this.element) {
|
||||
const title = this.getTooltip() ?? '';
|
||||
this.element.setAttribute('aria-label', title);
|
||||
}
|
||||
}
|
||||
updateClass() {
|
||||
// implement in subclass
|
||||
}
|
||||
updateChecked() {
|
||||
// implement in subclass
|
||||
}
|
||||
dispose() {
|
||||
if (this.element) {
|
||||
this.element.remove();
|
||||
this.element = undefined;
|
||||
}
|
||||
this._context = undefined;
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
export class ActionViewItem extends BaseActionViewItem {
|
||||
constructor(context, action, options) {
|
||||
options = {
|
||||
...options,
|
||||
icon: options.icon !== undefined ? options.icon : false,
|
||||
label: options.label !== undefined ? options.label : true,
|
||||
};
|
||||
super(context, action, options);
|
||||
this.options = options;
|
||||
this.cssClass = '';
|
||||
}
|
||||
render(container) {
|
||||
super.render(container);
|
||||
types.assertType(this.element);
|
||||
const label = document.createElement('a');
|
||||
label.classList.add('action-label');
|
||||
label.setAttribute('role', this.getDefaultAriaRole());
|
||||
this.label = label;
|
||||
this.element.appendChild(label);
|
||||
if (this.options.label && this.options.keybinding && !this.options.keybindingNotRenderedWithLabel) {
|
||||
const kbLabel = document.createElement('span');
|
||||
kbLabel.classList.add('keybinding');
|
||||
kbLabel.textContent = this.options.keybinding;
|
||||
this.element.appendChild(kbLabel);
|
||||
}
|
||||
this.updateClass();
|
||||
this.updateLabel();
|
||||
this.updateTooltip();
|
||||
this.updateEnabled();
|
||||
this.updateChecked();
|
||||
}
|
||||
getDefaultAriaRole() {
|
||||
if (this._action.id === Separator.ID) {
|
||||
return 'presentation'; // A separator is a presentation item
|
||||
}
|
||||
else {
|
||||
if (this.options.isMenu) {
|
||||
return 'menuitem';
|
||||
}
|
||||
else if (this.options.isTabList) {
|
||||
return 'tab';
|
||||
}
|
||||
else {
|
||||
return 'button';
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only set the tabIndex on the element once it is about to get focused
|
||||
// That way this element wont be a tab stop when it is not needed #106441
|
||||
focus() {
|
||||
if (this.label) {
|
||||
this.label.tabIndex = 0;
|
||||
this.label.focus();
|
||||
}
|
||||
}
|
||||
blur() {
|
||||
if (this.label) {
|
||||
this.label.tabIndex = -1;
|
||||
}
|
||||
}
|
||||
setFocusable(focusable) {
|
||||
if (this.label) {
|
||||
this.label.tabIndex = focusable ? 0 : -1;
|
||||
}
|
||||
}
|
||||
updateLabel() {
|
||||
if (this.options.label && this.label) {
|
||||
this.label.textContent = this.action.label;
|
||||
}
|
||||
}
|
||||
getTooltip() {
|
||||
let title = null;
|
||||
if (this.action.tooltip) {
|
||||
title = this.action.tooltip;
|
||||
}
|
||||
else if (this.action.label) {
|
||||
title = this.action.label;
|
||||
if (this.options.keybinding) {
|
||||
title = nls.localize(0, "{0} ({1})", title, this.options.keybinding);
|
||||
}
|
||||
}
|
||||
return title ?? undefined;
|
||||
}
|
||||
updateClass() {
|
||||
if (this.cssClass && this.label) {
|
||||
this.label.classList.remove(...this.cssClass.split(' '));
|
||||
}
|
||||
if (this.options.icon) {
|
||||
this.cssClass = this.getClass();
|
||||
if (this.label) {
|
||||
this.label.classList.add('codicon');
|
||||
if (this.cssClass) {
|
||||
this.label.classList.add(...this.cssClass.split(' '));
|
||||
}
|
||||
}
|
||||
this.updateEnabled();
|
||||
}
|
||||
else {
|
||||
this.label?.classList.remove('codicon');
|
||||
}
|
||||
}
|
||||
updateEnabled() {
|
||||
if (this.action.enabled) {
|
||||
if (this.label) {
|
||||
this.label.removeAttribute('aria-disabled');
|
||||
this.label.classList.remove('disabled');
|
||||
}
|
||||
this.element?.classList.remove('disabled');
|
||||
}
|
||||
else {
|
||||
if (this.label) {
|
||||
this.label.setAttribute('aria-disabled', 'true');
|
||||
this.label.classList.add('disabled');
|
||||
}
|
||||
this.element?.classList.add('disabled');
|
||||
}
|
||||
}
|
||||
updateAriaLabel() {
|
||||
if (this.label) {
|
||||
const title = this.getTooltip() ?? '';
|
||||
this.label.setAttribute('aria-label', title);
|
||||
}
|
||||
}
|
||||
updateChecked() {
|
||||
if (this.label) {
|
||||
if (this.action.checked !== undefined) {
|
||||
this.label.classList.toggle('checked', this.action.checked);
|
||||
if (this.options.isTabList) {
|
||||
this.label.setAttribute('aria-selected', this.action.checked ? 'true' : 'false');
|
||||
}
|
||||
else {
|
||||
this.label.setAttribute('aria-checked', this.action.checked ? 'true' : 'false');
|
||||
this.label.setAttribute('role', 'checkbox');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.label.classList.remove('checked');
|
||||
this.label.removeAttribute(this.options.isTabList ? 'aria-selected' : 'aria-checked');
|
||||
this.label.setAttribute('role', this.getDefaultAriaRole());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export class SelectActionViewItem extends BaseActionViewItem {
|
||||
constructor(ctx, action, options, selected, contextViewProvider, styles, selectBoxOptions) {
|
||||
super(ctx, action);
|
||||
this.selectBox = new SelectBox(options, selected, contextViewProvider, styles, selectBoxOptions);
|
||||
this.selectBox.setFocusable(false);
|
||||
this._register(this.selectBox);
|
||||
this.registerListeners();
|
||||
}
|
||||
select(index) {
|
||||
this.selectBox.select(index);
|
||||
}
|
||||
registerListeners() {
|
||||
this._register(this.selectBox.onDidSelect(e => this.runAction(e.selected, e.index)));
|
||||
}
|
||||
runAction(option, index) {
|
||||
this.actionRunner.run(this._action, this.getActionContext(option, index));
|
||||
}
|
||||
getActionContext(option, index) {
|
||||
return option;
|
||||
}
|
||||
setFocusable(focusable) {
|
||||
this.selectBox.setFocusable(focusable);
|
||||
}
|
||||
focus() {
|
||||
this.selectBox?.focus();
|
||||
}
|
||||
blur() {
|
||||
this.selectBox?.blur();
|
||||
}
|
||||
render(container) {
|
||||
this.selectBox.render(container);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=actionViewItems.js.map
|
||||
File diff suppressed because one or more lines are too long
124
_internal/editor/esm/vs/base/browser/ui/actionbar/actionbar.css
Normal file
124
_internal/editor/esm/vs/base/browser/ui/actionbar/actionbar.css
Normal file
@@ -0,0 +1,124 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-action-bar {
|
||||
white-space: nowrap;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-action-bar .actions-container {
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-action-bar.vertical .actions-container {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item {
|
||||
display: block;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
position: relative; /* DO NOT REMOVE - this is the key to preventing the ghosting icon bug in Chrome 42 */
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item.disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .icon,
|
||||
.monaco-action-bar .action-item .codicon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .codicon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-label {
|
||||
display: flex;
|
||||
font-size: 11px;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item.disabled .action-label:not(.icon) ,
|
||||
.monaco-action-bar .action-item.disabled .action-label:not(.icon)::before,
|
||||
.monaco-action-bar .action-item.disabled .action-label:not(.icon):hover {
|
||||
color: var(--vscode-disabledForeground);
|
||||
}
|
||||
|
||||
/* Unable to change color of SVGs, hence opacity is used */
|
||||
.monaco-action-bar .action-item.disabled .action-label.icon ,
|
||||
.monaco-action-bar .action-item.disabled .action-label.icon::before,
|
||||
.monaco-action-bar .action-item.disabled .action-label.icon:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* Vertical actions */
|
||||
|
||||
.monaco-action-bar.vertical {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.monaco-action-bar.vertical .action-item {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.monaco-action-bar.vertical .action-label.separator {
|
||||
display: block;
|
||||
border-bottom: 1px solid var(--vscode-disabledForeground);
|
||||
padding-top: 1px;
|
||||
margin-left: .8em;
|
||||
margin-right: .8em;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .action-label.separator {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
margin: 5px 4px !important;
|
||||
cursor: default;
|
||||
min-width: 1px;
|
||||
padding: 0;
|
||||
background-color: var(--vscode-disabledForeground);
|
||||
}
|
||||
|
||||
.secondary-actions .monaco-action-bar .action-label {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
/* Action Items */
|
||||
.monaco-action-bar .action-item.select-container {
|
||||
overflow: hidden; /* somehow the dropdown overflows its container, we prevent it here to not push */
|
||||
flex: 1;
|
||||
max-width: 170px;
|
||||
min-width: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item.action-dropdown-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator > div {
|
||||
width: 1px;
|
||||
}
|
||||
443
_internal/editor/esm/vs/base/browser/ui/actionbar/actionbar.js
Normal file
443
_internal/editor/esm/vs/base/browser/ui/actionbar/actionbar.js
Normal file
@@ -0,0 +1,443 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as DOM from '../../dom.js';
|
||||
import { StandardKeyboardEvent } from '../../keyboardEvent.js';
|
||||
import { ActionViewItem, BaseActionViewItem } from './actionViewItems.js';
|
||||
import { createInstantHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
import { ActionRunner, Separator } from '../../../common/actions.js';
|
||||
import { Emitter } from '../../../common/event.js';
|
||||
import { Disposable, DisposableMap, DisposableStore, dispose } from '../../../common/lifecycle.js';
|
||||
import * as types from '../../../common/types.js';
|
||||
import './actionbar.css';
|
||||
export class ActionBar extends Disposable {
|
||||
get onDidBlur() { return this._onDidBlur.event; }
|
||||
get onDidCancel() { return this._onDidCancel.event; }
|
||||
get onDidRun() { return this._onDidRun.event; }
|
||||
get onWillRun() { return this._onWillRun.event; }
|
||||
constructor(container, options = {}) {
|
||||
super();
|
||||
this._actionRunnerDisposables = this._register(new DisposableStore());
|
||||
this.viewItemDisposables = this._register(new DisposableMap());
|
||||
// Trigger Key Tracking
|
||||
this.triggerKeyDown = false;
|
||||
this.focusable = true;
|
||||
this._onDidBlur = this._register(new Emitter());
|
||||
this._onDidCancel = this._register(new Emitter({ onWillAddFirstListener: () => this.cancelHasListener = true }));
|
||||
this.cancelHasListener = false;
|
||||
this._onDidRun = this._register(new Emitter());
|
||||
this._onWillRun = this._register(new Emitter());
|
||||
this.options = options;
|
||||
this._context = options.context ?? null;
|
||||
this._orientation = this.options.orientation ?? 0 /* ActionsOrientation.HORIZONTAL */;
|
||||
this._triggerKeys = {
|
||||
keyDown: this.options.triggerKeys?.keyDown ?? false,
|
||||
keys: this.options.triggerKeys?.keys ?? [3 /* KeyCode.Enter */, 10 /* KeyCode.Space */]
|
||||
};
|
||||
this._hoverDelegate = options.hoverDelegate ?? this._register(createInstantHoverDelegate());
|
||||
if (this.options.actionRunner) {
|
||||
this._actionRunner = this.options.actionRunner;
|
||||
}
|
||||
else {
|
||||
this._actionRunner = new ActionRunner();
|
||||
this._actionRunnerDisposables.add(this._actionRunner);
|
||||
}
|
||||
this._actionRunnerDisposables.add(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
|
||||
this._actionRunnerDisposables.add(this._actionRunner.onWillRun(e => this._onWillRun.fire(e)));
|
||||
this.viewItems = [];
|
||||
this.focusedItem = undefined;
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.className = 'monaco-action-bar';
|
||||
let previousKeys;
|
||||
let nextKeys;
|
||||
switch (this._orientation) {
|
||||
case 0 /* ActionsOrientation.HORIZONTAL */:
|
||||
previousKeys = [15 /* KeyCode.LeftArrow */];
|
||||
nextKeys = [17 /* KeyCode.RightArrow */];
|
||||
break;
|
||||
case 1 /* ActionsOrientation.VERTICAL */:
|
||||
previousKeys = [16 /* KeyCode.UpArrow */];
|
||||
nextKeys = [18 /* KeyCode.DownArrow */];
|
||||
this.domNode.className += ' vertical';
|
||||
break;
|
||||
}
|
||||
this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let eventHandled = true;
|
||||
const focusedItem = typeof this.focusedItem === 'number' ? this.viewItems[this.focusedItem] : undefined;
|
||||
if (previousKeys && (event.equals(previousKeys[0]) || event.equals(previousKeys[1]))) {
|
||||
eventHandled = this.focusPrevious();
|
||||
}
|
||||
else if (nextKeys && (event.equals(nextKeys[0]) || event.equals(nextKeys[1]))) {
|
||||
eventHandled = this.focusNext();
|
||||
}
|
||||
else if (event.equals(9 /* KeyCode.Escape */) && this.cancelHasListener) {
|
||||
this._onDidCancel.fire();
|
||||
}
|
||||
else if (event.equals(14 /* KeyCode.Home */)) {
|
||||
eventHandled = this.focusFirst();
|
||||
}
|
||||
else if (event.equals(13 /* KeyCode.End */)) {
|
||||
eventHandled = this.focusLast();
|
||||
}
|
||||
else if (event.equals(2 /* KeyCode.Tab */) && focusedItem instanceof BaseActionViewItem && focusedItem.trapsArrowNavigation) {
|
||||
// Tab, so forcibly focus next #219199
|
||||
eventHandled = this.focusNext(undefined, true);
|
||||
}
|
||||
else if (this.isTriggerKeyEvent(event)) {
|
||||
// Staying out of the else branch even if not triggered
|
||||
if (this._triggerKeys.keyDown) {
|
||||
this.doTrigger(event);
|
||||
}
|
||||
else {
|
||||
this.triggerKeyDown = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eventHandled = false;
|
||||
}
|
||||
if (eventHandled) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}));
|
||||
this._register(DOM.addDisposableListener(this.domNode, DOM.EventType.KEY_UP, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
// Run action on Enter/Space
|
||||
if (this.isTriggerKeyEvent(event)) {
|
||||
if (!this._triggerKeys.keyDown && this.triggerKeyDown) {
|
||||
this.triggerKeyDown = false;
|
||||
this.doTrigger(event);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
// Recompute focused item
|
||||
else if (event.equals(2 /* KeyCode.Tab */) || event.equals(1024 /* KeyMod.Shift */ | 2 /* KeyCode.Tab */) || event.equals(16 /* KeyCode.UpArrow */) || event.equals(18 /* KeyCode.DownArrow */) || event.equals(15 /* KeyCode.LeftArrow */) || event.equals(17 /* KeyCode.RightArrow */)) {
|
||||
this.updateFocusedItem();
|
||||
}
|
||||
}));
|
||||
this.focusTracker = this._register(DOM.trackFocus(this.domNode));
|
||||
this._register(this.focusTracker.onDidBlur(() => {
|
||||
if (DOM.getActiveElement() === this.domNode || !DOM.isAncestor(DOM.getActiveElement(), this.domNode)) {
|
||||
this._onDidBlur.fire();
|
||||
this.previouslyFocusedItem = this.focusedItem;
|
||||
this.focusedItem = undefined;
|
||||
this.triggerKeyDown = false;
|
||||
}
|
||||
}));
|
||||
this._register(this.focusTracker.onDidFocus(() => this.updateFocusedItem()));
|
||||
this.actionsList = document.createElement('ul');
|
||||
this.actionsList.className = 'actions-container';
|
||||
if (this.options.highlightToggledItems) {
|
||||
this.actionsList.classList.add('highlight-toggled');
|
||||
}
|
||||
this.actionsList.setAttribute('role', this.options.ariaRole || 'toolbar');
|
||||
if (this.options.ariaLabel) {
|
||||
this.actionsList.setAttribute('aria-label', this.options.ariaLabel);
|
||||
}
|
||||
this.domNode.appendChild(this.actionsList);
|
||||
container.appendChild(this.domNode);
|
||||
}
|
||||
refreshRole() {
|
||||
if (this.length() >= 1) {
|
||||
this.actionsList.setAttribute('role', this.options.ariaRole || 'toolbar');
|
||||
}
|
||||
else {
|
||||
this.actionsList.setAttribute('role', 'presentation');
|
||||
}
|
||||
}
|
||||
// Some action bars should not be focusable at times
|
||||
// When an action bar is not focusable make sure to make all the elements inside it not focusable
|
||||
// When an action bar is focusable again, make sure the first item can be focused
|
||||
setFocusable(focusable) {
|
||||
this.focusable = focusable;
|
||||
if (this.focusable) {
|
||||
const firstEnabled = this.viewItems.find(vi => vi instanceof BaseActionViewItem && vi.isEnabled());
|
||||
if (firstEnabled instanceof BaseActionViewItem) {
|
||||
firstEnabled.setFocusable(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.viewItems.forEach(vi => {
|
||||
if (vi instanceof BaseActionViewItem) {
|
||||
vi.setFocusable(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
isTriggerKeyEvent(event) {
|
||||
let ret = false;
|
||||
this._triggerKeys.keys.forEach(keyCode => {
|
||||
ret = ret || event.equals(keyCode);
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
updateFocusedItem() {
|
||||
for (let i = 0; i < this.actionsList.children.length; i++) {
|
||||
const elem = this.actionsList.children[i];
|
||||
if (DOM.isAncestor(DOM.getActiveElement(), elem)) {
|
||||
this.focusedItem = i;
|
||||
this.viewItems[this.focusedItem]?.showHover?.();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
get context() {
|
||||
return this._context;
|
||||
}
|
||||
set context(context) {
|
||||
this._context = context;
|
||||
this.viewItems.forEach(i => i.setActionContext(context));
|
||||
}
|
||||
get actionRunner() {
|
||||
return this._actionRunner;
|
||||
}
|
||||
set actionRunner(actionRunner) {
|
||||
this._actionRunner = actionRunner;
|
||||
// when setting a new `IActionRunner` make sure to dispose old listeners and
|
||||
// start to forward events from the new listener
|
||||
this._actionRunnerDisposables.clear();
|
||||
this._actionRunnerDisposables.add(this._actionRunner.onDidRun(e => this._onDidRun.fire(e)));
|
||||
this._actionRunnerDisposables.add(this._actionRunner.onWillRun(e => this._onWillRun.fire(e)));
|
||||
this.viewItems.forEach(item => item.actionRunner = actionRunner);
|
||||
}
|
||||
getContainer() {
|
||||
return this.domNode;
|
||||
}
|
||||
getAction(indexOrElement) {
|
||||
// by index
|
||||
if (typeof indexOrElement === 'number') {
|
||||
return this.viewItems[indexOrElement]?.action;
|
||||
}
|
||||
// by element
|
||||
if (DOM.isHTMLElement(indexOrElement)) {
|
||||
while (indexOrElement.parentElement !== this.actionsList) {
|
||||
if (!indexOrElement.parentElement) {
|
||||
return undefined;
|
||||
}
|
||||
indexOrElement = indexOrElement.parentElement;
|
||||
}
|
||||
for (let i = 0; i < this.actionsList.childNodes.length; i++) {
|
||||
if (this.actionsList.childNodes[i] === indexOrElement) {
|
||||
return this.viewItems[i].action;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
push(arg, options = {}) {
|
||||
const actions = Array.isArray(arg) ? arg : [arg];
|
||||
let index = types.isNumber(options.index) ? options.index : null;
|
||||
actions.forEach((action) => {
|
||||
const actionViewItemElement = document.createElement('li');
|
||||
actionViewItemElement.className = 'action-item';
|
||||
actionViewItemElement.setAttribute('role', 'presentation');
|
||||
let item;
|
||||
const viewItemOptions = { hoverDelegate: this._hoverDelegate, ...options, isTabList: this.options.ariaRole === 'tablist' };
|
||||
if (this.options.actionViewItemProvider) {
|
||||
item = this.options.actionViewItemProvider(action, viewItemOptions);
|
||||
}
|
||||
if (!item) {
|
||||
item = new ActionViewItem(this.context, action, viewItemOptions);
|
||||
}
|
||||
// Prevent native context menu on actions
|
||||
if (!this.options.allowContextMenu) {
|
||||
this.viewItemDisposables.set(item, DOM.addDisposableListener(actionViewItemElement, DOM.EventType.CONTEXT_MENU, (e) => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
}));
|
||||
}
|
||||
item.actionRunner = this._actionRunner;
|
||||
item.setActionContext(this.context);
|
||||
item.render(actionViewItemElement);
|
||||
if (index === null || index < 0 || index >= this.actionsList.children.length) {
|
||||
this.actionsList.appendChild(actionViewItemElement);
|
||||
this.viewItems.push(item);
|
||||
}
|
||||
else {
|
||||
this.actionsList.insertBefore(actionViewItemElement, this.actionsList.children[index]);
|
||||
this.viewItems.splice(index, 0, item);
|
||||
index++;
|
||||
}
|
||||
});
|
||||
// We need to allow for the first enabled item to be focused on using tab navigation #106441
|
||||
if (this.focusable) {
|
||||
let didFocus = false;
|
||||
for (const item of this.viewItems) {
|
||||
if (!(item instanceof BaseActionViewItem)) {
|
||||
continue;
|
||||
}
|
||||
let focus;
|
||||
if (didFocus) {
|
||||
focus = false; // already focused an item
|
||||
}
|
||||
else if (item.action.id === Separator.ID) {
|
||||
focus = false; // never focus a separator
|
||||
}
|
||||
else if (!item.isEnabled() && this.options.focusOnlyEnabledItems) {
|
||||
focus = false; // never focus a disabled item
|
||||
}
|
||||
else {
|
||||
focus = true;
|
||||
}
|
||||
if (focus) {
|
||||
item.setFocusable(true);
|
||||
didFocus = true;
|
||||
}
|
||||
else {
|
||||
item.setFocusable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof this.focusedItem === 'number') {
|
||||
// After a clear actions might be re-added to simply toggle some actions. We should preserve focus #97128
|
||||
this.focus(this.focusedItem);
|
||||
}
|
||||
this.refreshRole();
|
||||
}
|
||||
clear() {
|
||||
if (this.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
this.viewItems = dispose(this.viewItems);
|
||||
this.viewItemDisposables.clearAndDisposeAll();
|
||||
DOM.clearNode(this.actionsList);
|
||||
this.refreshRole();
|
||||
}
|
||||
length() {
|
||||
return this.viewItems.length;
|
||||
}
|
||||
isEmpty() {
|
||||
return this.viewItems.length === 0;
|
||||
}
|
||||
focus(arg) {
|
||||
let selectFirst = false;
|
||||
let index = undefined;
|
||||
if (arg === undefined) {
|
||||
selectFirst = true;
|
||||
}
|
||||
else if (typeof arg === 'number') {
|
||||
index = arg;
|
||||
}
|
||||
else if (typeof arg === 'boolean') {
|
||||
selectFirst = arg;
|
||||
}
|
||||
if (selectFirst && typeof this.focusedItem === 'undefined') {
|
||||
const firstEnabled = this.viewItems.findIndex(item => item.isEnabled());
|
||||
// Focus the first enabled item
|
||||
this.focusedItem = firstEnabled === -1 ? undefined : firstEnabled;
|
||||
this.updateFocus(undefined, undefined, true);
|
||||
}
|
||||
else {
|
||||
if (index !== undefined) {
|
||||
this.focusedItem = index;
|
||||
}
|
||||
this.updateFocus(undefined, undefined, true);
|
||||
}
|
||||
}
|
||||
focusFirst() {
|
||||
this.focusedItem = this.length() - 1;
|
||||
return this.focusNext(true);
|
||||
}
|
||||
focusLast() {
|
||||
this.focusedItem = 0;
|
||||
return this.focusPrevious(true);
|
||||
}
|
||||
focusNext(forceLoop, forceFocus) {
|
||||
if (typeof this.focusedItem === 'undefined') {
|
||||
this.focusedItem = this.viewItems.length - 1;
|
||||
}
|
||||
else if (this.viewItems.length <= 1) {
|
||||
return false;
|
||||
}
|
||||
const startIndex = this.focusedItem;
|
||||
let item;
|
||||
do {
|
||||
if (!forceLoop && this.options.preventLoopNavigation && this.focusedItem + 1 >= this.viewItems.length) {
|
||||
this.focusedItem = startIndex;
|
||||
return false;
|
||||
}
|
||||
this.focusedItem = (this.focusedItem + 1) % this.viewItems.length;
|
||||
item = this.viewItems[this.focusedItem];
|
||||
} while (this.focusedItem !== startIndex && ((this.options.focusOnlyEnabledItems && !item.isEnabled()) || item.action.id === Separator.ID));
|
||||
this.updateFocus(undefined, undefined, forceFocus);
|
||||
return true;
|
||||
}
|
||||
focusPrevious(forceLoop) {
|
||||
if (typeof this.focusedItem === 'undefined') {
|
||||
this.focusedItem = 0;
|
||||
}
|
||||
else if (this.viewItems.length <= 1) {
|
||||
return false;
|
||||
}
|
||||
const startIndex = this.focusedItem;
|
||||
let item;
|
||||
do {
|
||||
this.focusedItem = this.focusedItem - 1;
|
||||
if (this.focusedItem < 0) {
|
||||
if (!forceLoop && this.options.preventLoopNavigation) {
|
||||
this.focusedItem = startIndex;
|
||||
return false;
|
||||
}
|
||||
this.focusedItem = this.viewItems.length - 1;
|
||||
}
|
||||
item = this.viewItems[this.focusedItem];
|
||||
} while (this.focusedItem !== startIndex && ((this.options.focusOnlyEnabledItems && !item.isEnabled()) || item.action.id === Separator.ID));
|
||||
this.updateFocus(true);
|
||||
return true;
|
||||
}
|
||||
updateFocus(fromRight, preventScroll, forceFocus = false) {
|
||||
if (typeof this.focusedItem === 'undefined') {
|
||||
this.actionsList.focus({ preventScroll });
|
||||
}
|
||||
if (this.previouslyFocusedItem !== undefined && this.previouslyFocusedItem !== this.focusedItem) {
|
||||
this.viewItems[this.previouslyFocusedItem]?.blur();
|
||||
}
|
||||
const actionViewItem = this.focusedItem !== undefined ? this.viewItems[this.focusedItem] : undefined;
|
||||
if (actionViewItem) {
|
||||
let focusItem = true;
|
||||
if (!types.isFunction(actionViewItem.focus)) {
|
||||
focusItem = false;
|
||||
}
|
||||
if (this.options.focusOnlyEnabledItems && types.isFunction(actionViewItem.isEnabled) && !actionViewItem.isEnabled()) {
|
||||
focusItem = false;
|
||||
}
|
||||
if (actionViewItem.action.id === Separator.ID) {
|
||||
focusItem = false;
|
||||
}
|
||||
if (!focusItem) {
|
||||
this.actionsList.focus({ preventScroll });
|
||||
this.previouslyFocusedItem = undefined;
|
||||
}
|
||||
else if (forceFocus || this.previouslyFocusedItem !== this.focusedItem) {
|
||||
actionViewItem.focus(fromRight);
|
||||
this.previouslyFocusedItem = this.focusedItem;
|
||||
}
|
||||
if (focusItem) {
|
||||
actionViewItem.showHover?.();
|
||||
}
|
||||
}
|
||||
}
|
||||
doTrigger(event) {
|
||||
if (typeof this.focusedItem === 'undefined') {
|
||||
return; //nothing to focus
|
||||
}
|
||||
// trigger action
|
||||
const actionViewItem = this.viewItems[this.focusedItem];
|
||||
if (actionViewItem instanceof BaseActionViewItem) {
|
||||
const context = (actionViewItem._context === null || actionViewItem._context === undefined) ? event : actionViewItem._context;
|
||||
this.run(actionViewItem._action, context);
|
||||
}
|
||||
}
|
||||
async run(action, context) {
|
||||
await this._actionRunner.run(action, context);
|
||||
}
|
||||
dispose() {
|
||||
this._context = undefined;
|
||||
this.viewItems = dispose(this.viewItems);
|
||||
this.getContainer().remove();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=actionbar.js.map
|
||||
File diff suppressed because one or more lines are too long
9
_internal/editor/esm/vs/base/browser/ui/aria/aria.css
Normal file
9
_internal/editor/esm/vs/base/browser/ui/aria/aria.css
Normal file
@@ -0,0 +1,9 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-aria-container {
|
||||
position: absolute; /* try to hide from window but not from screen readers */
|
||||
left:-999em;
|
||||
}
|
||||
82
_internal/editor/esm/vs/base/browser/ui/aria/aria.js
Normal file
82
_internal/editor/esm/vs/base/browser/ui/aria/aria.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from '../../dom.js';
|
||||
import './aria.css';
|
||||
// Use a max length since we are inserting the whole msg in the DOM and that can cause browsers to freeze for long messages #94233
|
||||
const MAX_MESSAGE_LENGTH = 20000;
|
||||
let ariaContainer;
|
||||
let alertContainer;
|
||||
let alertContainer2;
|
||||
let statusContainer;
|
||||
let statusContainer2;
|
||||
export function setARIAContainer(parent) {
|
||||
ariaContainer = document.createElement('div');
|
||||
ariaContainer.className = 'monaco-aria-container';
|
||||
const createAlertContainer = () => {
|
||||
const element = document.createElement('div');
|
||||
element.className = 'monaco-alert';
|
||||
element.setAttribute('role', 'alert');
|
||||
element.setAttribute('aria-atomic', 'true');
|
||||
ariaContainer.appendChild(element);
|
||||
return element;
|
||||
};
|
||||
alertContainer = createAlertContainer();
|
||||
alertContainer2 = createAlertContainer();
|
||||
const createStatusContainer = () => {
|
||||
const element = document.createElement('div');
|
||||
element.className = 'monaco-status';
|
||||
element.setAttribute('aria-live', 'polite');
|
||||
element.setAttribute('aria-atomic', 'true');
|
||||
ariaContainer.appendChild(element);
|
||||
return element;
|
||||
};
|
||||
statusContainer = createStatusContainer();
|
||||
statusContainer2 = createStatusContainer();
|
||||
parent.appendChild(ariaContainer);
|
||||
}
|
||||
/**
|
||||
* Given the provided message, will make sure that it is read as alert to screen readers.
|
||||
*/
|
||||
export function alert(msg) {
|
||||
if (!ariaContainer) {
|
||||
return;
|
||||
}
|
||||
// Use alternate containers such that duplicated messages get read out by screen readers #99466
|
||||
if (alertContainer.textContent !== msg) {
|
||||
dom.clearNode(alertContainer2);
|
||||
insertMessage(alertContainer, msg);
|
||||
}
|
||||
else {
|
||||
dom.clearNode(alertContainer);
|
||||
insertMessage(alertContainer2, msg);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given the provided message, will make sure that it is read as status to screen readers.
|
||||
*/
|
||||
export function status(msg) {
|
||||
if (!ariaContainer) {
|
||||
return;
|
||||
}
|
||||
if (statusContainer.textContent !== msg) {
|
||||
dom.clearNode(statusContainer2);
|
||||
insertMessage(statusContainer, msg);
|
||||
}
|
||||
else {
|
||||
dom.clearNode(statusContainer);
|
||||
insertMessage(statusContainer2, msg);
|
||||
}
|
||||
}
|
||||
function insertMessage(target, msg) {
|
||||
dom.clearNode(target);
|
||||
if (msg.length > MAX_MESSAGE_LENGTH) {
|
||||
msg = msg.substr(0, MAX_MESSAGE_LENGTH);
|
||||
}
|
||||
target.textContent = msg;
|
||||
// See https://www.paciellogroup.com/blog/2012/06/html5-accessibility-chops-aria-rolealert-browser-support/
|
||||
target.style.visibility = 'hidden';
|
||||
target.style.visibility = 'visible';
|
||||
}
|
||||
//# sourceMappingURL=aria.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/ui/aria/aria.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/ui/aria/aria.js.map
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-breadcrumbs {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
.monaco-breadcrumbs .monaco-breadcrumb-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 0 1 auto;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
align-self: center;
|
||||
height: 100%;
|
||||
outline: none;
|
||||
}
|
||||
.monaco-breadcrumbs.disabled .monaco-breadcrumb-item {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-breadcrumbs .monaco-breadcrumb-item .codicon-breadcrumb-separator {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.monaco-breadcrumbs .monaco-breadcrumb-item:first-of-type::before {
|
||||
content: ' ';
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
import './breadcrumbsWidget.css';
|
||||
//# sourceMappingURL=breadcrumbsWidget.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts","vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts"],"names":[],"mappings":"AACA,OAAO,yBAAyB,CAAC","file":"breadcrumbsWidget.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["\nimport './breadcrumbsWidget.css';\n\nexport interface IBreadcrumbsWidgetStyles {\n\treadonly breadcrumbsBackground: string | undefined;\n\treadonly breadcrumbsForeground: string | undefined;\n\treadonly breadcrumbsHoverForeground: string | undefined;\n\treadonly breadcrumbsFocusForeground: string | undefined;\n\treadonly breadcrumbsFocusAndSelectionForeground: string | undefined;\n}\n","\nimport './breadcrumbsWidget.css';\n\nexport interface IBreadcrumbsWidgetStyles {\n\treadonly breadcrumbsBackground: string | undefined;\n\treadonly breadcrumbsForeground: string | undefined;\n\treadonly breadcrumbsHoverForeground: string | undefined;\n\treadonly breadcrumbsFocusForeground: string | undefined;\n\treadonly breadcrumbsFocusAndSelectionForeground: string | undefined;\n}\n"]}
|
||||
174
_internal/editor/esm/vs/base/browser/ui/button/button.css
Normal file
174
_internal/editor/esm/vs/base/browser/ui/button/button.css
Normal file
@@ -0,0 +1,174 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-text-button {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
border-radius: 2px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px solid var(--vscode-button-border, transparent);
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.monaco-text-button:focus {
|
||||
outline-offset: 2px !important;
|
||||
}
|
||||
|
||||
.monaco-text-button:hover {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.monaco-button.disabled:focus,
|
||||
.monaco-button.disabled {
|
||||
opacity: 0.4 !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-text-button .codicon {
|
||||
margin: 0 0.2em;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.monaco-text-button.monaco-text-button-with-short-label {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 4px;
|
||||
overflow: hidden;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.monaco-text-button.monaco-text-button-with-short-label > .monaco-button-label {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.monaco-text-button.monaco-text-button-with-short-label > .monaco-button-label-short {
|
||||
flex-grow: 1;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-text-button.monaco-text-button-with-short-label > .monaco-button-label,
|
||||
.monaco-text-button.monaco-text-button-with-short-label > .monaco-button-label-short {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: normal;
|
||||
font-style: inherit;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown.disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown > .monaco-button:focus {
|
||||
outline-offset: -1px !important;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown.disabled > .monaco-button.disabled,
|
||||
.monaco-button-dropdown.disabled > .monaco-button.disabled:focus,
|
||||
.monaco-button-dropdown.disabled > .monaco-button-dropdown-separator {
|
||||
opacity: 0.4 !important;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown > .monaco-button.monaco-text-button {
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown .monaco-button-dropdown-separator {
|
||||
padding: 4px 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown .monaco-button-dropdown-separator > div {
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown > .monaco-button.monaco-dropdown-button {
|
||||
border: 1px solid var(--vscode-button-border, transparent);
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 2px 2px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-button-dropdown > .monaco-button.monaco-text-button {
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
|
||||
.monaco-description-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 4px 5px; /* allows button focus outline to be visible */
|
||||
}
|
||||
|
||||
.monaco-description-button .monaco-button-description {
|
||||
font-style: italic;
|
||||
font-size: 11px;
|
||||
padding: 4px 20px;
|
||||
}
|
||||
|
||||
.monaco-description-button .monaco-button-label,
|
||||
.monaco-description-button .monaco-button-description {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-description-button .monaco-button-label > .codicon,
|
||||
.monaco-description-button .monaco-button-description > .codicon {
|
||||
margin: 0 0.2em;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* default color styles - based on CSS variables */
|
||||
|
||||
.monaco-button.default-colors,
|
||||
.monaco-button-dropdown.default-colors > .monaco-button{
|
||||
color: var(--vscode-button-foreground);
|
||||
background-color: var(--vscode-button-background);
|
||||
}
|
||||
|
||||
.monaco-button.default-colors:hover,
|
||||
.monaco-button-dropdown.default-colors > .monaco-button:hover {
|
||||
background-color: var(--vscode-button-hoverBackground);
|
||||
}
|
||||
|
||||
.monaco-button.default-colors.secondary,
|
||||
.monaco-button-dropdown.default-colors > .monaco-button.secondary {
|
||||
color: var(--vscode-button-secondaryForeground);
|
||||
background-color: var(--vscode-button-secondaryBackground);
|
||||
}
|
||||
|
||||
.monaco-button.default-colors.secondary:hover,
|
||||
.monaco-button-dropdown.default-colors > .monaco-button.secondary:hover {
|
||||
background-color: var(--vscode-button-secondaryHoverBackground);
|
||||
}
|
||||
|
||||
.monaco-button-dropdown.default-colors .monaco-button-dropdown-separator {
|
||||
background-color: var(--vscode-button-background);
|
||||
border-top: 1px solid var(--vscode-button-border);
|
||||
border-bottom: 1px solid var(--vscode-button-border);
|
||||
}
|
||||
|
||||
.monaco-button-dropdown.default-colors .monaco-button.secondary + .monaco-button-dropdown-separator {
|
||||
background-color: var(--vscode-button-secondaryBackground);
|
||||
}
|
||||
|
||||
.monaco-button-dropdown.default-colors .monaco-button-dropdown-separator > div {
|
||||
background-color: var(--vscode-button-separator);
|
||||
}
|
||||
230
_internal/editor/esm/vs/base/browser/ui/button/button.js
Normal file
230
_internal/editor/esm/vs/base/browser/ui/button/button.js
Normal file
@@ -0,0 +1,230 @@
|
||||
import { addDisposableListener, EventHelper, EventType, reset, trackFocus } from '../../dom.js';
|
||||
import { StandardKeyboardEvent } from '../../keyboardEvent.js';
|
||||
import { renderMarkdown, renderAsPlaintext } from '../../markdownRenderer.js';
|
||||
import { Gesture, EventType as TouchEventType } from '../../touch.js';
|
||||
import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
import { renderLabelWithIcons } from '../iconLabel/iconLabels.js';
|
||||
import { Color } from '../../../common/color.js';
|
||||
import { Emitter } from '../../../common/event.js';
|
||||
import { isMarkdownString, markdownStringEqual } from '../../../common/htmlContent.js';
|
||||
import { Disposable } from '../../../common/lifecycle.js';
|
||||
import { ThemeIcon } from '../../../common/themables.js';
|
||||
import './button.css';
|
||||
import { getBaseLayerHoverDelegate } from '../hover/hoverDelegate2.js';
|
||||
import { safeSetInnerHtml } from '../../domSanitize.js';
|
||||
export const unthemedButtonStyles = {
|
||||
buttonBackground: '#0E639C',
|
||||
buttonHoverBackground: '#006BB3',
|
||||
buttonSeparator: Color.white.toString(),
|
||||
buttonForeground: Color.white.toString(),
|
||||
buttonBorder: undefined,
|
||||
buttonSecondaryBackground: undefined,
|
||||
buttonSecondaryForeground: undefined,
|
||||
buttonSecondaryHoverBackground: undefined
|
||||
};
|
||||
// Only allow a very limited set of inline html tags
|
||||
const buttonSanitizerConfig = Object.freeze({
|
||||
allowedTags: {
|
||||
override: ['b', 'i', 'u', 'code', 'span'],
|
||||
},
|
||||
allowedAttributes: {
|
||||
override: ['class'],
|
||||
},
|
||||
});
|
||||
export class Button extends Disposable {
|
||||
get onDidClick() { return this._onDidClick.event; }
|
||||
constructor(container, options) {
|
||||
super();
|
||||
this._label = '';
|
||||
this._onDidClick = this._register(new Emitter());
|
||||
this._onDidEscape = this._register(new Emitter());
|
||||
this.options = options;
|
||||
this._element = document.createElement('a');
|
||||
this._element.classList.add('monaco-button');
|
||||
this._element.tabIndex = 0;
|
||||
this._element.setAttribute('role', 'button');
|
||||
this._element.classList.toggle('secondary', !!options.secondary);
|
||||
const background = options.secondary ? options.buttonSecondaryBackground : options.buttonBackground;
|
||||
const foreground = options.secondary ? options.buttonSecondaryForeground : options.buttonForeground;
|
||||
this._element.style.color = foreground || '';
|
||||
this._element.style.backgroundColor = background || '';
|
||||
if (options.supportShortLabel) {
|
||||
this._labelShortElement = document.createElement('div');
|
||||
this._labelShortElement.classList.add('monaco-button-label-short');
|
||||
this._element.appendChild(this._labelShortElement);
|
||||
this._labelElement = document.createElement('div');
|
||||
this._labelElement.classList.add('monaco-button-label');
|
||||
this._element.appendChild(this._labelElement);
|
||||
this._element.classList.add('monaco-text-button-with-short-label');
|
||||
}
|
||||
if (typeof options.title === 'string') {
|
||||
this.setTitle(options.title);
|
||||
}
|
||||
if (typeof options.ariaLabel === 'string') {
|
||||
this._element.setAttribute('aria-label', options.ariaLabel);
|
||||
}
|
||||
container.appendChild(this._element);
|
||||
this.enabled = !options.disabled;
|
||||
this._register(Gesture.addTarget(this._element));
|
||||
[EventType.CLICK, TouchEventType.Tap].forEach(eventType => {
|
||||
this._register(addDisposableListener(this._element, eventType, e => {
|
||||
if (!this.enabled) {
|
||||
EventHelper.stop(e);
|
||||
return;
|
||||
}
|
||||
this._onDidClick.fire(e);
|
||||
}));
|
||||
});
|
||||
this._register(addDisposableListener(this._element, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let eventHandled = false;
|
||||
if (this.enabled && (event.equals(3 /* KeyCode.Enter */) || event.equals(10 /* KeyCode.Space */))) {
|
||||
this._onDidClick.fire(e);
|
||||
eventHandled = true;
|
||||
}
|
||||
else if (event.equals(9 /* KeyCode.Escape */)) {
|
||||
this._onDidEscape.fire(e);
|
||||
this._element.blur();
|
||||
eventHandled = true;
|
||||
}
|
||||
if (eventHandled) {
|
||||
EventHelper.stop(event, true);
|
||||
}
|
||||
}));
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OVER, e => {
|
||||
if (!this._element.classList.contains('disabled')) {
|
||||
this.updateBackground(true);
|
||||
}
|
||||
}));
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OUT, e => {
|
||||
this.updateBackground(false); // restore standard styles
|
||||
}));
|
||||
// Also set hover background when button is focused for feedback
|
||||
this.focusTracker = this._register(trackFocus(this._element));
|
||||
this._register(this.focusTracker.onDidFocus(() => { if (this.enabled) {
|
||||
this.updateBackground(true);
|
||||
} }));
|
||||
this._register(this.focusTracker.onDidBlur(() => { if (this.enabled) {
|
||||
this.updateBackground(false);
|
||||
} }));
|
||||
}
|
||||
dispose() {
|
||||
super.dispose();
|
||||
this._element.remove();
|
||||
}
|
||||
getContentElements(content) {
|
||||
const elements = [];
|
||||
for (let segment of renderLabelWithIcons(content)) {
|
||||
if (typeof (segment) === 'string') {
|
||||
segment = segment.trim();
|
||||
// Ignore empty segment
|
||||
if (segment === '') {
|
||||
continue;
|
||||
}
|
||||
// Convert string segments to <span> nodes
|
||||
const node = document.createElement('span');
|
||||
node.textContent = segment;
|
||||
elements.push(node);
|
||||
}
|
||||
else {
|
||||
elements.push(segment);
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
updateBackground(hover) {
|
||||
let background;
|
||||
if (this.options.secondary) {
|
||||
background = hover ? this.options.buttonSecondaryHoverBackground : this.options.buttonSecondaryBackground;
|
||||
}
|
||||
else {
|
||||
background = hover ? this.options.buttonHoverBackground : this.options.buttonBackground;
|
||||
}
|
||||
if (background) {
|
||||
this._element.style.backgroundColor = background;
|
||||
}
|
||||
}
|
||||
get element() {
|
||||
return this._element;
|
||||
}
|
||||
set label(value) {
|
||||
if (this._label === value) {
|
||||
return;
|
||||
}
|
||||
if (isMarkdownString(this._label) && isMarkdownString(value) && markdownStringEqual(this._label, value)) {
|
||||
return;
|
||||
}
|
||||
this._element.classList.add('monaco-text-button');
|
||||
const labelElement = this.options.supportShortLabel ? this._labelElement : this._element;
|
||||
if (isMarkdownString(value)) {
|
||||
const rendered = renderMarkdown(value, undefined, document.createElement('span'));
|
||||
rendered.dispose();
|
||||
// Don't include outer `<p>`
|
||||
const root = rendered.element.querySelector('p')?.innerHTML;
|
||||
if (root) {
|
||||
safeSetInnerHtml(labelElement, root, buttonSanitizerConfig);
|
||||
}
|
||||
else {
|
||||
reset(labelElement);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.options.supportIcons) {
|
||||
reset(labelElement, ...this.getContentElements(value));
|
||||
}
|
||||
else {
|
||||
labelElement.textContent = value;
|
||||
}
|
||||
}
|
||||
let title = '';
|
||||
if (typeof this.options.title === 'string') {
|
||||
title = this.options.title;
|
||||
}
|
||||
else if (this.options.title) {
|
||||
title = renderAsPlaintext(value);
|
||||
}
|
||||
this.setTitle(title);
|
||||
this._setAriaLabel();
|
||||
this._label = value;
|
||||
}
|
||||
get label() {
|
||||
return this._label;
|
||||
}
|
||||
_setAriaLabel() {
|
||||
if (typeof this.options.ariaLabel === 'string') {
|
||||
this._element.setAttribute('aria-label', this.options.ariaLabel);
|
||||
}
|
||||
else if (typeof this.options.title === 'string') {
|
||||
this._element.setAttribute('aria-label', this.options.title);
|
||||
}
|
||||
}
|
||||
set icon(icon) {
|
||||
this._setAriaLabel();
|
||||
const oldIcons = Array.from(this._element.classList).filter(item => item.startsWith('codicon-'));
|
||||
this._element.classList.remove(...oldIcons);
|
||||
this._element.classList.add(...ThemeIcon.asClassNameArray(icon));
|
||||
}
|
||||
set enabled(value) {
|
||||
if (value) {
|
||||
this._element.classList.remove('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(false));
|
||||
this._element.tabIndex = 0;
|
||||
}
|
||||
else {
|
||||
this._element.classList.add('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(true));
|
||||
}
|
||||
}
|
||||
get enabled() {
|
||||
return !this._element.classList.contains('disabled');
|
||||
}
|
||||
setTitle(title) {
|
||||
if (!this._hover && title !== '') {
|
||||
this._hover = this._register(getBaseLayerHoverDelegate().setupManagedHover(this.options.hoverDelegate ?? getDefaultHoverDelegate('element'), this._element, title));
|
||||
}
|
||||
else if (this._hover) {
|
||||
this._hover.update(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=button.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.codicon-wrench-subaction {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@keyframes codicon-spin {
|
||||
100% {
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.codicon-sync.codicon-modifier-spin,
|
||||
.codicon-loading.codicon-modifier-spin,
|
||||
.codicon-gear.codicon-modifier-spin,
|
||||
.codicon-notebook-state-executing.codicon-modifier-spin {
|
||||
/* Use steps to throttle FPS to reduce CPU usage */
|
||||
animation: codicon-spin 1.5s steps(30) infinite;
|
||||
}
|
||||
|
||||
.codicon-modifier-disabled {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/* custom speed & easing for loading icon */
|
||||
.codicon-loading,
|
||||
.codicon-tree-item-loading::before {
|
||||
animation-duration: 1s !important;
|
||||
animation-timing-function: cubic-bezier(0.53, 0.21, 0.29, 0.67) !important;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
@font-face {
|
||||
font-family: "codicon";
|
||||
font-display: block;
|
||||
src: url(./codicon.ttf) format("truetype");
|
||||
}
|
||||
|
||||
.codicon[class*='codicon-'] {
|
||||
font: normal normal normal 16px/1 codicon;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
text-align: center;
|
||||
text-transform: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
/* icon rules are dynamically created by the platform theme service (see iconsStyleSheet.ts) */
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import './codicon/codicon.css';
|
||||
import './codicon/codicon-modifiers.css';
|
||||
//# sourceMappingURL=codiconStyles.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/ui/codicons/codiconStyles.ts","vs/base/browser/ui/codicons/codiconStyles.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,uBAAuB,CAAC;AAC/B,OAAO,iCAAiC,CAAC","file":"codiconStyles.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport './codicon/codicon.css';\nimport './codicon/codicon-modifiers.css';\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport './codicon/codicon.css';\nimport './codicon/codicon-modifiers.css';\n"]}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.context-view {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.context-view.fixed {
|
||||
all: initial;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
position: fixed;
|
||||
color: inherit;
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { BrowserFeatures } from '../../canIUse.js';
|
||||
import * as DOM from '../../dom.js';
|
||||
import { Disposable, DisposableStore, toDisposable } from '../../../common/lifecycle.js';
|
||||
import * as platform from '../../../common/platform.js';
|
||||
import { Range } from '../../../common/range.js';
|
||||
import './contextview.css';
|
||||
export function isAnchor(obj) {
|
||||
const anchor = obj;
|
||||
return !!anchor && typeof anchor.x === 'number' && typeof anchor.y === 'number';
|
||||
}
|
||||
export var LayoutAnchorMode;
|
||||
(function (LayoutAnchorMode) {
|
||||
LayoutAnchorMode[LayoutAnchorMode["AVOID"] = 0] = "AVOID";
|
||||
LayoutAnchorMode[LayoutAnchorMode["ALIGN"] = 1] = "ALIGN";
|
||||
})(LayoutAnchorMode || (LayoutAnchorMode = {}));
|
||||
/**
|
||||
* Lays out a one dimensional view next to an anchor in a viewport.
|
||||
*
|
||||
* @returns The view offset within the viewport.
|
||||
*/
|
||||
export function layout(viewportSize, viewSize, anchor) {
|
||||
const layoutAfterAnchorBoundary = anchor.mode === LayoutAnchorMode.ALIGN ? anchor.offset : anchor.offset + anchor.size;
|
||||
const layoutBeforeAnchorBoundary = anchor.mode === LayoutAnchorMode.ALIGN ? anchor.offset + anchor.size : anchor.offset;
|
||||
if (anchor.position === 0 /* LayoutAnchorPosition.Before */) {
|
||||
if (viewSize <= viewportSize - layoutAfterAnchorBoundary) {
|
||||
return layoutAfterAnchorBoundary; // happy case, lay it out after the anchor
|
||||
}
|
||||
if (viewSize <= layoutBeforeAnchorBoundary) {
|
||||
return layoutBeforeAnchorBoundary - viewSize; // ok case, lay it out before the anchor
|
||||
}
|
||||
return Math.max(viewportSize - viewSize, 0); // sad case, lay it over the anchor
|
||||
}
|
||||
else {
|
||||
if (viewSize <= layoutBeforeAnchorBoundary) {
|
||||
return layoutBeforeAnchorBoundary - viewSize; // happy case, lay it out before the anchor
|
||||
}
|
||||
if (viewSize <= viewportSize - layoutAfterAnchorBoundary) {
|
||||
return layoutAfterAnchorBoundary; // ok case, lay it out after the anchor
|
||||
}
|
||||
return 0; // sad case, lay it over the anchor
|
||||
}
|
||||
}
|
||||
export class ContextView extends Disposable {
|
||||
static { this.BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur']; }
|
||||
static { this.BUBBLE_DOWN_EVENTS = ['click']; }
|
||||
constructor(container, domPosition) {
|
||||
super();
|
||||
this.container = null;
|
||||
this.useFixedPosition = false;
|
||||
this.useShadowDOM = false;
|
||||
this.delegate = null;
|
||||
this.toDisposeOnClean = Disposable.None;
|
||||
this.toDisposeOnSetContainer = Disposable.None;
|
||||
this.shadowRoot = null;
|
||||
this.shadowRootHostElement = null;
|
||||
this.view = DOM.$('.context-view');
|
||||
DOM.hide(this.view);
|
||||
this.setContainer(container, domPosition);
|
||||
this._register(toDisposable(() => this.setContainer(null, 1 /* ContextViewDOMPosition.ABSOLUTE */)));
|
||||
}
|
||||
setContainer(container, domPosition) {
|
||||
this.useFixedPosition = domPosition !== 1 /* ContextViewDOMPosition.ABSOLUTE */;
|
||||
const usedShadowDOM = this.useShadowDOM;
|
||||
this.useShadowDOM = domPosition === 3 /* ContextViewDOMPosition.FIXED_SHADOW */;
|
||||
if (container === this.container && usedShadowDOM === this.useShadowDOM) {
|
||||
return; // container is the same and no shadow DOM usage has changed
|
||||
}
|
||||
if (this.container) {
|
||||
this.toDisposeOnSetContainer.dispose();
|
||||
this.view.remove();
|
||||
if (this.shadowRoot) {
|
||||
this.shadowRoot = null;
|
||||
this.shadowRootHostElement?.remove();
|
||||
this.shadowRootHostElement = null;
|
||||
}
|
||||
this.container = null;
|
||||
}
|
||||
if (container) {
|
||||
this.container = container;
|
||||
if (this.useShadowDOM) {
|
||||
this.shadowRootHostElement = DOM.$('.shadow-root-host');
|
||||
this.container.appendChild(this.shadowRootHostElement);
|
||||
this.shadowRoot = this.shadowRootHostElement.attachShadow({ mode: 'open' });
|
||||
const style = document.createElement('style');
|
||||
style.textContent = SHADOW_ROOT_CSS;
|
||||
this.shadowRoot.appendChild(style);
|
||||
this.shadowRoot.appendChild(this.view);
|
||||
this.shadowRoot.appendChild(DOM.$('slot'));
|
||||
}
|
||||
else {
|
||||
this.container.appendChild(this.view);
|
||||
}
|
||||
const toDisposeOnSetContainer = new DisposableStore();
|
||||
ContextView.BUBBLE_UP_EVENTS.forEach(event => {
|
||||
toDisposeOnSetContainer.add(DOM.addStandardDisposableListener(this.container, event, e => {
|
||||
this.onDOMEvent(e, false);
|
||||
}));
|
||||
});
|
||||
ContextView.BUBBLE_DOWN_EVENTS.forEach(event => {
|
||||
toDisposeOnSetContainer.add(DOM.addStandardDisposableListener(this.container, event, e => {
|
||||
this.onDOMEvent(e, true);
|
||||
}, true));
|
||||
});
|
||||
this.toDisposeOnSetContainer = toDisposeOnSetContainer;
|
||||
}
|
||||
}
|
||||
show(delegate) {
|
||||
if (this.isVisible()) {
|
||||
this.hide();
|
||||
}
|
||||
// Show static box
|
||||
DOM.clearNode(this.view);
|
||||
this.view.className = 'context-view monaco-component';
|
||||
this.view.style.top = '0px';
|
||||
this.view.style.left = '0px';
|
||||
this.view.style.zIndex = `${2575 + (delegate.layer ?? 0)}`;
|
||||
this.view.style.position = this.useFixedPosition ? 'fixed' : 'absolute';
|
||||
DOM.show(this.view);
|
||||
// Render content
|
||||
this.toDisposeOnClean = delegate.render(this.view) || Disposable.None;
|
||||
// Set active delegate
|
||||
this.delegate = delegate;
|
||||
// Layout
|
||||
this.doLayout();
|
||||
// Focus
|
||||
this.delegate.focus?.();
|
||||
}
|
||||
getViewElement() {
|
||||
return this.view;
|
||||
}
|
||||
layout() {
|
||||
if (!this.isVisible()) {
|
||||
return;
|
||||
}
|
||||
if (this.delegate.canRelayout === false && !(platform.isIOS && BrowserFeatures.pointerEvents)) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
this.delegate?.layout?.();
|
||||
this.doLayout();
|
||||
}
|
||||
doLayout() {
|
||||
// Check that we still have a delegate - this.delegate.layout may have hidden
|
||||
if (!this.isVisible()) {
|
||||
return;
|
||||
}
|
||||
// Get anchor
|
||||
const anchor = this.delegate.getAnchor();
|
||||
// Compute around
|
||||
let around;
|
||||
// Get the element's position and size (to anchor the view)
|
||||
if (DOM.isHTMLElement(anchor)) {
|
||||
const elementPosition = DOM.getDomNodePagePosition(anchor);
|
||||
// In areas where zoom is applied to the element or its ancestors, we need to adjust the size of the element
|
||||
// e.g. The title bar has counter zoom behavior meaning it applies the inverse of zoom level.
|
||||
// Window Zoom Level: 1.5, Title Bar Zoom: 1/1.5, Size Multiplier: 1.5
|
||||
const zoom = DOM.getDomNodeZoomLevel(anchor);
|
||||
around = {
|
||||
top: elementPosition.top * zoom,
|
||||
left: elementPosition.left * zoom,
|
||||
width: elementPosition.width * zoom,
|
||||
height: elementPosition.height * zoom
|
||||
};
|
||||
}
|
||||
else if (isAnchor(anchor)) {
|
||||
around = {
|
||||
top: anchor.y,
|
||||
left: anchor.x,
|
||||
width: anchor.width || 1,
|
||||
height: anchor.height || 2
|
||||
};
|
||||
}
|
||||
else {
|
||||
around = {
|
||||
top: anchor.posy,
|
||||
left: anchor.posx,
|
||||
// We are about to position the context view where the mouse
|
||||
// cursor is. To prevent the view being exactly under the mouse
|
||||
// when showing and thus potentially triggering an action within,
|
||||
// we treat the mouse location like a small sized block element.
|
||||
width: 2,
|
||||
height: 2
|
||||
};
|
||||
}
|
||||
const viewSizeWidth = DOM.getTotalWidth(this.view);
|
||||
const viewSizeHeight = DOM.getTotalHeight(this.view);
|
||||
const anchorPosition = this.delegate.anchorPosition ?? 0 /* AnchorPosition.BELOW */;
|
||||
const anchorAlignment = this.delegate.anchorAlignment ?? 0 /* AnchorAlignment.LEFT */;
|
||||
const anchorAxisAlignment = this.delegate.anchorAxisAlignment ?? 0 /* AnchorAxisAlignment.VERTICAL */;
|
||||
let top;
|
||||
let left;
|
||||
const activeWindow = DOM.getActiveWindow();
|
||||
if (anchorAxisAlignment === 0 /* AnchorAxisAlignment.VERTICAL */) {
|
||||
const verticalAnchor = { offset: around.top - activeWindow.pageYOffset, size: around.height, position: anchorPosition === 0 /* AnchorPosition.BELOW */ ? 0 /* LayoutAnchorPosition.Before */ : 1 /* LayoutAnchorPosition.After */ };
|
||||
const horizontalAnchor = { offset: around.left, size: around.width, position: anchorAlignment === 0 /* AnchorAlignment.LEFT */ ? 0 /* LayoutAnchorPosition.Before */ : 1 /* LayoutAnchorPosition.After */, mode: LayoutAnchorMode.ALIGN };
|
||||
top = layout(activeWindow.innerHeight, viewSizeHeight, verticalAnchor) + activeWindow.pageYOffset;
|
||||
// if view intersects vertically with anchor, we must avoid the anchor
|
||||
if (Range.intersects({ start: top, end: top + viewSizeHeight }, { start: verticalAnchor.offset, end: verticalAnchor.offset + verticalAnchor.size })) {
|
||||
horizontalAnchor.mode = LayoutAnchorMode.AVOID;
|
||||
}
|
||||
left = layout(activeWindow.innerWidth, viewSizeWidth, horizontalAnchor);
|
||||
}
|
||||
else {
|
||||
const horizontalAnchor = { offset: around.left, size: around.width, position: anchorAlignment === 0 /* AnchorAlignment.LEFT */ ? 0 /* LayoutAnchorPosition.Before */ : 1 /* LayoutAnchorPosition.After */ };
|
||||
const verticalAnchor = { offset: around.top, size: around.height, position: anchorPosition === 0 /* AnchorPosition.BELOW */ ? 0 /* LayoutAnchorPosition.Before */ : 1 /* LayoutAnchorPosition.After */, mode: LayoutAnchorMode.ALIGN };
|
||||
left = layout(activeWindow.innerWidth, viewSizeWidth, horizontalAnchor);
|
||||
// if view intersects horizontally with anchor, we must avoid the anchor
|
||||
if (Range.intersects({ start: left, end: left + viewSizeWidth }, { start: horizontalAnchor.offset, end: horizontalAnchor.offset + horizontalAnchor.size })) {
|
||||
verticalAnchor.mode = LayoutAnchorMode.AVOID;
|
||||
}
|
||||
top = layout(activeWindow.innerHeight, viewSizeHeight, verticalAnchor) + activeWindow.pageYOffset;
|
||||
}
|
||||
this.view.classList.remove('top', 'bottom', 'left', 'right');
|
||||
this.view.classList.add(anchorPosition === 0 /* AnchorPosition.BELOW */ ? 'bottom' : 'top');
|
||||
this.view.classList.add(anchorAlignment === 0 /* AnchorAlignment.LEFT */ ? 'left' : 'right');
|
||||
this.view.classList.toggle('fixed', this.useFixedPosition);
|
||||
const containerPosition = DOM.getDomNodePagePosition(this.container);
|
||||
// Account for container scroll when positioning the context view
|
||||
const containerScrollTop = this.container.scrollTop || 0;
|
||||
const containerScrollLeft = this.container.scrollLeft || 0;
|
||||
this.view.style.top = `${top - (this.useFixedPosition ? DOM.getDomNodePagePosition(this.view).top : containerPosition.top) + containerScrollTop}px`;
|
||||
this.view.style.left = `${left - (this.useFixedPosition ? DOM.getDomNodePagePosition(this.view).left : containerPosition.left) + containerScrollLeft}px`;
|
||||
this.view.style.width = 'initial';
|
||||
}
|
||||
hide(data) {
|
||||
const delegate = this.delegate;
|
||||
this.delegate = null;
|
||||
if (delegate?.onHide) {
|
||||
delegate.onHide(data);
|
||||
}
|
||||
this.toDisposeOnClean.dispose();
|
||||
DOM.hide(this.view);
|
||||
}
|
||||
isVisible() {
|
||||
return !!this.delegate;
|
||||
}
|
||||
onDOMEvent(e, onCapture) {
|
||||
if (this.delegate) {
|
||||
if (this.delegate.onDOMEvent) {
|
||||
this.delegate.onDOMEvent(e, DOM.getWindow(e).document.activeElement);
|
||||
}
|
||||
else if (onCapture && !DOM.isAncestor(e.target, this.container)) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
this.hide();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
const SHADOW_ROOT_CSS = /* css */ `
|
||||
:host {
|
||||
all: initial; /* 1st rule so subsequent properties are reset. */
|
||||
}
|
||||
|
||||
.codicon[class*='codicon-'] {
|
||||
font: normal normal normal 16px/1 codicon;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
text-align: center;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
:host {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", system-ui, "Ubuntu", "Droid Sans", sans-serif;
|
||||
}
|
||||
|
||||
:host-context(.mac) { font-family: -apple-system, BlinkMacSystemFont, sans-serif; }
|
||||
:host-context(.mac:lang(zh-Hans)) { font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", sans-serif; }
|
||||
:host-context(.mac:lang(zh-Hant)) { font-family: -apple-system, BlinkMacSystemFont, "PingFang TC", sans-serif; }
|
||||
:host-context(.mac:lang(ja)) { font-family: -apple-system, BlinkMacSystemFont, "Hiragino Kaku Gothic Pro", sans-serif; }
|
||||
:host-context(.mac:lang(ko)) { font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Nanum Gothic", "AppleGothic", sans-serif; }
|
||||
|
||||
:host-context(.windows) { font-family: "Segoe WPC", "Segoe UI", sans-serif; }
|
||||
:host-context(.windows:lang(zh-Hans)) { font-family: "Segoe WPC", "Segoe UI", "Microsoft YaHei", sans-serif; }
|
||||
:host-context(.windows:lang(zh-Hant)) { font-family: "Segoe WPC", "Segoe UI", "Microsoft Jhenghei", sans-serif; }
|
||||
:host-context(.windows:lang(ja)) { font-family: "Segoe WPC", "Segoe UI", "Yu Gothic UI", "Meiryo UI", sans-serif; }
|
||||
:host-context(.windows:lang(ko)) { font-family: "Segoe WPC", "Segoe UI", "Malgun Gothic", "Dotom", sans-serif; }
|
||||
|
||||
:host-context(.linux) { font-family: system-ui, "Ubuntu", "Droid Sans", sans-serif; }
|
||||
:host-context(.linux:lang(zh-Hans)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; }
|
||||
:host-context(.linux:lang(zh-Hant)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans", sans-serif; }
|
||||
:host-context(.linux:lang(ja)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", sans-serif; }
|
||||
:host-context(.linux:lang(ko)) { font-family: system-ui, "Ubuntu", "Droid Sans", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; }
|
||||
`;
|
||||
//# sourceMappingURL=contextview.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-count-badge {
|
||||
padding: 3px 6px;
|
||||
border-radius: 11px;
|
||||
font-size: 11px;
|
||||
min-width: 18px;
|
||||
min-height: 18px;
|
||||
line-height: 11px;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-count-badge.long {
|
||||
padding: 2px 3px;
|
||||
border-radius: 2px;
|
||||
min-height: auto;
|
||||
line-height: normal;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { $, append } from '../../dom.js';
|
||||
import { format } from '../../../common/strings.js';
|
||||
import './countBadge.css';
|
||||
import { Disposable, MutableDisposable, toDisposable } from '../../../common/lifecycle.js';
|
||||
import { getBaseLayerHoverDelegate } from '../hover/hoverDelegate2.js';
|
||||
export class CountBadge extends Disposable {
|
||||
constructor(container, options, styles) {
|
||||
super();
|
||||
this.options = options;
|
||||
this.styles = styles;
|
||||
this.count = 0;
|
||||
this.hover = this._register(new MutableDisposable());
|
||||
this.element = append(container, $('.monaco-count-badge'));
|
||||
this._register(toDisposable(() => container.removeChild(this.element)));
|
||||
this.countFormat = this.options.countFormat || '{0}';
|
||||
this.titleFormat = this.options.titleFormat || '';
|
||||
this.setCount(this.options.count || 0);
|
||||
this.updateHover();
|
||||
}
|
||||
setCount(count) {
|
||||
this.count = count;
|
||||
this.render();
|
||||
}
|
||||
setTitleFormat(titleFormat) {
|
||||
this.titleFormat = titleFormat;
|
||||
this.updateHover();
|
||||
this.render();
|
||||
}
|
||||
updateHover() {
|
||||
if (this.titleFormat !== '' && !this.hover.value) {
|
||||
this.hover.value = getBaseLayerHoverDelegate().setupDelayedHoverAtMouse(this.element, () => ({ content: format(this.titleFormat, this.count), appearance: { compact: true } }));
|
||||
}
|
||||
else if (this.titleFormat === '' && this.hover.value) {
|
||||
this.hover.value = undefined;
|
||||
}
|
||||
}
|
||||
render() {
|
||||
this.element.textContent = format(this.countFormat, this.count);
|
||||
this.element.style.backgroundColor = this.styles.badgeBackground ?? '';
|
||||
this.element.style.color = this.styles.badgeForeground ?? '';
|
||||
if (this.styles.badgeBorder) {
|
||||
this.element.style.border = `1px solid ${this.styles.badgeBorder}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=countBadge.js.map
|
||||
File diff suppressed because one or more lines are too long
246
_internal/editor/esm/vs/base/browser/ui/dialog/dialog.css
Normal file
246
_internal/editor/esm/vs/base/browser/ui/dialog/dialog.css
Normal file
@@ -0,0 +1,246 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/** Dialog: Modal Block */
|
||||
.monaco-dialog-modal-block {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 2575; /* Above Context Views, Below Workbench Hover */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-dialog-modal-block.dimmed {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/** Dialog: Container */
|
||||
.monaco-dialog-box {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
width: min-content;
|
||||
min-width: 500px;
|
||||
max-width: 90vw;
|
||||
min-height: 75px;
|
||||
padding: 10px;
|
||||
transform: translate3d(0px, 0px, 0px);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical {
|
||||
min-width: 350px; /* more narrow when aligned vertically */
|
||||
}
|
||||
|
||||
/** Dialog: Title Actions Row */
|
||||
.monaco-dialog-box .dialog-toolbar-row {
|
||||
height: 22px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-toolbar-row .actions-container {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/** Dialog: Message/Footer Row */
|
||||
.monaco-dialog-box .dialog-message-row,
|
||||
.monaco-dialog-box .dialog-footer-row {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical .dialog-message-row {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-message-row > .dialog-icon.codicon {
|
||||
flex: 0 0 48px;
|
||||
height: 48px;
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical .dialog-message-row > .dialog-icon.codicon {
|
||||
flex: 0 0 64px;
|
||||
height: 64px;
|
||||
font-size: 64px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box:not(.align-vertical) .dialog-message-row > .dialog-icon.codicon {
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
/** Dialog: Message/Footer Container */
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container,
|
||||
.monaco-dialog-box .dialog-footer-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
user-select: text;
|
||||
-webkit-user-select: text;
|
||||
word-wrap: break-word; /* never overflow long words, but break to next line */
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-footer-row {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box:not(.align-vertical) .dialog-message-row .dialog-message-container,
|
||||
.monaco-dialog-box:not(.align-vertical) .dialog-footer-row {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical .dialog-message-row .dialog-message-container,
|
||||
.monaco-dialog-box.align-vertical .dialog-footer-row {
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container ul,
|
||||
.monaco-dialog-box .dialog-footer-row ul {
|
||||
padding-inline-start: 20px; /* reduce excessive indent of list items in the dialog */
|
||||
}
|
||||
|
||||
/** Dialog: Message */
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-message {
|
||||
line-height: 22px;
|
||||
font-size: 18px;
|
||||
flex: 1; /* let the message always grow */
|
||||
white-space: normal;
|
||||
word-wrap: break-word; /* never overflow long words, but break to next line */
|
||||
min-height: 48px; /* matches icon height */
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/** Dialog: Details */
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-message-detail {
|
||||
line-height: 22px;
|
||||
flex: 1; /* let the message always grow */
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-message a:focus {
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
/** Dialog: Checkbox */
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-checkbox-row {
|
||||
padding: 15px 0px 0px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-checkbox-row .dialog-checkbox-message {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/** Dialog: Input */
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-message-input {
|
||||
padding: 15px 0px 0px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-dialog-box .dialog-message-row .dialog-message-container .dialog-message-input .monaco-inputbox {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/** Dialog: File Path */
|
||||
.monaco-dialog-box code {
|
||||
font-family: var(--monaco-monospace-font);
|
||||
}
|
||||
|
||||
/** Dialog: Buttons Row */
|
||||
.monaco-dialog-box > .dialog-buttons-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 1px;
|
||||
overflow: hidden; /* buttons row should never overflow */
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
padding: 20px 10px 10px;
|
||||
}
|
||||
|
||||
/** Dialog: Buttons */
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.monaco-dialog-box:not(.align-vertical) > .dialog-buttons-row > .dialog-buttons {
|
||||
overflow: hidden;
|
||||
justify-content: flex-end;
|
||||
margin-left: 67px; /* for long buttons, force align with text */
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical > .dialog-buttons-row > .dialog-buttons {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons > .monaco-button {
|
||||
padding: 4px 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 4px 5px; /* allows button focus outline to be visible */
|
||||
outline-offset: 2px !important;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical > .dialog-buttons-row > .dialog-buttons > .monaco-button {
|
||||
margin: 4px 0; /* allows button focus outline to be visible */
|
||||
}
|
||||
|
||||
.monaco-dialog-box:not(.align-vertical) > .dialog-buttons-row > .dialog-buttons > .monaco-button {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
/** Dialog: Dropdown */
|
||||
.monaco-dialog-box:not(.align-vertical) > .dialog-buttons-row > .dialog-buttons > .monaco-button-dropdown {
|
||||
margin: 4px 5px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical > .dialog-buttons-row > .dialog-buttons > .monaco-button-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons > .monaco-button-dropdown:focus-within {
|
||||
/**
|
||||
* This is a trick to make the focus outline appear on the entire
|
||||
* container of the dropdown button to ensure the dialog box looks
|
||||
* consistent to dialogs without dropdown buttons.
|
||||
*/
|
||||
outline-offset: 2px !important;
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
outline-color: var(--vscode-focusBorder);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons > .monaco-button-dropdown > .monaco-text-button {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-dialog-box.align-vertical > .dialog-buttons-row > .dialog-buttons > .monaco-button-dropdown > .monaco-text-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.monaco-dialog-box > .dialog-buttons-row > .dialog-buttons > .monaco-button-dropdown > .monaco-dropdown-button {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
6
_internal/editor/esm/vs/base/browser/ui/dialog/dialog.js
Normal file
6
_internal/editor/esm/vs/base/browser/ui/dialog/dialog.js
Normal file
@@ -0,0 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import './dialog.css';
|
||||
//# sourceMappingURL=dialog.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/ui/dialog/dialog.ts","vs/base/browser/ui/dialog/dialog.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,cAAc,CAAC","file":"dialog.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport './dialog.css';\n\nexport interface IDialogStyles {\n\treadonly dialogForeground: string | undefined;\n\treadonly dialogBackground: string | undefined;\n\treadonly dialogShadow: string | undefined;\n\treadonly dialogBorder: string | undefined;\n\treadonly errorIconForeground: string | undefined;\n\treadonly warningIconForeground: string | undefined;\n\treadonly infoIconForeground: string | undefined;\n\treadonly textLinkForeground: string | undefined;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport './dialog.css';\n\nexport interface IDialogStyles {\n\treadonly dialogForeground: string | undefined;\n\treadonly dialogBackground: string | undefined;\n\treadonly dialogShadow: string | undefined;\n\treadonly dialogBorder: string | undefined;\n\treadonly errorIconForeground: string | undefined;\n\treadonly warningIconForeground: string | undefined;\n\treadonly infoIconForeground: string | undefined;\n\treadonly textLinkForeground: string | undefined;\n}\n"]}
|
||||
28
_internal/editor/esm/vs/base/browser/ui/dnd/dnd.css
Normal file
28
_internal/editor/esm/vs/base/browser/ui/dnd/dnd.css
Normal file
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-drag-image {
|
||||
display: inline-block;
|
||||
padding: 1px 7px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
|
||||
/* Default styles */
|
||||
background-color: var(--vscode-list-activeSelectionBackground);
|
||||
color: var(--vscode-list-activeSelectionForeground);
|
||||
outline: 1px solid var(--vscode-list-focusOutline);
|
||||
outline-offset: -1px;
|
||||
|
||||
/*
|
||||
* Browsers apply an effect to the drag image when the div becomes too
|
||||
* large which makes them unreadable. Use max width so it does not happen
|
||||
*/
|
||||
max-width: 120px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
26
_internal/editor/esm/vs/base/browser/ui/dnd/dnd.js
Normal file
26
_internal/editor/esm/vs/base/browser/ui/dnd/dnd.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { $ } from '../../dom.js';
|
||||
import './dnd.css';
|
||||
export function applyDragImage(event, container, label, extraClasses = []) {
|
||||
if (!event.dataTransfer) {
|
||||
return;
|
||||
}
|
||||
const dragImage = $('.monaco-drag-image');
|
||||
dragImage.textContent = label;
|
||||
dragImage.classList.add(...extraClasses);
|
||||
const getDragImageContainer = (e) => {
|
||||
while (e && !e.classList.contains('monaco-workbench')) {
|
||||
e = e.parentElement;
|
||||
}
|
||||
return e || container.ownerDocument.body;
|
||||
};
|
||||
const dragContainer = getDragImageContainer(container);
|
||||
dragContainer.appendChild(dragImage);
|
||||
event.dataTransfer.setDragImage(dragImage, -10, -10);
|
||||
// Removes the element when the DND operation is done
|
||||
setTimeout(() => dragImage.remove(), 0);
|
||||
}
|
||||
//# sourceMappingURL=dnd.js.map
|
||||
1
_internal/editor/esm/vs/base/browser/ui/dnd/dnd.js.map
Normal file
1
_internal/editor/esm/vs/base/browser/ui/dnd/dnd.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/ui/dnd/dnd.ts","vs/base/browser/ui/dnd/dnd.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC,OAAO,WAAW,CAAC;AAEnB,MAAM,UAAU,cAAc,CAAC,KAAgB,EAAE,SAAsB,EAAE,KAAa,EAAE,eAAyB,EAAE;IAClH,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QACzB,OAAO;IACR,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC1C,SAAS,CAAC,WAAW,GAAG,KAAK,CAAC;IAC9B,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IAEzC,MAAM,qBAAqB,GAAG,CAAC,CAAqB,EAAE,EAAE;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACvD,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,IAAI,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC;IAC1C,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IACvD,aAAa,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACrC,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAErD,qDAAqD;IACrD,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC","file":"dnd.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { $ } from '../../dom.js';\nimport './dnd.css';\n\nexport function applyDragImage(event: DragEvent, container: HTMLElement, label: string, extraClasses: string[] = []): void {\n\tif (!event.dataTransfer) {\n\t\treturn;\n\t}\n\n\tconst dragImage = $('.monaco-drag-image');\n\tdragImage.textContent = label;\n\tdragImage.classList.add(...extraClasses);\n\n\tconst getDragImageContainer = (e: HTMLElement | null) => {\n\t\twhile (e && !e.classList.contains('monaco-workbench')) {\n\t\t\te = e.parentElement;\n\t\t}\n\t\treturn e || container.ownerDocument.body;\n\t};\n\n\tconst dragContainer = getDragImageContainer(container);\n\tdragContainer.appendChild(dragImage);\n\tevent.dataTransfer.setDragImage(dragImage, -10, -10);\n\n\t// Removes the element when the DND operation is done\n\tsetTimeout(() => dragImage.remove(), 0);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { $ } from '../../dom.js';\nimport './dnd.css';\n\nexport function applyDragImage(event: DragEvent, container: HTMLElement, label: string, extraClasses: string[] = []): void {\n\tif (!event.dataTransfer) {\n\t\treturn;\n\t}\n\n\tconst dragImage = $('.monaco-drag-image');\n\tdragImage.textContent = label;\n\tdragImage.classList.add(...extraClasses);\n\n\tconst getDragImageContainer = (e: HTMLElement | null) => {\n\t\twhile (e && !e.classList.contains('monaco-workbench')) {\n\t\t\te = e.parentElement;\n\t\t}\n\t\treturn e || container.ownerDocument.body;\n\t};\n\n\tconst dragContainer = getDragImageContainer(container);\n\tdragContainer.appendChild(dragImage);\n\tevent.dataTransfer.setDragImage(dragImage, -10, -10);\n\n\t// Removes the element when the DND operation is done\n\tsetTimeout(() => dragImage.remove(), 0);\n}\n"]}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-dropdown {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.monaco-dropdown > .dropdown-label {
|
||||
cursor: pointer;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.monaco-dropdown > .dropdown-label > .action-label.disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary {
|
||||
display: flex !important;
|
||||
flex-direction: row;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary > .action-container > .action-label {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary > .dropdown-action-container > .monaco-dropdown > .dropdown-label .codicon[class*='codicon-'] {
|
||||
font-size: 12px;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
line-height: 16px;
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.monaco-dropdown-with-primary > .dropdown-action-container > .monaco-dropdown > .dropdown-label > .action-label {
|
||||
display: block;
|
||||
background-size: 16px;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
139
_internal/editor/esm/vs/base/browser/ui/dropdown/dropdown.js
Normal file
139
_internal/editor/esm/vs/base/browser/ui/dropdown/dropdown.js
Normal file
@@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { $, addDisposableListener, append, EventHelper, EventType, isMouseEvent } from '../../dom.js';
|
||||
import { StandardKeyboardEvent } from '../../keyboardEvent.js';
|
||||
import { EventType as GestureEventType, Gesture } from '../../touch.js';
|
||||
import { ActionRunner } from '../../../common/actions.js';
|
||||
import { Emitter } from '../../../common/event.js';
|
||||
import './dropdown.css';
|
||||
export class BaseDropdown extends ActionRunner {
|
||||
constructor(container, options) {
|
||||
super();
|
||||
this._onDidChangeVisibility = this._register(new Emitter());
|
||||
this.onDidChangeVisibility = this._onDidChangeVisibility.event;
|
||||
this._element = append(container, $('.monaco-dropdown'));
|
||||
this._label = append(this._element, $('.dropdown-label'));
|
||||
let labelRenderer = options.labelRenderer;
|
||||
if (!labelRenderer) {
|
||||
labelRenderer = (container) => {
|
||||
container.textContent = options.label || '';
|
||||
return null;
|
||||
};
|
||||
}
|
||||
for (const event of [EventType.CLICK, EventType.MOUSE_DOWN, GestureEventType.Tap]) {
|
||||
this._register(addDisposableListener(this.element, event, e => EventHelper.stop(e, true))); // prevent default click behaviour to trigger
|
||||
}
|
||||
for (const event of [EventType.MOUSE_DOWN, GestureEventType.Tap]) {
|
||||
this._register(addDisposableListener(this._label, event, e => {
|
||||
if (isMouseEvent(e) && e.button !== 0) {
|
||||
// prevent right click trigger to allow separate context menu (https://github.com/microsoft/vscode/issues/151064)
|
||||
return;
|
||||
}
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
}
|
||||
else {
|
||||
this.show();
|
||||
}
|
||||
}));
|
||||
}
|
||||
this._register(addDisposableListener(this._label, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if (event.equals(3 /* KeyCode.Enter */) || event.equals(10 /* KeyCode.Space */)) {
|
||||
EventHelper.stop(e, true); // https://github.com/microsoft/vscode/issues/57997
|
||||
if (this.visible) {
|
||||
this.hide();
|
||||
}
|
||||
else {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
}));
|
||||
const cleanupFn = labelRenderer(this._label);
|
||||
if (cleanupFn) {
|
||||
this._register(cleanupFn);
|
||||
}
|
||||
this._register(Gesture.addTarget(this._label));
|
||||
}
|
||||
get element() {
|
||||
return this._element;
|
||||
}
|
||||
show() {
|
||||
if (!this.visible) {
|
||||
this.visible = true;
|
||||
this._onDidChangeVisibility.fire(true);
|
||||
}
|
||||
}
|
||||
hide() {
|
||||
if (this.visible) {
|
||||
this.visible = false;
|
||||
this._onDidChangeVisibility.fire(false);
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
super.dispose();
|
||||
this.hide();
|
||||
if (this.boxContainer) {
|
||||
this.boxContainer.remove();
|
||||
this.boxContainer = undefined;
|
||||
}
|
||||
if (this.contents) {
|
||||
this.contents.remove();
|
||||
this.contents = undefined;
|
||||
}
|
||||
if (this._label) {
|
||||
this._label.remove();
|
||||
this._label = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
export class DropdownMenu extends BaseDropdown {
|
||||
constructor(container, _options) {
|
||||
super(container, _options);
|
||||
this._options = _options;
|
||||
this._actions = [];
|
||||
this.actions = _options.actions || [];
|
||||
}
|
||||
set menuOptions(options) {
|
||||
this._menuOptions = options;
|
||||
}
|
||||
get menuOptions() {
|
||||
return this._menuOptions;
|
||||
}
|
||||
get actions() {
|
||||
if (this._options.actionProvider) {
|
||||
return this._options.actionProvider.getActions();
|
||||
}
|
||||
return this._actions;
|
||||
}
|
||||
set actions(actions) {
|
||||
this._actions = actions;
|
||||
}
|
||||
show() {
|
||||
super.show();
|
||||
this.element.classList.add('active');
|
||||
this._options.contextMenuProvider.showContextMenu({
|
||||
getAnchor: () => this.element,
|
||||
getActions: () => this.actions,
|
||||
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
|
||||
getActionViewItem: (action, options) => this.menuOptions && this.menuOptions.actionViewItemProvider ? this.menuOptions.actionViewItemProvider(action, options) : undefined,
|
||||
getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : undefined,
|
||||
getMenuClassName: () => this._options.menuClassName || '',
|
||||
onHide: () => this.onHide(),
|
||||
actionRunner: this.menuOptions ? this.menuOptions.actionRunner : undefined,
|
||||
anchorAlignment: this.menuOptions ? this.menuOptions.anchorAlignment : 0 /* AnchorAlignment.LEFT */,
|
||||
domForShadowRoot: this._options.menuAsChild ? this.element : undefined,
|
||||
skipTelemetry: this._options.skipTelemetry
|
||||
});
|
||||
}
|
||||
hide() {
|
||||
super.hide();
|
||||
}
|
||||
onHide() {
|
||||
this.hide();
|
||||
this.element.classList.remove('active');
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=dropdown.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,107 @@
|
||||
import { Emitter } from '../../../common/event.js';
|
||||
import { $, append } from '../../dom.js';
|
||||
import { BaseActionViewItem } from '../actionbar/actionViewItems.js';
|
||||
import { getBaseLayerHoverDelegate } from '../hover/hoverDelegate2.js';
|
||||
import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
import './dropdown.css';
|
||||
import { DropdownMenu } from './dropdown.js';
|
||||
export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
||||
get onDidChangeVisibility() { return this._onDidChangeVisibility.event; }
|
||||
constructor(action, menuActionsOrProvider, contextMenuProvider, options = Object.create(null)) {
|
||||
super(null, action, options);
|
||||
this.actionItem = null;
|
||||
this._onDidChangeVisibility = this._register(new Emitter());
|
||||
this.menuActionsOrProvider = menuActionsOrProvider;
|
||||
this.contextMenuProvider = contextMenuProvider;
|
||||
this.options = options;
|
||||
if (this.options.actionRunner) {
|
||||
this.actionRunner = this.options.actionRunner;
|
||||
}
|
||||
}
|
||||
render(container) {
|
||||
this.actionItem = container;
|
||||
const labelRenderer = (el) => {
|
||||
this.element = append(el, $('a.action-label'));
|
||||
return this.renderLabel(this.element);
|
||||
};
|
||||
const isActionsArray = Array.isArray(this.menuActionsOrProvider);
|
||||
const options = {
|
||||
contextMenuProvider: this.contextMenuProvider,
|
||||
labelRenderer: labelRenderer,
|
||||
menuAsChild: this.options.menuAsChild,
|
||||
actions: isActionsArray ? this.menuActionsOrProvider : undefined,
|
||||
actionProvider: isActionsArray ? undefined : this.menuActionsOrProvider,
|
||||
skipTelemetry: this.options.skipTelemetry
|
||||
};
|
||||
this.dropdownMenu = this._register(new DropdownMenu(container, options));
|
||||
this._register(this.dropdownMenu.onDidChangeVisibility(visible => {
|
||||
this.element?.setAttribute('aria-expanded', `${visible}`);
|
||||
this._onDidChangeVisibility.fire(visible);
|
||||
}));
|
||||
this.dropdownMenu.menuOptions = {
|
||||
actionViewItemProvider: this.options.actionViewItemProvider,
|
||||
actionRunner: this.actionRunner,
|
||||
getKeyBinding: this.options.keybindingProvider,
|
||||
context: this._context
|
||||
};
|
||||
if (this.options.anchorAlignmentProvider) {
|
||||
const that = this;
|
||||
this.dropdownMenu.menuOptions = {
|
||||
...this.dropdownMenu.menuOptions,
|
||||
get anchorAlignment() {
|
||||
return that.options.anchorAlignmentProvider();
|
||||
}
|
||||
};
|
||||
}
|
||||
this.updateTooltip();
|
||||
this.updateEnabled();
|
||||
}
|
||||
renderLabel(element) {
|
||||
let classNames = [];
|
||||
if (typeof this.options.classNames === 'string') {
|
||||
classNames = this.options.classNames.split(/\s+/g).filter(s => !!s);
|
||||
}
|
||||
else if (this.options.classNames) {
|
||||
classNames = this.options.classNames;
|
||||
}
|
||||
// todo@aeschli: remove codicon, should come through `this.options.classNames`
|
||||
if (!classNames.find(c => c === 'icon')) {
|
||||
classNames.push('codicon');
|
||||
}
|
||||
element.classList.add(...classNames);
|
||||
if (this._action.label) {
|
||||
this._register(getBaseLayerHoverDelegate().setupManagedHover(this.options.hoverDelegate ?? getDefaultHoverDelegate('mouse'), element, this._action.label));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
getTooltip() {
|
||||
let title = null;
|
||||
if (this.action.tooltip) {
|
||||
title = this.action.tooltip;
|
||||
}
|
||||
else if (this.action.label) {
|
||||
title = this.action.label;
|
||||
}
|
||||
return title ?? undefined;
|
||||
}
|
||||
setActionContext(newContext) {
|
||||
super.setActionContext(newContext);
|
||||
if (this.dropdownMenu) {
|
||||
if (this.dropdownMenu.menuOptions) {
|
||||
this.dropdownMenu.menuOptions.context = newContext;
|
||||
}
|
||||
else {
|
||||
this.dropdownMenu.menuOptions = { context: newContext };
|
||||
}
|
||||
}
|
||||
}
|
||||
show() {
|
||||
this.dropdownMenu?.show();
|
||||
}
|
||||
updateEnabled() {
|
||||
const disabled = !this.action.enabled;
|
||||
this.actionItem?.classList.toggle('disabled', disabled);
|
||||
this.element?.classList.toggle('disabled', disabled);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=dropdownActionViewItem.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,70 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/* ---------- Find input ---------- */
|
||||
|
||||
.monaco-findInput {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.monaco-findInput .monaco-inputbox {
|
||||
font-size: 13px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.monaco-findInput > .controls {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
.vs .monaco-findInput.disabled {
|
||||
background-color: #E1E1E1;
|
||||
}
|
||||
|
||||
/* Theming */
|
||||
.vs-dark .monaco-findInput.disabled {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
/* Highlighting */
|
||||
.monaco-findInput.highlight-0 .controls,
|
||||
.hc-light .monaco-findInput.highlight-0 .controls {
|
||||
animation: monaco-findInput-highlight-0 100ms linear 0s;
|
||||
}
|
||||
|
||||
.monaco-findInput.highlight-1 .controls,
|
||||
.hc-light .monaco-findInput.highlight-1 .controls {
|
||||
animation: monaco-findInput-highlight-1 100ms linear 0s;
|
||||
}
|
||||
|
||||
.hc-black .monaco-findInput.highlight-0 .controls,
|
||||
.vs-dark .monaco-findInput.highlight-0 .controls {
|
||||
animation: monaco-findInput-highlight-dark-0 100ms linear 0s;
|
||||
}
|
||||
|
||||
.hc-black .monaco-findInput.highlight-1 .controls,
|
||||
.vs-dark .monaco-findInput.highlight-1 .controls {
|
||||
animation: monaco-findInput-highlight-dark-1 100ms linear 0s;
|
||||
}
|
||||
|
||||
@keyframes monaco-findInput-highlight-0 {
|
||||
0% { background: rgba(253, 255, 0, 0.8); }
|
||||
100% { background: transparent; }
|
||||
}
|
||||
@keyframes monaco-findInput-highlight-1 {
|
||||
0% { background: rgba(253, 255, 0, 0.8); }
|
||||
/* Made intentionally different such that the CSS minifier does not collapse the two animations into a single one*/
|
||||
99% { background: transparent; }
|
||||
}
|
||||
|
||||
@keyframes monaco-findInput-highlight-dark-0 {
|
||||
0% { background: rgba(255, 255, 255, 0.44); }
|
||||
100% { background: transparent; }
|
||||
}
|
||||
@keyframes monaco-findInput-highlight-dark-1 {
|
||||
0% { background: rgba(255, 255, 255, 0.44); }
|
||||
/* Made intentionally different such that the CSS minifier does not collapse the two animations into a single one*/
|
||||
99% { background: transparent; }
|
||||
}
|
||||
293
_internal/editor/esm/vs/base/browser/ui/findinput/findInput.js
Normal file
293
_internal/editor/esm/vs/base/browser/ui/findinput/findInput.js
Normal file
@@ -0,0 +1,293 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from '../../dom.js';
|
||||
import { CaseSensitiveToggle, RegexToggle, WholeWordsToggle } from './findInputToggles.js';
|
||||
import { HistoryInputBox } from '../inputbox/inputBox.js';
|
||||
import { Widget } from '../widget.js';
|
||||
import { Emitter } from '../../../common/event.js';
|
||||
import './findInput.css';
|
||||
import * as nls from '../../../../nls.js';
|
||||
import { DisposableStore, MutableDisposable } from '../../../common/lifecycle.js';
|
||||
import { createInstantHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
const NLS_DEFAULT_LABEL = nls.localize(1, "input");
|
||||
export class FindInput extends Widget {
|
||||
get onDidOptionChange() { return this._onDidOptionChange.event; }
|
||||
get onKeyDown() { return this._onKeyDown.event; }
|
||||
get onMouseDown() { return this._onMouseDown.event; }
|
||||
get onCaseSensitiveKeyDown() { return this._onCaseSensitiveKeyDown.event; }
|
||||
get onRegexKeyDown() { return this._onRegexKeyDown.event; }
|
||||
constructor(parent, contextViewProvider, options) {
|
||||
super();
|
||||
this.fixFocusOnOptionClickEnabled = true;
|
||||
this.imeSessionInProgress = false;
|
||||
this.additionalTogglesDisposables = this._register(new MutableDisposable());
|
||||
this.additionalToggles = [];
|
||||
this._onDidOptionChange = this._register(new Emitter());
|
||||
this._onKeyDown = this._register(new Emitter());
|
||||
this._onMouseDown = this._register(new Emitter());
|
||||
this._onInput = this._register(new Emitter());
|
||||
this._onKeyUp = this._register(new Emitter());
|
||||
this._onCaseSensitiveKeyDown = this._register(new Emitter());
|
||||
this._onRegexKeyDown = this._register(new Emitter());
|
||||
this._lastHighlightFindOptions = 0;
|
||||
this.placeholder = options.placeholder || '';
|
||||
this.validation = options.validation;
|
||||
this.label = options.label || NLS_DEFAULT_LABEL;
|
||||
this.showCommonFindToggles = !!options.showCommonFindToggles;
|
||||
const appendCaseSensitiveLabel = options.appendCaseSensitiveLabel || '';
|
||||
const appendWholeWordsLabel = options.appendWholeWordsLabel || '';
|
||||
const appendRegexLabel = options.appendRegexLabel || '';
|
||||
const flexibleHeight = !!options.flexibleHeight;
|
||||
const flexibleWidth = !!options.flexibleWidth;
|
||||
const flexibleMaxHeight = options.flexibleMaxHeight;
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.classList.add('monaco-findInput');
|
||||
this.inputBox = this._register(new HistoryInputBox(this.domNode, contextViewProvider, {
|
||||
placeholder: this.placeholder || '',
|
||||
ariaLabel: this.label || '',
|
||||
validationOptions: {
|
||||
validation: this.validation
|
||||
},
|
||||
showHistoryHint: options.showHistoryHint,
|
||||
flexibleHeight,
|
||||
flexibleWidth,
|
||||
flexibleMaxHeight,
|
||||
inputBoxStyles: options.inputBoxStyles,
|
||||
history: options.history
|
||||
}));
|
||||
const hoverDelegate = this._register(createInstantHoverDelegate());
|
||||
if (this.showCommonFindToggles) {
|
||||
this.regex = this._register(new RegexToggle({
|
||||
appendTitle: appendRegexLabel,
|
||||
isChecked: false,
|
||||
hoverDelegate,
|
||||
...options.toggleStyles
|
||||
}));
|
||||
this._register(this.regex.onChange(viaKeyboard => {
|
||||
this._onDidOptionChange.fire(viaKeyboard);
|
||||
if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
this.validate();
|
||||
}));
|
||||
this._register(this.regex.onKeyDown(e => {
|
||||
this._onRegexKeyDown.fire(e);
|
||||
}));
|
||||
this.wholeWords = this._register(new WholeWordsToggle({
|
||||
appendTitle: appendWholeWordsLabel,
|
||||
isChecked: false,
|
||||
hoverDelegate,
|
||||
...options.toggleStyles
|
||||
}));
|
||||
this._register(this.wholeWords.onChange(viaKeyboard => {
|
||||
this._onDidOptionChange.fire(viaKeyboard);
|
||||
if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
this.validate();
|
||||
}));
|
||||
this.caseSensitive = this._register(new CaseSensitiveToggle({
|
||||
appendTitle: appendCaseSensitiveLabel,
|
||||
isChecked: false,
|
||||
hoverDelegate,
|
||||
...options.toggleStyles
|
||||
}));
|
||||
this._register(this.caseSensitive.onChange(viaKeyboard => {
|
||||
this._onDidOptionChange.fire(viaKeyboard);
|
||||
if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
this.validate();
|
||||
}));
|
||||
this._register(this.caseSensitive.onKeyDown(e => {
|
||||
this._onCaseSensitiveKeyDown.fire(e);
|
||||
}));
|
||||
// Arrow-Key support to navigate between options
|
||||
const indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode];
|
||||
this.onkeydown(this.domNode, (event) => {
|
||||
if (event.equals(15 /* KeyCode.LeftArrow */) || event.equals(17 /* KeyCode.RightArrow */) || event.equals(9 /* KeyCode.Escape */)) {
|
||||
const index = indexes.indexOf(this.domNode.ownerDocument.activeElement);
|
||||
if (index >= 0) {
|
||||
let newIndex = -1;
|
||||
if (event.equals(17 /* KeyCode.RightArrow */)) {
|
||||
newIndex = (index + 1) % indexes.length;
|
||||
}
|
||||
else if (event.equals(15 /* KeyCode.LeftArrow */)) {
|
||||
if (index === 0) {
|
||||
newIndex = indexes.length - 1;
|
||||
}
|
||||
else {
|
||||
newIndex = index - 1;
|
||||
}
|
||||
}
|
||||
if (event.equals(9 /* KeyCode.Escape */)) {
|
||||
indexes[index].blur();
|
||||
this.inputBox.focus();
|
||||
}
|
||||
else if (newIndex >= 0) {
|
||||
indexes[newIndex].focus();
|
||||
}
|
||||
dom.EventHelper.stop(event, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this.controls = document.createElement('div');
|
||||
this.controls.className = 'controls';
|
||||
this.controls.style.display = this.showCommonFindToggles ? '' : 'none';
|
||||
if (this.caseSensitive) {
|
||||
this.controls.append(this.caseSensitive.domNode);
|
||||
}
|
||||
if (this.wholeWords) {
|
||||
this.controls.appendChild(this.wholeWords.domNode);
|
||||
}
|
||||
if (this.regex) {
|
||||
this.controls.appendChild(this.regex.domNode);
|
||||
}
|
||||
this.setAdditionalToggles(options?.additionalToggles);
|
||||
if (this.controls) {
|
||||
this.domNode.appendChild(this.controls);
|
||||
}
|
||||
parent?.appendChild(this.domNode);
|
||||
this._register(dom.addDisposableListener(this.inputBox.inputElement, 'compositionstart', (e) => {
|
||||
this.imeSessionInProgress = true;
|
||||
}));
|
||||
this._register(dom.addDisposableListener(this.inputBox.inputElement, 'compositionend', (e) => {
|
||||
this.imeSessionInProgress = false;
|
||||
this._onInput.fire();
|
||||
}));
|
||||
this.onkeydown(this.inputBox.inputElement, (e) => this._onKeyDown.fire(e));
|
||||
this.onkeyup(this.inputBox.inputElement, (e) => this._onKeyUp.fire(e));
|
||||
this.oninput(this.inputBox.inputElement, (e) => this._onInput.fire());
|
||||
this.onmousedown(this.inputBox.inputElement, (e) => this._onMouseDown.fire(e));
|
||||
}
|
||||
get onDidChange() {
|
||||
return this.inputBox.onDidChange;
|
||||
}
|
||||
layout(style) {
|
||||
this.inputBox.layout();
|
||||
this.updateInputBoxPadding(style.collapsedFindWidget);
|
||||
}
|
||||
enable() {
|
||||
this.domNode.classList.remove('disabled');
|
||||
this.inputBox.enable();
|
||||
this.regex?.enable();
|
||||
this.wholeWords?.enable();
|
||||
this.caseSensitive?.enable();
|
||||
for (const toggle of this.additionalToggles) {
|
||||
toggle.enable();
|
||||
}
|
||||
}
|
||||
disable() {
|
||||
this.domNode.classList.add('disabled');
|
||||
this.inputBox.disable();
|
||||
this.regex?.disable();
|
||||
this.wholeWords?.disable();
|
||||
this.caseSensitive?.disable();
|
||||
for (const toggle of this.additionalToggles) {
|
||||
toggle.disable();
|
||||
}
|
||||
}
|
||||
setFocusInputOnOptionClick(value) {
|
||||
this.fixFocusOnOptionClickEnabled = value;
|
||||
}
|
||||
setEnabled(enabled) {
|
||||
if (enabled) {
|
||||
this.enable();
|
||||
}
|
||||
else {
|
||||
this.disable();
|
||||
}
|
||||
}
|
||||
setAdditionalToggles(toggles) {
|
||||
for (const currentToggle of this.additionalToggles) {
|
||||
currentToggle.domNode.remove();
|
||||
}
|
||||
this.additionalToggles = [];
|
||||
this.additionalTogglesDisposables.value = new DisposableStore();
|
||||
for (const toggle of toggles ?? []) {
|
||||
this.additionalTogglesDisposables.value.add(toggle);
|
||||
this.controls.appendChild(toggle.domNode);
|
||||
this.additionalTogglesDisposables.value.add(toggle.onChange(viaKeyboard => {
|
||||
this._onDidOptionChange.fire(viaKeyboard);
|
||||
if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
}));
|
||||
this.additionalToggles.push(toggle);
|
||||
}
|
||||
if (this.additionalToggles.length > 0) {
|
||||
this.controls.style.display = '';
|
||||
}
|
||||
this.updateInputBoxPadding();
|
||||
}
|
||||
updateInputBoxPadding(controlsHidden = false) {
|
||||
if (controlsHidden) {
|
||||
this.inputBox.paddingRight = 0;
|
||||
}
|
||||
else {
|
||||
this.inputBox.paddingRight =
|
||||
((this.caseSensitive?.width() ?? 0) + (this.wholeWords?.width() ?? 0) + (this.regex?.width() ?? 0))
|
||||
+ this.additionalToggles.reduce((r, t) => r + t.width(), 0);
|
||||
}
|
||||
}
|
||||
getValue() {
|
||||
return this.inputBox.value;
|
||||
}
|
||||
setValue(value) {
|
||||
if (this.inputBox.value !== value) {
|
||||
this.inputBox.value = value;
|
||||
}
|
||||
}
|
||||
select() {
|
||||
this.inputBox.select();
|
||||
}
|
||||
focus() {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
getCaseSensitive() {
|
||||
return this.caseSensitive?.checked ?? false;
|
||||
}
|
||||
setCaseSensitive(value) {
|
||||
if (this.caseSensitive) {
|
||||
this.caseSensitive.checked = value;
|
||||
}
|
||||
}
|
||||
getWholeWords() {
|
||||
return this.wholeWords?.checked ?? false;
|
||||
}
|
||||
setWholeWords(value) {
|
||||
if (this.wholeWords) {
|
||||
this.wholeWords.checked = value;
|
||||
}
|
||||
}
|
||||
getRegex() {
|
||||
return this.regex?.checked ?? false;
|
||||
}
|
||||
setRegex(value) {
|
||||
if (this.regex) {
|
||||
this.regex.checked = value;
|
||||
this.validate();
|
||||
}
|
||||
}
|
||||
focusOnCaseSensitive() {
|
||||
this.caseSensitive?.focus();
|
||||
}
|
||||
highlightFindOptions() {
|
||||
this.domNode.classList.remove('highlight-' + (this._lastHighlightFindOptions));
|
||||
this._lastHighlightFindOptions = 1 - this._lastHighlightFindOptions;
|
||||
this.domNode.classList.add('highlight-' + (this._lastHighlightFindOptions));
|
||||
}
|
||||
validate() {
|
||||
this.inputBox.validate();
|
||||
}
|
||||
showMessage(message) {
|
||||
this.inputBox.showMessage(message);
|
||||
}
|
||||
clearMessage() {
|
||||
this.inputBox.hideMessage();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=findInput.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
import { Toggle } from '../toggle/toggle.js';
|
||||
import { Codicon } from '../../../common/codicons.js';
|
||||
import * as nls from '../../../../nls.js';
|
||||
const NLS_CASE_SENSITIVE_TOGGLE_LABEL = nls.localize(2, "Match Case");
|
||||
const NLS_WHOLE_WORD_TOGGLE_LABEL = nls.localize(3, "Match Whole Word");
|
||||
const NLS_REGEX_TOGGLE_LABEL = nls.localize(4, "Use Regular Expression");
|
||||
export class CaseSensitiveToggle extends Toggle {
|
||||
constructor(opts) {
|
||||
super({
|
||||
icon: Codicon.caseSensitive,
|
||||
title: NLS_CASE_SENSITIVE_TOGGLE_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
hoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
inputActiveOptionForeground: opts.inputActiveOptionForeground,
|
||||
inputActiveOptionBackground: opts.inputActiveOptionBackground
|
||||
});
|
||||
}
|
||||
}
|
||||
export class WholeWordsToggle extends Toggle {
|
||||
constructor(opts) {
|
||||
super({
|
||||
icon: Codicon.wholeWord,
|
||||
title: NLS_WHOLE_WORD_TOGGLE_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
hoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
inputActiveOptionForeground: opts.inputActiveOptionForeground,
|
||||
inputActiveOptionBackground: opts.inputActiveOptionBackground
|
||||
});
|
||||
}
|
||||
}
|
||||
export class RegexToggle extends Toggle {
|
||||
constructor(opts) {
|
||||
super({
|
||||
icon: Codicon.regex,
|
||||
title: NLS_REGEX_TOGGLE_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
hoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
inputActiveOptionForeground: opts.inputActiveOptionForeground,
|
||||
inputActiveOptionBackground: opts.inputActiveOptionBackground
|
||||
});
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=findInputToggles.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["vs/base/browser/ui/findinput/findInputToggles.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAW1C,MAAM,+BAA+B,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAiB,EAAE,YAAY,CAAC,CAAC;AACtF,MAAM,2BAA2B,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAkB,EAAE,kBAAkB,CAAC,CAAC;AACzF,MAAM,sBAAsB,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAkB,EAAE,wBAAwB,CAAC,CAAC;AAE1F,MAAM,OAAO,mBAAoB,SAAQ,MAAM;IAC9C,YAAY,IAA0B;QACrC,KAAK,CAAC;YACL,IAAI,EAAE,OAAO,CAAC,aAAa;YAC3B,KAAK,EAAE,+BAA+B,GAAG,IAAI,CAAC,WAAW;YACzD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,uBAAuB,CAAC,SAAS,CAAC;YACvE,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;YAC7D,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;SAC7D,CAAC,CAAC;IACJ,CAAC;CACD;AAED,MAAM,OAAO,gBAAiB,SAAQ,MAAM;IAC3C,YAAY,IAA0B;QACrC,KAAK,CAAC;YACL,IAAI,EAAE,OAAO,CAAC,SAAS;YACvB,KAAK,EAAE,2BAA2B,GAAG,IAAI,CAAC,WAAW;YACrD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,uBAAuB,CAAC,SAAS,CAAC;YACvE,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;YAC7D,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;SAC7D,CAAC,CAAC;IACJ,CAAC;CACD;AAED,MAAM,OAAO,WAAY,SAAQ,MAAM;IACtC,YAAY,IAA0B;QACrC,KAAK,CAAC;YACL,IAAI,EAAE,OAAO,CAAC,KAAK;YACnB,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAC,WAAW;YAChD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,uBAAuB,CAAC,SAAS,CAAC;YACvE,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;YACrD,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;YAC7D,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;SAC7D,CAAC,CAAC;IACJ,CAAC;CACD","file":"findInputToggles.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';\nimport { IHoverDelegate } from '../hover/hoverDelegate.js';\nimport { Toggle } from '../toggle/toggle.js';\nimport { Codicon } from '../../../common/codicons.js';\nimport * as nls from '../../../../nls.js';\n\nexport interface IFindInputToggleOpts {\n\treadonly appendTitle: string;\n\treadonly isChecked: boolean;\n\treadonly inputActiveOptionBorder: string | undefined;\n\treadonly inputActiveOptionForeground: string | undefined;\n\treadonly inputActiveOptionBackground: string | undefined;\n\treadonly hoverDelegate?: IHoverDelegate;\n}\n\nconst NLS_CASE_SENSITIVE_TOGGLE_LABEL = nls.localize('caseDescription', \"Match Case\");\nconst NLS_WHOLE_WORD_TOGGLE_LABEL = nls.localize('wordsDescription', \"Match Whole Word\");\nconst NLS_REGEX_TOGGLE_LABEL = nls.localize('regexDescription', \"Use Regular Expression\");\n\nexport class CaseSensitiveToggle extends Toggle {\n\tconstructor(opts: IFindInputToggleOpts) {\n\t\tsuper({\n\t\t\ticon: Codicon.caseSensitive,\n\t\t\ttitle: NLS_CASE_SENSITIVE_TOGGLE_LABEL + opts.appendTitle,\n\t\t\tisChecked: opts.isChecked,\n\t\t\thoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),\n\t\t\tinputActiveOptionBorder: opts.inputActiveOptionBorder,\n\t\t\tinputActiveOptionForeground: opts.inputActiveOptionForeground,\n\t\t\tinputActiveOptionBackground: opts.inputActiveOptionBackground\n\t\t});\n\t}\n}\n\nexport class WholeWordsToggle extends Toggle {\n\tconstructor(opts: IFindInputToggleOpts) {\n\t\tsuper({\n\t\t\ticon: Codicon.wholeWord,\n\t\t\ttitle: NLS_WHOLE_WORD_TOGGLE_LABEL + opts.appendTitle,\n\t\t\tisChecked: opts.isChecked,\n\t\t\thoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),\n\t\t\tinputActiveOptionBorder: opts.inputActiveOptionBorder,\n\t\t\tinputActiveOptionForeground: opts.inputActiveOptionForeground,\n\t\t\tinputActiveOptionBackground: opts.inputActiveOptionBackground\n\t\t});\n\t}\n}\n\nexport class RegexToggle extends Toggle {\n\tconstructor(opts: IFindInputToggleOpts) {\n\t\tsuper({\n\t\t\ticon: Codicon.regex,\n\t\t\ttitle: NLS_REGEX_TOGGLE_LABEL + opts.appendTitle,\n\t\t\tisChecked: opts.isChecked,\n\t\t\thoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),\n\t\t\tinputActiveOptionBorder: opts.inputActiveOptionBorder,\n\t\t\tinputActiveOptionForeground: opts.inputActiveOptionForeground,\n\t\t\tinputActiveOptionBackground: opts.inputActiveOptionBackground\n\t\t});\n\t}\n}\n"]}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from '../../dom.js';
|
||||
import { Toggle } from '../toggle/toggle.js';
|
||||
import { HistoryInputBox } from '../inputbox/inputBox.js';
|
||||
import { Widget } from '../widget.js';
|
||||
import { Codicon } from '../../../common/codicons.js';
|
||||
import { Emitter } from '../../../common/event.js';
|
||||
import './findInput.css';
|
||||
import * as nls from '../../../../nls.js';
|
||||
import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
const NLS_DEFAULT_LABEL = nls.localize(5, "input");
|
||||
const NLS_PRESERVE_CASE_LABEL = nls.localize(6, "Preserve Case");
|
||||
class PreserveCaseToggle extends Toggle {
|
||||
constructor(opts) {
|
||||
super({
|
||||
// TODO: does this need its own icon?
|
||||
icon: Codicon.preserveCase,
|
||||
title: NLS_PRESERVE_CASE_LABEL + opts.appendTitle,
|
||||
isChecked: opts.isChecked,
|
||||
hoverDelegate: opts.hoverDelegate ?? getDefaultHoverDelegate('element'),
|
||||
inputActiveOptionBorder: opts.inputActiveOptionBorder,
|
||||
inputActiveOptionForeground: opts.inputActiveOptionForeground,
|
||||
inputActiveOptionBackground: opts.inputActiveOptionBackground,
|
||||
});
|
||||
}
|
||||
}
|
||||
export class ReplaceInput extends Widget {
|
||||
get onDidOptionChange() { return this._onDidOptionChange.event; }
|
||||
get onKeyDown() { return this._onKeyDown.event; }
|
||||
get onPreserveCaseKeyDown() { return this._onPreserveCaseKeyDown.event; }
|
||||
constructor(parent, contextViewProvider, _showOptionButtons, options) {
|
||||
super();
|
||||
this._showOptionButtons = _showOptionButtons;
|
||||
this.fixFocusOnOptionClickEnabled = true;
|
||||
this.cachedOptionsWidth = 0;
|
||||
this._onDidOptionChange = this._register(new Emitter());
|
||||
this._onKeyDown = this._register(new Emitter());
|
||||
this._onMouseDown = this._register(new Emitter());
|
||||
this._onInput = this._register(new Emitter());
|
||||
this._onKeyUp = this._register(new Emitter());
|
||||
this._onPreserveCaseKeyDown = this._register(new Emitter());
|
||||
this.contextViewProvider = contextViewProvider;
|
||||
this.placeholder = options.placeholder || '';
|
||||
this.validation = options.validation;
|
||||
this.label = options.label || NLS_DEFAULT_LABEL;
|
||||
const appendPreserveCaseLabel = options.appendPreserveCaseLabel || '';
|
||||
const history = options.history || new Set([]);
|
||||
const flexibleHeight = !!options.flexibleHeight;
|
||||
const flexibleWidth = !!options.flexibleWidth;
|
||||
const flexibleMaxHeight = options.flexibleMaxHeight;
|
||||
this.domNode = document.createElement('div');
|
||||
this.domNode.classList.add('monaco-findInput');
|
||||
this.inputBox = this._register(new HistoryInputBox(this.domNode, this.contextViewProvider, {
|
||||
ariaLabel: this.label || '',
|
||||
placeholder: this.placeholder || '',
|
||||
validationOptions: {
|
||||
validation: this.validation
|
||||
},
|
||||
history,
|
||||
showHistoryHint: options.showHistoryHint,
|
||||
flexibleHeight,
|
||||
flexibleWidth,
|
||||
flexibleMaxHeight,
|
||||
inputBoxStyles: options.inputBoxStyles
|
||||
}));
|
||||
this.preserveCase = this._register(new PreserveCaseToggle({
|
||||
appendTitle: appendPreserveCaseLabel,
|
||||
isChecked: false,
|
||||
...options.toggleStyles
|
||||
}));
|
||||
this._register(this.preserveCase.onChange(viaKeyboard => {
|
||||
this._onDidOptionChange.fire(viaKeyboard);
|
||||
if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
this.validate();
|
||||
}));
|
||||
this._register(this.preserveCase.onKeyDown(e => {
|
||||
this._onPreserveCaseKeyDown.fire(e);
|
||||
}));
|
||||
if (this._showOptionButtons) {
|
||||
this.cachedOptionsWidth = this.preserveCase.width();
|
||||
}
|
||||
else {
|
||||
this.cachedOptionsWidth = 0;
|
||||
}
|
||||
// Arrow-Key support to navigate between options
|
||||
const indexes = [this.preserveCase.domNode];
|
||||
this.onkeydown(this.domNode, (event) => {
|
||||
if (event.equals(15 /* KeyCode.LeftArrow */) || event.equals(17 /* KeyCode.RightArrow */) || event.equals(9 /* KeyCode.Escape */)) {
|
||||
const index = indexes.indexOf(this.domNode.ownerDocument.activeElement);
|
||||
if (index >= 0) {
|
||||
let newIndex = -1;
|
||||
if (event.equals(17 /* KeyCode.RightArrow */)) {
|
||||
newIndex = (index + 1) % indexes.length;
|
||||
}
|
||||
else if (event.equals(15 /* KeyCode.LeftArrow */)) {
|
||||
if (index === 0) {
|
||||
newIndex = indexes.length - 1;
|
||||
}
|
||||
else {
|
||||
newIndex = index - 1;
|
||||
}
|
||||
}
|
||||
if (event.equals(9 /* KeyCode.Escape */)) {
|
||||
indexes[index].blur();
|
||||
this.inputBox.focus();
|
||||
}
|
||||
else if (newIndex >= 0) {
|
||||
indexes[newIndex].focus();
|
||||
}
|
||||
dom.EventHelper.stop(event, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'controls';
|
||||
controls.style.display = this._showOptionButtons ? 'block' : 'none';
|
||||
controls.appendChild(this.preserveCase.domNode);
|
||||
this.domNode.appendChild(controls);
|
||||
parent?.appendChild(this.domNode);
|
||||
this.onkeydown(this.inputBox.inputElement, (e) => this._onKeyDown.fire(e));
|
||||
this.onkeyup(this.inputBox.inputElement, (e) => this._onKeyUp.fire(e));
|
||||
this.oninput(this.inputBox.inputElement, (e) => this._onInput.fire());
|
||||
this.onmousedown(this.inputBox.inputElement, (e) => this._onMouseDown.fire(e));
|
||||
}
|
||||
enable() {
|
||||
this.domNode.classList.remove('disabled');
|
||||
this.inputBox.enable();
|
||||
this.preserveCase.enable();
|
||||
}
|
||||
disable() {
|
||||
this.domNode.classList.add('disabled');
|
||||
this.inputBox.disable();
|
||||
this.preserveCase.disable();
|
||||
}
|
||||
setEnabled(enabled) {
|
||||
if (enabled) {
|
||||
this.enable();
|
||||
}
|
||||
else {
|
||||
this.disable();
|
||||
}
|
||||
}
|
||||
select() {
|
||||
this.inputBox.select();
|
||||
}
|
||||
focus() {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
getPreserveCase() {
|
||||
return this.preserveCase.checked;
|
||||
}
|
||||
setPreserveCase(value) {
|
||||
this.preserveCase.checked = value;
|
||||
}
|
||||
focusOnPreserve() {
|
||||
this.preserveCase.focus();
|
||||
}
|
||||
validate() {
|
||||
this.inputBox?.validate();
|
||||
}
|
||||
set width(newWidth) {
|
||||
this.inputBox.paddingRight = this.cachedOptionsWidth;
|
||||
this.domNode.style.width = newWidth + 'px';
|
||||
}
|
||||
dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=replaceInput.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,128 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from '../../dom.js';
|
||||
import { getBaseLayerHoverDelegate } from '../hover/hoverDelegate2.js';
|
||||
import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js';
|
||||
import { renderLabelWithIcons } from '../iconLabel/iconLabels.js';
|
||||
import { Disposable } from '../../../common/lifecycle.js';
|
||||
import * as objects from '../../../common/objects.js';
|
||||
/**
|
||||
* A widget which can render a label with substring highlights, often
|
||||
* originating from a filter function like the fuzzy matcher.
|
||||
*/
|
||||
export class HighlightedLabel extends Disposable {
|
||||
/**
|
||||
* Create a new {@link HighlightedLabel}.
|
||||
*
|
||||
* @param container The parent container to append to.
|
||||
*/
|
||||
constructor(container, options) {
|
||||
super();
|
||||
this.options = options;
|
||||
this.text = '';
|
||||
this.title = '';
|
||||
this.highlights = [];
|
||||
this.didEverRender = false;
|
||||
this.supportIcons = options?.supportIcons ?? false;
|
||||
this.domNode = dom.append(container, dom.$('span.monaco-highlighted-label'));
|
||||
}
|
||||
/**
|
||||
* The label's DOM node.
|
||||
*/
|
||||
get element() {
|
||||
return this.domNode;
|
||||
}
|
||||
/**
|
||||
* Set the label and highlights.
|
||||
*
|
||||
* @param text The label to display.
|
||||
* @param highlights The ranges to highlight.
|
||||
* @param title An optional title for the hover tooltip.
|
||||
* @param escapeNewLines Whether to escape new lines.
|
||||
* @returns
|
||||
*/
|
||||
set(text, highlights = [], title = '', escapeNewLines) {
|
||||
if (!text) {
|
||||
text = '';
|
||||
}
|
||||
if (escapeNewLines) {
|
||||
// adjusts highlights inplace
|
||||
text = HighlightedLabel.escapeNewLines(text, highlights);
|
||||
}
|
||||
if (this.didEverRender && this.text === text && this.title === title && objects.equals(this.highlights, highlights)) {
|
||||
return;
|
||||
}
|
||||
this.text = text;
|
||||
this.title = title;
|
||||
this.highlights = highlights;
|
||||
this.render();
|
||||
}
|
||||
render() {
|
||||
const children = [];
|
||||
let pos = 0;
|
||||
for (const highlight of this.highlights) {
|
||||
if (highlight.end === highlight.start) {
|
||||
continue;
|
||||
}
|
||||
if (pos < highlight.start) {
|
||||
const substring = this.text.substring(pos, highlight.start);
|
||||
if (this.supportIcons) {
|
||||
children.push(...renderLabelWithIcons(substring));
|
||||
}
|
||||
else {
|
||||
children.push(substring);
|
||||
}
|
||||
pos = highlight.start;
|
||||
}
|
||||
const substring = this.text.substring(pos, highlight.end);
|
||||
const element = dom.$('span.highlight', undefined, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]);
|
||||
if (highlight.extraClasses) {
|
||||
element.classList.add(...highlight.extraClasses);
|
||||
}
|
||||
children.push(element);
|
||||
pos = highlight.end;
|
||||
}
|
||||
if (pos < this.text.length) {
|
||||
const substring = this.text.substring(pos);
|
||||
if (this.supportIcons) {
|
||||
children.push(...renderLabelWithIcons(substring));
|
||||
}
|
||||
else {
|
||||
children.push(substring);
|
||||
}
|
||||
}
|
||||
dom.reset(this.domNode, ...children);
|
||||
if (!this.customHover && this.title !== '') {
|
||||
const hoverDelegate = this.options?.hoverDelegate ?? getDefaultHoverDelegate('mouse');
|
||||
this.customHover = this._register(getBaseLayerHoverDelegate().setupManagedHover(hoverDelegate, this.domNode, this.title));
|
||||
}
|
||||
else if (this.customHover) {
|
||||
this.customHover.update(this.title);
|
||||
}
|
||||
this.didEverRender = true;
|
||||
}
|
||||
static escapeNewLines(text, highlights) {
|
||||
let total = 0;
|
||||
let extra = 0;
|
||||
return text.replace(/\r\n|\r|\n/g, (match, offset) => {
|
||||
extra = match === '\r\n' ? -1 : 0;
|
||||
offset += total;
|
||||
for (const highlight of highlights) {
|
||||
if (highlight.end <= offset) {
|
||||
continue;
|
||||
}
|
||||
if (highlight.start >= offset) {
|
||||
highlight.start += extra;
|
||||
}
|
||||
if (highlight.end >= offset) {
|
||||
highlight.end += extra;
|
||||
}
|
||||
}
|
||||
total += extra;
|
||||
return '\u23CE';
|
||||
});
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=highlightedLabel.js.map
|
||||
File diff suppressed because one or more lines are too long
10
_internal/editor/esm/vs/base/browser/ui/hover/hover.js
Normal file
10
_internal/editor/esm/vs/base/browser/ui/hover/hover.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export function isManagedHoverTooltipMarkdownString(obj) {
|
||||
const candidate = obj;
|
||||
return typeof candidate === 'object' && 'markdown' in candidate && 'markdownNotSupportedFallback' in candidate;
|
||||
}
|
||||
// #endregion Managed hover
|
||||
//# sourceMappingURL=hover.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export {};
|
||||
//# sourceMappingURL=hoverDelegate.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Disposable } from '../../../common/lifecycle.js';
|
||||
let baseHoverDelegate = {
|
||||
showInstantHover: () => undefined,
|
||||
showDelayedHover: () => undefined,
|
||||
setupDelayedHover: () => Disposable.None,
|
||||
setupDelayedHoverAtMouse: () => Disposable.None,
|
||||
hideHover: () => undefined,
|
||||
showAndFocusLastHover: () => undefined,
|
||||
setupManagedHover: () => ({
|
||||
dispose: () => undefined,
|
||||
show: () => undefined,
|
||||
hide: () => undefined,
|
||||
update: () => undefined,
|
||||
}),
|
||||
showManagedHover: () => undefined
|
||||
};
|
||||
/**
|
||||
* Sets the hover delegate for use **only in the `base/` layer**.
|
||||
*/
|
||||
export function setBaseLayerHoverDelegate(hoverDelegate) {
|
||||
baseHoverDelegate = hoverDelegate;
|
||||
}
|
||||
/**
|
||||
* Gets the hover delegate for use **only in the `base/` layer**.
|
||||
*
|
||||
* Since the hover service depends on various platform services, this delegate essentially bypasses
|
||||
* the standard dependency injection mechanism by injecting a global hover service at start up. The
|
||||
* only reason this should be used is if `IHoverService` is not available.
|
||||
*/
|
||||
export function getBaseLayerHoverDelegate() {
|
||||
return baseHoverDelegate;
|
||||
}
|
||||
//# sourceMappingURL=hoverDelegate2.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/browser/ui/hover/hoverDelegate2.ts","vs/base/browser/ui/hover/hoverDelegate2.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAG1D,IAAI,iBAAiB,GAAoB;IACxC,gBAAgB,EAAE,GAAG,EAAE,CAAC,SAAS;IACjC,gBAAgB,EAAE,GAAG,EAAE,CAAC,SAAS;IACjC,iBAAiB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI;IACxC,wBAAwB,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI;IAC/C,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS;IAC1B,qBAAqB,EAAE,GAAG,EAAE,CAAC,SAAS;IACtC,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC;QACzB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;QACxB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;QACrB,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS;QACrB,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS;KACvB,CAAC;IACF,gBAAgB,EAAE,GAAG,EAAE,CAAC,SAAS;CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,aAA8B;IACvE,iBAAiB,GAAG,aAAa,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB;IACxC,OAAO,iBAAiB,CAAC;AAC1B,CAAC","file":"hoverDelegate2.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Disposable } from '../../../common/lifecycle.js';\nimport { IHoverDelegate2 } from './hover.js';\n\nlet baseHoverDelegate: IHoverDelegate2 = {\n\tshowInstantHover: () => undefined,\n\tshowDelayedHover: () => undefined,\n\tsetupDelayedHover: () => Disposable.None,\n\tsetupDelayedHoverAtMouse: () => Disposable.None,\n\thideHover: () => undefined,\n\tshowAndFocusLastHover: () => undefined,\n\tsetupManagedHover: () => ({\n\t\tdispose: () => undefined,\n\t\tshow: () => undefined,\n\t\thide: () => undefined,\n\t\tupdate: () => undefined,\n\t}),\n\tshowManagedHover: () => undefined\n};\n\n/**\n * Sets the hover delegate for use **only in the `base/` layer**.\n */\nexport function setBaseLayerHoverDelegate(hoverDelegate: IHoverDelegate2): void {\n\tbaseHoverDelegate = hoverDelegate;\n}\n\n/**\n * Gets the hover delegate for use **only in the `base/` layer**.\n *\n * Since the hover service depends on various platform services, this delegate essentially bypasses\n * the standard dependency injection mechanism by injecting a global hover service at start up. The\n * only reason this should be used is if `IHoverService` is not available.\n */\nexport function getBaseLayerHoverDelegate(): IHoverDelegate2 {\n\treturn baseHoverDelegate;\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Disposable } from '../../../common/lifecycle.js';\nimport { IHoverDelegate2 } from './hover.js';\n\nlet baseHoverDelegate: IHoverDelegate2 = {\n\tshowInstantHover: () => undefined,\n\tshowDelayedHover: () => undefined,\n\tsetupDelayedHover: () => Disposable.None,\n\tsetupDelayedHoverAtMouse: () => Disposable.None,\n\thideHover: () => undefined,\n\tshowAndFocusLastHover: () => undefined,\n\tsetupManagedHover: () => ({\n\t\tdispose: () => undefined,\n\t\tshow: () => undefined,\n\t\thide: () => undefined,\n\t\tupdate: () => undefined,\n\t}),\n\tshowManagedHover: () => undefined\n};\n\n/**\n * Sets the hover delegate for use **only in the `base/` layer**.\n */\nexport function setBaseLayerHoverDelegate(hoverDelegate: IHoverDelegate2): void {\n\tbaseHoverDelegate = hoverDelegate;\n}\n\n/**\n * Gets the hover delegate for use **only in the `base/` layer**.\n *\n * Since the hover service depends on various platform services, this delegate essentially bypasses\n * the standard dependency injection mechanism by injecting a global hover service at start up. The\n * only reason this should be used is if `IHoverService` is not available.\n */\nexport function getBaseLayerHoverDelegate(): IHoverDelegate2 {\n\treturn baseHoverDelegate;\n}\n"]}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Lazy } from '../../../common/lazy.js';
|
||||
const nullHoverDelegateFactory = () => ({
|
||||
get delay() { return -1; },
|
||||
dispose: () => { },
|
||||
showHover: () => { return undefined; },
|
||||
});
|
||||
let hoverDelegateFactory = nullHoverDelegateFactory;
|
||||
const defaultHoverDelegateMouse = new Lazy(() => hoverDelegateFactory('mouse', false));
|
||||
const defaultHoverDelegateElement = new Lazy(() => hoverDelegateFactory('element', false));
|
||||
// TODO: Remove when getDefaultHoverDelegate is no longer used
|
||||
export function setHoverDelegateFactory(hoverDelegateProvider) {
|
||||
hoverDelegateFactory = hoverDelegateProvider;
|
||||
}
|
||||
// TODO: Refine type for use in new IHoverService interface
|
||||
export function getDefaultHoverDelegate(placement) {
|
||||
if (placement === 'element') {
|
||||
return defaultHoverDelegateElement.value;
|
||||
}
|
||||
return defaultHoverDelegateMouse.value;
|
||||
}
|
||||
// TODO: Create equivalent in IHoverService
|
||||
export function createInstantHoverDelegate() {
|
||||
// Creates a hover delegate with instant hover enabled.
|
||||
// This hover belongs to the consumer and requires the them to dispose it.
|
||||
// Instant hover only makes sense for 'element' placement.
|
||||
return hoverDelegateFactory('element', true);
|
||||
}
|
||||
//# sourceMappingURL=hoverDelegateFactory.js.map
|
||||
File diff suppressed because one or more lines are too long
225
_internal/editor/esm/vs/base/browser/ui/hover/hoverWidget.css
Normal file
225
_internal/editor/esm/vs/base/browser/ui/hover/hoverWidget.css
Normal file
@@ -0,0 +1,225 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-hover {
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
user-select: text;
|
||||
-webkit-user-select: text;
|
||||
box-sizing: border-box;
|
||||
line-height: 1.5em;
|
||||
white-space: var(--vscode-hover-whiteSpace, normal);
|
||||
}
|
||||
|
||||
.monaco-hover.fade-in {
|
||||
animation: fadein 100ms linear;
|
||||
}
|
||||
|
||||
.monaco-hover.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-hover a:hover:not(.disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-contents:not(.html-hover-contents) {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) {
|
||||
max-width: var(--vscode-hover-maxWidth, 500px);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) hr {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.monaco-hover p,
|
||||
.monaco-hover .code,
|
||||
.monaco-hover ul,
|
||||
.monaco-hover h1,
|
||||
.monaco-hover h2,
|
||||
.monaco-hover h3,
|
||||
.monaco-hover h4,
|
||||
.monaco-hover h5,
|
||||
.monaco-hover h6 {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.monaco-hover h1,
|
||||
.monaco-hover h2,
|
||||
.monaco-hover h3,
|
||||
.monaco-hover h4,
|
||||
.monaco-hover h5,
|
||||
.monaco-hover h6 {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.monaco-hover code {
|
||||
font-family: var(--monaco-monospace-font);
|
||||
}
|
||||
|
||||
.monaco-hover hr {
|
||||
box-sizing: border-box;
|
||||
border-left: 0px;
|
||||
border-right: 0px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: -4px;
|
||||
margin-left: -8px;
|
||||
margin-right: -8px;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.monaco-hover p:first-child,
|
||||
.monaco-hover .code:first-child,
|
||||
.monaco-hover ul:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.monaco-hover p:last-child,
|
||||
.monaco-hover .code:last-child,
|
||||
.monaco-hover ul:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* MarkupContent Layout */
|
||||
.monaco-hover ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.monaco-hover ol {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.monaco-hover li > p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.monaco-hover li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.monaco-hover code {
|
||||
border-radius: 3px;
|
||||
padding: 0 0.4em;
|
||||
}
|
||||
|
||||
.monaco-hover .monaco-tokenized-source {
|
||||
white-space: var(--vscode-hover-sourceWhiteSpace, pre-wrap);
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar {
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar .info {
|
||||
font-style: italic;
|
||||
padding: 0px 8px;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar .actions {
|
||||
display: flex;
|
||||
padding: 0px 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar .actions .action-container {
|
||||
margin-right: 16px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-wrap: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar .actions .action-container .action .icon {
|
||||
padding-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar .actions .action-container a {
|
||||
color: var(--vscode-textLink-foreground);
|
||||
text-decoration: var(--text-link-decoration);
|
||||
}
|
||||
|
||||
.monaco-hover .hover-row.status-bar .actions .action-container a .icon.codicon {
|
||||
color: var(--vscode-textLink-foreground);
|
||||
}
|
||||
|
||||
.monaco-hover .markdown-hover .hover-contents .codicon {
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-contents a.code-link:hover,
|
||||
.monaco-hover .hover-contents a.code-link {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.monaco-hover .hover-contents a.code-link:before {
|
||||
content: '(';
|
||||
}
|
||||
|
||||
.monaco-hover .hover-contents a.code-link:after {
|
||||
content: ')';
|
||||
}
|
||||
|
||||
.monaco-hover .hover-contents a.code-link > span {
|
||||
text-decoration: underline;
|
||||
/** Hack to force underline to show **/
|
||||
border-bottom: 1px solid transparent;
|
||||
text-underline-position: under;
|
||||
color: var(--vscode-textLink-foreground);
|
||||
}
|
||||
|
||||
.monaco-hover .hover-contents a.code-link > span:hover {
|
||||
color: var(--vscode-textLink-activeForeground);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spans in markdown hovers need a margin-bottom to avoid looking cramped:
|
||||
* https://github.com/microsoft/vscode/issues/101496
|
||||
|
||||
* This was later refined to only apply when the last child of a rendered markdown block (before the
|
||||
* border or a `hr`) uses background color:
|
||||
* https://github.com/microsoft/vscode/issues/228136
|
||||
*/
|
||||
.monaco-hover .markdown-hover .hover-contents:not(.code-hover-contents):not(.html-hover-contents) p:last-child [style*="background-color"] {
|
||||
margin-bottom: 4px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a slight margin to try vertically align codicons with any text
|
||||
* https://github.com/microsoft/vscode/issues/221359
|
||||
*/
|
||||
.monaco-hover .markdown-hover .hover-contents:not(.code-hover-contents):not(.html-hover-contents) span.codicon {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.monaco-hover-content .action-container a {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.monaco-hover-content .action-container.disabled {
|
||||
pointer-events: none;
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Prevent text selection in all button-like elements within hovers */
|
||||
.monaco-hover .action-container,
|
||||
.monaco-hover .action,
|
||||
.monaco-hover button,
|
||||
.monaco-hover .monaco-button,
|
||||
.monaco-hover .monaco-text-button,
|
||||
.monaco-hover [role="button"] {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
91
_internal/editor/esm/vs/base/browser/ui/hover/hoverWidget.js
Normal file
91
_internal/editor/esm/vs/base/browser/ui/hover/hoverWidget.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as dom from '../../dom.js';
|
||||
import { StandardKeyboardEvent } from '../../keyboardEvent.js';
|
||||
import { DomScrollableElement } from '../scrollbar/scrollableElement.js';
|
||||
import { Disposable } from '../../../common/lifecycle.js';
|
||||
import './hoverWidget.css';
|
||||
import { localize } from '../../../../nls.js';
|
||||
const $ = dom.$;
|
||||
export class HoverWidget extends Disposable {
|
||||
constructor(fadeIn) {
|
||||
super();
|
||||
this.containerDomNode = document.createElement('div');
|
||||
this.containerDomNode.className = 'monaco-hover';
|
||||
this.containerDomNode.classList.toggle('fade-in', !!fadeIn);
|
||||
this.containerDomNode.tabIndex = 0;
|
||||
this.containerDomNode.setAttribute('role', 'tooltip');
|
||||
this.contentsDomNode = document.createElement('div');
|
||||
this.contentsDomNode.className = 'monaco-hover-content';
|
||||
this.scrollbar = this._register(new DomScrollableElement(this.contentsDomNode, {
|
||||
consumeMouseWheelIfScrollbarIsNeeded: true
|
||||
}));
|
||||
this.containerDomNode.appendChild(this.scrollbar.getDomNode());
|
||||
}
|
||||
onContentsChanged() {
|
||||
this.scrollbar.scanDomNode();
|
||||
}
|
||||
}
|
||||
export class HoverAction extends Disposable {
|
||||
static render(parent, actionOptions, keybindingLabel) {
|
||||
return new HoverAction(parent, actionOptions, keybindingLabel);
|
||||
}
|
||||
constructor(parent, actionOptions, keybindingLabel) {
|
||||
super();
|
||||
this.actionLabel = actionOptions.label;
|
||||
this.actionKeybindingLabel = keybindingLabel;
|
||||
this.actionContainer = dom.append(parent, $('div.action-container'));
|
||||
this.actionContainer.setAttribute('tabindex', '0');
|
||||
this.action = dom.append(this.actionContainer, $('a.action'));
|
||||
this.action.setAttribute('role', 'button');
|
||||
if (actionOptions.iconClass) {
|
||||
const iconElement = dom.append(this.action, $(`span.icon`));
|
||||
iconElement.classList.add(...actionOptions.iconClass.split(' '));
|
||||
}
|
||||
this.actionRenderedLabel = keybindingLabel ? `${actionOptions.label} (${keybindingLabel})` : actionOptions.label;
|
||||
const label = dom.append(this.action, $('span'));
|
||||
label.textContent = this.actionRenderedLabel;
|
||||
this._store.add(new ClickAction(this.actionContainer, actionOptions.run));
|
||||
this._store.add(new KeyDownAction(this.actionContainer, actionOptions.run, [3 /* KeyCode.Enter */, 10 /* KeyCode.Space */]));
|
||||
this.setEnabled(true);
|
||||
}
|
||||
setEnabled(enabled) {
|
||||
if (enabled) {
|
||||
this.actionContainer.classList.remove('disabled');
|
||||
this.actionContainer.removeAttribute('aria-disabled');
|
||||
}
|
||||
else {
|
||||
this.actionContainer.classList.add('disabled');
|
||||
this.actionContainer.setAttribute('aria-disabled', 'true');
|
||||
}
|
||||
}
|
||||
}
|
||||
export function getHoverAccessibleViewHint(shouldHaveHint, keybinding) {
|
||||
return shouldHaveHint && keybinding ? localize(7, "Inspect this in the accessible view with {0}.", keybinding) : shouldHaveHint ? localize(8, "Inspect this in the accessible view via the command Open Accessible View which is currently not triggerable via keybinding.") : '';
|
||||
}
|
||||
export class ClickAction extends Disposable {
|
||||
constructor(container, run) {
|
||||
super();
|
||||
this._register(dom.addDisposableListener(container, dom.EventType.CLICK, e => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
run(container);
|
||||
}));
|
||||
}
|
||||
}
|
||||
export class KeyDownAction extends Disposable {
|
||||
constructor(container, run, keyCodes) {
|
||||
super();
|
||||
this._register(dom.addDisposableListener(container, dom.EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if (keyCodes.some(keyCode => event.equals(keyCode))) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
run(container);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=hoverWidget.js.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user