This commit is contained in:
2025-11-02 19:17:20 +08:00
parent ebf784146e
commit e71b69db5f
2575 changed files with 1242294 additions and 95 deletions

28
_internal/editor/esm/metadata.d.ts vendored Normal file
View File

@@ -0,0 +1,28 @@
/*!----------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Released under the MIT license
* https://github.com/microsoft/monaco-editor/blob/main/LICENSE.txt
*----------------------------------------------------------------*/
export interface IWorkerDefinition {
id: string;
entry: string;
}
export interface IFeatureDefinition {
label: string;
entry: string | string[] | undefined;
worker?: IWorkerDefinition;
}
export const features: IFeatureDefinition[];
export const languages: IFeatureDefinition[];
export type EditorLanguage = 'abap' | 'apex' | 'azcli' | 'bat' | 'bicep' | 'cameligo' | 'clojure' | 'coffee' | 'cpp' | 'csharp' | 'csp' | 'css' | 'cypher' | 'dart' | 'dockerfile' | 'ecl' | 'elixir' | 'flow9' | 'freemarker2' | 'fsharp' | 'go' | 'graphql' | 'handlebars' | 'hcl' | 'html' | 'ini' | 'java' | 'javascript' | 'json' | 'julia' | 'kotlin' | 'less' | 'lexon' | 'liquid' | 'lua' | 'm3' | 'markdown' | 'mdx' | 'mips' | 'msdax' | 'mysql' | 'objective-c' | 'pascal' | 'pascaligo' | 'perl' | 'pgsql' | 'php' | 'pla' | 'postiats' | 'powerquery' | 'powershell' | 'protobuf' | 'pug' | 'python' | 'qsharp' | 'r' | 'razor' | 'redis' | 'redshift' | 'restructuredtext' | 'ruby' | 'rust' | 'sb' | 'scala' | 'scheme' | 'scss' | 'shell' | 'solidity' | 'sophia' | 'sparql' | 'sql' | 'st' | 'swift' | 'systemverilog' | 'tcl' | 'twig' | 'typescript' | 'typespec' | 'vb' | 'wgsl' | 'xml' | 'yaml';
export type EditorFeature = 'anchorSelect' | 'bracketMatching' | 'browser' | 'caretOperations' | 'clipboard' | 'codeAction' | 'codeEditor' | 'codelens' | 'colorPicker' | 'comment' | 'contextmenu' | 'cursorUndo' | 'diffEditor' | 'diffEditorBreadcrumbs' | 'dnd' | 'documentSymbols' | 'dropOrPasteInto' | 'find' | 'floatingMenu' | 'folding' | 'fontZoom' | 'format' | 'gotoError' | 'gotoLine' | 'gotoSymbol' | 'gpu' | 'hover' | 'iPadShowKeyboard' | 'inPlaceReplace' | 'indentation' | 'inlayHints' | 'inlineCompletions' | 'inlineProgress' | 'insertFinalNewLine' | 'inspectTokens' | 'lineSelection' | 'linesOperations' | 'linkedEditing' | 'links' | 'longLinesHelper' | 'middleScroll' | 'multicursor' | 'parameterHints' | 'placeholderText' | 'quickCommand' | 'quickHelp' | 'quickOutline' | 'readOnlyMessage' | 'referenceSearch' | 'rename' | 'sectionHeaders' | 'semanticTokens' | 'smartSelect' | 'snippet' | 'stickyScroll' | 'suggest' | 'toggleHighContrast' | 'toggleTabFocusMode' | 'tokenization' | 'unicodeHighlighter' | 'unusualLineTerminators' | 'wordHighlighter' | 'wordOperations' | 'wordPartOperations';
export type NegatedEditorFeature = '!anchorSelect' | '!bracketMatching' | '!browser' | '!caretOperations' | '!clipboard' | '!codeAction' | '!codeEditor' | '!codelens' | '!colorPicker' | '!comment' | '!contextmenu' | '!cursorUndo' | '!diffEditor' | '!diffEditorBreadcrumbs' | '!dnd' | '!documentSymbols' | '!dropOrPasteInto' | '!find' | '!floatingMenu' | '!folding' | '!fontZoom' | '!format' | '!gotoError' | '!gotoLine' | '!gotoSymbol' | '!gpu' | '!hover' | '!iPadShowKeyboard' | '!inPlaceReplace' | '!indentation' | '!inlayHints' | '!inlineCompletions' | '!inlineProgress' | '!insertFinalNewLine' | '!inspectTokens' | '!lineSelection' | '!linesOperations' | '!linkedEditing' | '!links' | '!longLinesHelper' | '!middleScroll' | '!multicursor' | '!parameterHints' | '!placeholderText' | '!quickCommand' | '!quickHelp' | '!quickOutline' | '!readOnlyMessage' | '!referenceSearch' | '!rename' | '!sectionHeaders' | '!semanticTokens' | '!smartSelect' | '!snippet' | '!stickyScroll' | '!suggest' | '!toggleHighContrast' | '!toggleTabFocusMode' | '!tokenization' | '!unicodeHighlighter' | '!unusualLineTerminators' | '!wordHighlighter' | '!wordOperations' | '!wordPartOperations';

View File

@@ -0,0 +1,629 @@
exports.features = [
{
"label": "anchorSelect",
"entry": "vs/editor/contrib/anchorSelect/browser/anchorSelect"
},
{
"label": "bracketMatching",
"entry": "vs/editor/contrib/bracketMatching/browser/bracketMatching"
},
{
"label": "browser",
"entry": "vs/editor/browser/coreCommands"
},
{
"label": "caretOperations",
"entry": [
"vs/editor/contrib/caretOperations/browser/caretOperations",
"vs/editor/contrib/caretOperations/browser/transpose"
]
},
{
"label": "clipboard",
"entry": "vs/editor/contrib/clipboard/browser/clipboard"
},
{
"label": "codeAction",
"entry": "vs/editor/contrib/codeAction/browser/codeActionContributions"
},
{
"label": "codeEditor",
"entry": "vs/editor/browser/widget/codeEditor/codeEditorWidget"
},
{
"label": "codelens",
"entry": "vs/editor/contrib/codelens/browser/codelensController"
},
{
"label": "colorPicker",
"entry": "vs/editor/contrib/colorPicker/browser/colorPickerContribution"
},
{
"label": "comment",
"entry": "vs/editor/contrib/comment/browser/comment"
},
{
"label": "contextmenu",
"entry": "vs/editor/contrib/contextmenu/browser/contextmenu"
},
{
"label": "cursorUndo",
"entry": "vs/editor/contrib/cursorUndo/browser/cursorUndo"
},
{
"label": "diffEditor",
"entry": "vs/editor/browser/widget/diffEditor/diffEditor.contribution"
},
{
"label": "diffEditorBreadcrumbs",
"entry": "vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution"
},
{
"label": "dnd",
"entry": "vs/editor/contrib/dnd/browser/dnd"
},
{
"label": "documentSymbols",
"entry": "vs/editor/contrib/documentSymbols/browser/documentSymbols"
},
{
"label": "dropOrPasteInto",
"entry": [
"vs/editor/contrib/dropOrPasteInto/browser/copyPasteContribution",
"vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorContribution"
]
},
{
"label": "find",
"entry": "vs/editor/contrib/find/browser/findController"
},
{
"label": "floatingMenu",
"entry": "vs/editor/contrib/floatingMenu/browser/floatingMenu.contribution"
},
{
"label": "folding",
"entry": "vs/editor/contrib/folding/browser/folding"
},
{
"label": "fontZoom",
"entry": "vs/editor/contrib/fontZoom/browser/fontZoom"
},
{
"label": "format",
"entry": "vs/editor/contrib/format/browser/formatActions"
},
{
"label": "gotoError",
"entry": "vs/editor/contrib/gotoError/browser/gotoError"
},
{
"label": "gotoLine",
"entry": "vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess"
},
{
"label": "gotoSymbol",
"entry": [
"vs/editor/contrib/gotoSymbol/browser/goToCommands",
"vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition"
]
},
{
"label": "gpu",
"entry": "vs/editor/contrib/gpu/browser/gpuActions"
},
{
"label": "hover",
"entry": "vs/editor/contrib/hover/browser/hoverContribution"
},
{
"label": "iPadShowKeyboard",
"entry": "vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard"
},
{
"label": "inPlaceReplace",
"entry": "vs/editor/contrib/inPlaceReplace/browser/inPlaceReplace"
},
{
"label": "indentation",
"entry": "vs/editor/contrib/indentation/browser/indentation"
},
{
"label": "inlayHints",
"entry": "vs/editor/contrib/inlayHints/browser/inlayHintsContribution"
},
{
"label": "inlineCompletions",
"entry": "vs/editor/contrib/inlineCompletions/browser/inlineCompletions.contribution"
},
{
"label": "inlineProgress",
"entry": "vs/editor/contrib/inlineProgress/browser/inlineProgress"
},
{
"label": "insertFinalNewLine",
"entry": "vs/editor/contrib/insertFinalNewLine/browser/insertFinalNewLine"
},
{
"label": "inspectTokens",
"entry": "vs/editor/standalone/browser/inspectTokens/inspectTokens"
},
{
"label": "lineSelection",
"entry": "vs/editor/contrib/lineSelection/browser/lineSelection"
},
{
"label": "linesOperations",
"entry": "vs/editor/contrib/linesOperations/browser/linesOperations"
},
{
"label": "linkedEditing",
"entry": "vs/editor/contrib/linkedEditing/browser/linkedEditing"
},
{
"label": "links",
"entry": "vs/editor/contrib/links/browser/links"
},
{
"label": "longLinesHelper",
"entry": "vs/editor/contrib/longLinesHelper/browser/longLinesHelper"
},
{
"label": "middleScroll",
"entry": "vs/editor/contrib/middleScroll/browser/middleScroll.contribution"
},
{
"label": "multicursor",
"entry": "vs/editor/contrib/multicursor/browser/multicursor"
},
{
"label": "parameterHints",
"entry": "vs/editor/contrib/parameterHints/browser/parameterHints"
},
{
"label": "placeholderText",
"entry": "vs/editor/contrib/placeholderText/browser/placeholderText.contribution"
},
{
"label": "quickCommand",
"entry": "vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess"
},
{
"label": "quickHelp",
"entry": "vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess"
},
{
"label": "quickOutline",
"entry": "vs/editor/standalone/browser/quickAccess/standaloneGotoSymbolQuickAccess"
},
{
"label": "readOnlyMessage",
"entry": "vs/editor/contrib/readOnlyMessage/browser/contribution"
},
{
"label": "referenceSearch",
"entry": "vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch"
},
{
"label": "rename",
"entry": "vs/editor/contrib/rename/browser/rename"
},
{
"label": "sectionHeaders",
"entry": "vs/editor/contrib/sectionHeaders/browser/sectionHeaders"
},
{
"label": "semanticTokens",
"entry": [
"vs/editor/contrib/semanticTokens/browser/documentSemanticTokens",
"vs/editor/contrib/semanticTokens/browser/viewportSemanticTokens"
]
},
{
"label": "smartSelect",
"entry": "vs/editor/contrib/smartSelect/browser/smartSelect"
},
{
"label": "snippet",
"entry": "vs/editor/contrib/snippet/browser/snippetController2"
},
{
"label": "stickyScroll",
"entry": "vs/editor/contrib/stickyScroll/browser/stickyScrollContribution"
},
{
"label": "suggest",
"entry": [
"vs/editor/contrib/suggest/browser/suggestController",
"vs/editor/contrib/suggest/browser/suggestInlineCompletions"
]
},
{
"label": "toggleHighContrast",
"entry": "vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast"
},
{
"label": "toggleTabFocusMode",
"entry": "vs/editor/contrib/toggleTabFocusMode/browser/toggleTabFocusMode"
},
{
"label": "tokenization",
"entry": "vs/editor/contrib/tokenization/browser/tokenization"
},
{
"label": "unicodeHighlighter",
"entry": "vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter"
},
{
"label": "unusualLineTerminators",
"entry": "vs/editor/contrib/unusualLineTerminators/browser/unusualLineTerminators"
},
{
"label": "wordHighlighter",
"entry": "vs/editor/contrib/wordHighlighter/browser/wordHighlighter"
},
{
"label": "wordOperations",
"entry": "vs/editor/contrib/wordOperations/browser/wordOperations"
},
{
"label": "wordPartOperations",
"entry": "vs/editor/contrib/wordPartOperations/browser/wordPartOperations"
}
];
exports.languages = [
{
"label": "abap",
"entry": "vs/basic-languages/abap/abap.contribution"
},
{
"label": "apex",
"entry": "vs/basic-languages/apex/apex.contribution"
},
{
"label": "azcli",
"entry": "vs/basic-languages/azcli/azcli.contribution"
},
{
"label": "bat",
"entry": "vs/basic-languages/bat/bat.contribution"
},
{
"label": "bicep",
"entry": "vs/basic-languages/bicep/bicep.contribution"
},
{
"label": "cameligo",
"entry": "vs/basic-languages/cameligo/cameligo.contribution"
},
{
"label": "clojure",
"entry": "vs/basic-languages/clojure/clojure.contribution"
},
{
"label": "coffee",
"entry": "vs/basic-languages/coffee/coffee.contribution"
},
{
"label": "cpp",
"entry": "vs/basic-languages/cpp/cpp.contribution"
},
{
"label": "csharp",
"entry": "vs/basic-languages/csharp/csharp.contribution"
},
{
"label": "csp",
"entry": "vs/basic-languages/csp/csp.contribution"
},
{
"label": "css",
"entry": [
"vs/basic-languages/css/css.contribution",
"vs/language/css/monaco.contribution"
],
"worker": {
"id": "vs/language/css/cssWorker",
"entry": "vs/language/css/css.worker"
}
},
{
"label": "cypher",
"entry": "vs/basic-languages/cypher/cypher.contribution"
},
{
"label": "dart",
"entry": "vs/basic-languages/dart/dart.contribution"
},
{
"label": "dockerfile",
"entry": "vs/basic-languages/dockerfile/dockerfile.contribution"
},
{
"label": "ecl",
"entry": "vs/basic-languages/ecl/ecl.contribution"
},
{
"label": "elixir",
"entry": "vs/basic-languages/elixir/elixir.contribution"
},
{
"label": "flow9",
"entry": "vs/basic-languages/flow9/flow9.contribution"
},
{
"label": "freemarker2",
"entry": "vs/basic-languages/freemarker2/freemarker2.contribution"
},
{
"label": "fsharp",
"entry": "vs/basic-languages/fsharp/fsharp.contribution"
},
{
"label": "go",
"entry": "vs/basic-languages/go/go.contribution"
},
{
"label": "graphql",
"entry": "vs/basic-languages/graphql/graphql.contribution"
},
{
"label": "handlebars",
"entry": "vs/basic-languages/handlebars/handlebars.contribution"
},
{
"label": "hcl",
"entry": "vs/basic-languages/hcl/hcl.contribution"
},
{
"label": "html",
"entry": [
"vs/basic-languages/html/html.contribution",
"vs/language/html/monaco.contribution"
],
"worker": {
"id": "vs/language/html/htmlWorker",
"entry": "vs/language/html/html.worker"
}
},
{
"label": "ini",
"entry": "vs/basic-languages/ini/ini.contribution"
},
{
"label": "java",
"entry": "vs/basic-languages/java/java.contribution"
},
{
"label": "javascript",
"entry": "vs/basic-languages/javascript/javascript.contribution"
},
{
"label": "json",
"entry": "vs/language/json/monaco.contribution",
"worker": {
"id": "vs/language/json/jsonWorker",
"entry": "vs/language/json/json.worker"
}
},
{
"label": "julia",
"entry": "vs/basic-languages/julia/julia.contribution"
},
{
"label": "kotlin",
"entry": "vs/basic-languages/kotlin/kotlin.contribution"
},
{
"label": "less",
"entry": "vs/basic-languages/less/less.contribution"
},
{
"label": "lexon",
"entry": "vs/basic-languages/lexon/lexon.contribution"
},
{
"label": "liquid",
"entry": "vs/basic-languages/liquid/liquid.contribution"
},
{
"label": "lua",
"entry": "vs/basic-languages/lua/lua.contribution"
},
{
"label": "m3",
"entry": "vs/basic-languages/m3/m3.contribution"
},
{
"label": "markdown",
"entry": "vs/basic-languages/markdown/markdown.contribution"
},
{
"label": "mdx",
"entry": "vs/basic-languages/mdx/mdx.contribution"
},
{
"label": "mips",
"entry": "vs/basic-languages/mips/mips.contribution"
},
{
"label": "msdax",
"entry": "vs/basic-languages/msdax/msdax.contribution"
},
{
"label": "mysql",
"entry": "vs/basic-languages/mysql/mysql.contribution"
},
{
"label": "objective-c",
"entry": "vs/basic-languages/objective-c/objective-c.contribution"
},
{
"label": "pascal",
"entry": "vs/basic-languages/pascal/pascal.contribution"
},
{
"label": "pascaligo",
"entry": "vs/basic-languages/pascaligo/pascaligo.contribution"
},
{
"label": "perl",
"entry": "vs/basic-languages/perl/perl.contribution"
},
{
"label": "pgsql",
"entry": "vs/basic-languages/pgsql/pgsql.contribution"
},
{
"label": "php",
"entry": "vs/basic-languages/php/php.contribution"
},
{
"label": "pla",
"entry": "vs/basic-languages/pla/pla.contribution"
},
{
"label": "postiats",
"entry": "vs/basic-languages/postiats/postiats.contribution"
},
{
"label": "powerquery",
"entry": "vs/basic-languages/powerquery/powerquery.contribution"
},
{
"label": "powershell",
"entry": "vs/basic-languages/powershell/powershell.contribution"
},
{
"label": "protobuf",
"entry": "vs/basic-languages/protobuf/protobuf.contribution"
},
{
"label": "pug",
"entry": "vs/basic-languages/pug/pug.contribution"
},
{
"label": "python",
"entry": "vs/basic-languages/python/python.contribution"
},
{
"label": "qsharp",
"entry": "vs/basic-languages/qsharp/qsharp.contribution"
},
{
"label": "r",
"entry": "vs/basic-languages/r/r.contribution"
},
{
"label": "razor",
"entry": "vs/basic-languages/razor/razor.contribution"
},
{
"label": "redis",
"entry": "vs/basic-languages/redis/redis.contribution"
},
{
"label": "redshift",
"entry": "vs/basic-languages/redshift/redshift.contribution"
},
{
"label": "restructuredtext",
"entry": "vs/basic-languages/restructuredtext/restructuredtext.contribution"
},
{
"label": "ruby",
"entry": "vs/basic-languages/ruby/ruby.contribution"
},
{
"label": "rust",
"entry": "vs/basic-languages/rust/rust.contribution"
},
{
"label": "sb",
"entry": "vs/basic-languages/sb/sb.contribution"
},
{
"label": "scala",
"entry": "vs/basic-languages/scala/scala.contribution"
},
{
"label": "scheme",
"entry": "vs/basic-languages/scheme/scheme.contribution"
},
{
"label": "scss",
"entry": "vs/basic-languages/scss/scss.contribution"
},
{
"label": "shell",
"entry": "vs/basic-languages/shell/shell.contribution"
},
{
"label": "solidity",
"entry": "vs/basic-languages/solidity/solidity.contribution"
},
{
"label": "sophia",
"entry": "vs/basic-languages/sophia/sophia.contribution"
},
{
"label": "sparql",
"entry": "vs/basic-languages/sparql/sparql.contribution"
},
{
"label": "sql",
"entry": "vs/basic-languages/sql/sql.contribution"
},
{
"label": "st",
"entry": "vs/basic-languages/st/st.contribution"
},
{
"label": "swift",
"entry": "vs/basic-languages/swift/swift.contribution"
},
{
"label": "systemverilog",
"entry": "vs/basic-languages/systemverilog/systemverilog.contribution"
},
{
"label": "tcl",
"entry": "vs/basic-languages/tcl/tcl.contribution"
},
{
"label": "twig",
"entry": "vs/basic-languages/twig/twig.contribution"
},
{
"label": "typescript",
"entry": [
"vs/basic-languages/typescript/typescript.contribution",
"vs/language/typescript/monaco.contribution"
],
"worker": {
"id": "vs/language/typescript/tsWorker",
"entry": "vs/language/typescript/ts.worker"
}
},
{
"label": "typespec",
"entry": "vs/basic-languages/typespec/typespec.contribution"
},
{
"label": "vb",
"entry": "vs/basic-languages/vb/vb.contribution"
},
{
"label": "wgsl",
"entry": "vs/basic-languages/wgsl/wgsl.contribution"
},
{
"label": "xml",
"entry": "vs/basic-languages/xml/xml.contribution"
},
{
"label": "yaml",
"entry": "vs/basic-languages/yaml/yaml.contribution"
}
];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because one or more lines are too long

View 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

View 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"]}

View 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

View 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"]}

View 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

File diff suppressed because one or more lines are too long

View 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

View 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"]}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View 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

File diff suppressed because one or more lines are too long

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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"]}

View 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

File diff suppressed because one or more lines are too long

View 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

View 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"]}

View 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

View File

@@ -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

View 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

View 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"]}

View 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

File diff suppressed because one or more lines are too long

View 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

View 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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
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([
['&quot;', '"'],
['&nbsp;', ' '],
['&amp;', '&'],
['&#39;', '\''],
['&lt;', '<'],
['&gt;', '>'],
]);
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() + ' &nbsp;')[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 + ' &nbsp;');
}
}
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

View 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

File diff suppressed because one or more lines are too long

View 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

File diff suppressed because one or more lines are too long

View 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

File diff suppressed because one or more lines are too long

View 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

File diff suppressed because one or more lines are too long

View 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

View 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"]}

View File

@@ -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

View 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;
}

View 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

View 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;
}

View 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

File diff suppressed because one or more lines are too long

View File

@@ -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: ' ';
}

View File

@@ -0,0 +1,2 @@
import './breadcrumbsWidget.css';
//# sourceMappingURL=breadcrumbsWidget.js.map

View File

@@ -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"]}

View 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);
}

View 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

View 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.
*--------------------------------------------------------------------------------------------*/
.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;
}

View 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.
*--------------------------------------------------------------------------------------------*/
@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) */

View File

@@ -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

View File

@@ -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"]}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View 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;
}

View 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

View File

@@ -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"]}

View 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;
}

View 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

View 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"]}

View File

@@ -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;
}

View 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

View File

@@ -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

View File

@@ -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; }
}

View 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

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More