Skip to content

Commit 7b8cd25

Browse files
authored
Merge pull request #3760 from cdr/jsjoeio-add-vscode-test
feat: add registerRequireOnSelf on function
2 parents 670f0a1 + 911cb03 commit 7b8cd25

File tree

3 files changed

+371
-105
lines changed

3 files changed

+371
-105
lines changed

src/browser/pages/vscode.ts

+131-48
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { getOptions } from "../../common/util"
1+
import { getOptions, Options } from "../../common/util"
22
import "../register"
33

4-
const options = getOptions()
5-
6-
// TODO: Add proper types.
7-
/* eslint-disable @typescript-eslint/no-explicit-any */
4+
// TODO@jsjoeio: Add proper types.
5+
type FixMeLater = any
86

97
// NOTE@jsjoeio
108
// This lives here ../../../lib/vscode/src/vs/base/common/platform.ts#L106
@@ -19,7 +17,20 @@ type NlsConfiguration = {
1917
_resolvedLanguagePackCoreLocation?: string
2018
_corruptedFile?: string
2119
_languagePackSupport?: boolean
22-
loadBundle?: any
20+
loadBundle?: FixMeLater
21+
}
22+
23+
/**
24+
* Helper function to create the path to the bundle
25+
* for getNlsConfiguration.
26+
*/
27+
export function createBundlePath(_resolvedLanguagePackCoreLocation: string, bundle: string) {
28+
// NOTE@jsjoeio - this comment was here before me
29+
// Refers to operating systems that use a different path separator.
30+
// Probably just Windows but we're not sure if "/" breaks on Windows
31+
// so we'll leave it alone for now.
32+
// FIXME: Only works if path separators are /.
33+
return _resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
2334
}
2435

2536
/**
@@ -30,42 +41,45 @@ type NlsConfiguration = {
3041
*
3142
* Make sure to wrap this in a try/catch block when you call it.
3243
**/
33-
export function getNlsConfiguration(document: Document) {
44+
export function getNlsConfiguration(_document: Document, base: string) {
3445
const errorMsgPrefix = "[vscode]"
35-
const nlsConfigElement = document?.getElementById(nlsConfigElementId)
36-
const nlsConfig = nlsConfigElement?.getAttribute("data-settings")
37-
38-
if (!document) {
39-
throw new Error(`${errorMsgPrefix} Could not parse NLS configuration. document is undefined.`)
40-
}
46+
const nlsConfigElement = _document?.getElementById(nlsConfigElementId)
47+
const dataSettings = nlsConfigElement?.getAttribute("data-settings")
4148

4249
if (!nlsConfigElement) {
4350
throw new Error(
4451
`${errorMsgPrefix} Could not parse NLS configuration. Could not find nlsConfigElement with id: ${nlsConfigElementId}`,
4552
)
4653
}
4754

48-
if (!nlsConfig) {
55+
if (!dataSettings) {
4956
throw new Error(
5057
`${errorMsgPrefix} Could not parse NLS configuration. Found nlsConfigElement but missing data-settings attribute.`,
5158
)
5259
}
5360

54-
return JSON.parse(nlsConfig) as NlsConfiguration
55-
}
61+
const nlsConfig = JSON.parse(dataSettings) as NlsConfiguration
5662

57-
try {
58-
const nlsConfig = getNlsConfiguration(document)
5963
if (nlsConfig._resolvedLanguagePackCoreLocation) {
60-
const bundles = Object.create(null)
61-
nlsConfig.loadBundle = (bundle: any, _language: any, cb: any): void => {
64+
// NOTE@jsjoeio
65+
// Not sure why we use Object.create(null) instead of {}
66+
// They are not the same
67+
// See: https://stackoverflow.com/a/15518712/3015595
68+
// We copied this from ../../../lib/vscode/src/bootstrap.js#L143
69+
const bundles: {
70+
[key: string]: string
71+
} = Object.create(null)
72+
73+
type LoadBundleCallback = (_: undefined, result?: string) => void
74+
75+
nlsConfig.loadBundle = (bundle: string, _language: string, cb: LoadBundleCallback): void => {
6276
const result = bundles[bundle]
6377
if (result) {
6478
return cb(undefined, result)
6579
}
6680
// FIXME: Only works if path separators are /.
67-
const path = nlsConfig._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json"
68-
fetch(`${options.base}/vscode/resource/?path=${encodeURIComponent(path)}`)
81+
const path = createBundlePath(nlsConfig._resolvedLanguagePackCoreLocation || "", bundle)
82+
fetch(`${base}/vscode/resource/?path=${encodeURIComponent(path)}`)
6983
.then((response) => response.json())
7084
.then((json) => {
7185
bundles[bundle] = json
@@ -74,17 +88,61 @@ try {
7488
.catch(cb)
7589
}
7690
}
77-
;(self.require as any) = {
91+
92+
return nlsConfig
93+
}
94+
95+
type GetLoaderParams = {
96+
nlsConfig: NlsConfiguration
97+
options: Options
98+
_window: Window
99+
}
100+
101+
/**
102+
* Link to types in the loader source repo
103+
* https://github.com/microsoft/vscode-loader/blob/main/src/loader.d.ts#L280
104+
*/
105+
type Loader = {
106+
baseUrl: string
107+
recordStats: boolean
108+
// TODO@jsjoeio: There don't appear to be any types for trustedTypes yet.
109+
trustedTypesPolicy: FixMeLater
110+
paths: {
111+
[key: string]: string
112+
}
113+
"vs/nls": NlsConfiguration
114+
}
115+
116+
/**
117+
* A helper function which creates a script url if the value
118+
* is valid.
119+
*
120+
* Extracted into a function to make it easier to test
121+
*/
122+
export function _createScriptURL(value: string, origin: string): string {
123+
if (value.startsWith(origin)) {
124+
return value
125+
}
126+
throw new Error(`Invalid script url: ${value}`)
127+
}
128+
129+
/**
130+
* A helper function to get the require loader
131+
*
132+
* This used by VSCode/code-server
133+
* to load files.
134+
*
135+
* We extracted the logic into a function so that
136+
* it's easier to test.
137+
**/
138+
export function getConfigurationForLoader({ nlsConfig, options, _window }: GetLoaderParams) {
139+
const loader: Loader = {
78140
// Without the full URL VS Code will try to load file://.
79141
baseUrl: `${window.location.origin}${options.csStaticBase}/lib/vscode/out`,
80142
recordStats: true,
81-
// TODO: There don't appear to be any types for trustedTypes yet.
82-
trustedTypesPolicy: (window as any).trustedTypes?.createPolicy("amdLoader", {
143+
trustedTypesPolicy: (_window as FixMeLater).trustedTypes?.createPolicy("amdLoader", {
83144
createScriptURL(value: string): string {
84-
if (value.startsWith(window.location.origin)) {
85-
return value
86-
}
87-
throw new Error(`Invalid script url: ${value}`)
145+
return _createScriptURL(value, window.location.origin)
88146
},
89147
}),
90148
paths: {
@@ -100,25 +158,16 @@ try {
100158
},
101159
"vs/nls": nlsConfig,
102160
}
103-
} catch (error) {
104-
console.error(error)
105-
/* Probably fine. */
161+
162+
return loader
106163
}
107164

108-
export function setBodyBackgroundToThemeBackgroundColor(document: Document, localStorage: Storage) {
165+
/**
166+
* Sets the body background color to match the theme.
167+
*/
168+
export function setBodyBackgroundToThemeBackgroundColor(_document: Document, _localStorage: Storage) {
109169
const errorMsgPrefix = "[vscode]"
110-
111-
if (!document) {
112-
throw new Error(`${errorMsgPrefix} Could not set body background to theme background color. Document is undefined.`)
113-
}
114-
115-
if (!localStorage) {
116-
throw new Error(
117-
`${errorMsgPrefix} Could not set body background to theme background color. localStorage is undefined.`,
118-
)
119-
}
120-
121-
const colorThemeData = localStorage.getItem("colorThemeData")
170+
const colorThemeData = _localStorage.getItem("colorThemeData")
122171

123172
if (!colorThemeData) {
124173
throw new Error(
@@ -155,14 +204,48 @@ export function setBodyBackgroundToThemeBackgroundColor(document: Document, loca
155204
)
156205
}
157206

158-
document.body.style.background = editorBgColor
207+
_document.body.style.background = editorBgColor
159208

160209
return null
161210
}
162211

212+
/**
213+
* A helper function to encapsulate all the
214+
* logic used in this file.
215+
*
216+
* We purposely include all of this in a single function
217+
* so that it's easier to test.
218+
*/
219+
export function main(_document: Document | undefined, _window: Window | undefined, _localStorage: Storage | undefined) {
220+
if (!_document) {
221+
throw new Error(`document is undefined.`)
222+
}
223+
224+
if (!_window) {
225+
throw new Error(`window is undefined.`)
226+
}
227+
228+
if (!_localStorage) {
229+
throw new Error(`localStorage is undefined.`)
230+
}
231+
232+
const options = getOptions()
233+
const nlsConfig = getNlsConfiguration(_document, options.base)
234+
235+
const loader = getConfigurationForLoader({
236+
nlsConfig,
237+
options,
238+
_window,
239+
})
240+
241+
;(self.require as unknown as Loader) = loader
242+
243+
setBodyBackgroundToThemeBackgroundColor(_document, _localStorage)
244+
}
245+
163246
try {
164-
setBodyBackgroundToThemeBackgroundColor(document, localStorage)
247+
main(document, window, localStorage)
165248
} catch (error) {
166-
console.error("Something went wrong setting the body background to the theme background color.")
249+
console.error("[vscode] failed to initialize VS Code")
167250
console.error(error)
168251
}

0 commit comments

Comments
 (0)