-
Notifications
You must be signed in to change notification settings - Fork 15k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: improve feature string parsing (#23130)
* test: add pre-change snapshot of new-window event * move to .ts file for easier diff * refactor: improve feature string parsing logic * test: update snapshots * update type names per review * update comma-separated parse test * use for loop instead of reduce per review * tighten up types * avoid variable guest contents id returnValue in test snapshot
- Loading branch information
Showing
10 changed files
with
589 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* Utilities to parse comma-separated key value pairs used in browser APIs. | ||
* For example: "x=100,y=200,width=500,height=500" | ||
*/ | ||
import { BrowserWindowConstructorOptions } from 'electron'; | ||
|
||
type RequiredBrowserWindowConstructorOptions = Required<BrowserWindowConstructorOptions>; | ||
type IntegerBrowserWindowOptionKeys = { | ||
[K in keyof RequiredBrowserWindowConstructorOptions]: | ||
RequiredBrowserWindowConstructorOptions[K] extends number ? K : never | ||
}[keyof RequiredBrowserWindowConstructorOptions]; | ||
|
||
// This could be an array of keys, but an object allows us to add a compile-time | ||
// check validating that we haven't added an integer property to | ||
// BrowserWindowConstructorOptions that this module doesn't know about. | ||
const keysOfTypeNumberCompileTimeCheck: { [K in IntegerBrowserWindowOptionKeys] : true } = { | ||
x: true, | ||
y: true, | ||
width: true, | ||
height: true, | ||
minWidth: true, | ||
maxWidth: true, | ||
minHeight: true, | ||
maxHeight: true, | ||
opacity: true | ||
}; | ||
// Note `top` / `left` are special cases from the browser which we later convert | ||
// to y / x. | ||
const keysOfTypeNumber = ['top', 'left', ...Object.keys(keysOfTypeNumberCompileTimeCheck)]; | ||
|
||
/** | ||
* Note that we only allow "0" and "1" boolean conversion when the type is known | ||
* not to be an integer. | ||
* | ||
* The coercion of yes/no/1/0 represents best effort accordance with the spec: | ||
* https://html.spec.whatwg.org/multipage/window-object.html#concept-window-open-features-parse-boolean | ||
*/ | ||
type CoercedValue = string | number | boolean; | ||
function coerce (key: string, value: string): CoercedValue { | ||
if (keysOfTypeNumber.includes(key)) { | ||
return Number(value); | ||
} | ||
|
||
switch (value) { | ||
case 'true': | ||
case '1': | ||
case 'yes': | ||
case undefined: | ||
return true; | ||
case 'false': | ||
case '0': | ||
case 'no': | ||
return false; | ||
default: | ||
return value; | ||
} | ||
} | ||
|
||
export function parseCommaSeparatedKeyValue (source: string, useSoonToBeDeprecatedBehaviorForBareKeys: boolean) { | ||
const bareKeys = [] as string[]; | ||
const parsed = {} as { [key: string]: any }; | ||
for (const keyValuePair of source.split(',')) { | ||
const [key, value] = keyValuePair.split('=').map(str => str.trim()); | ||
if (useSoonToBeDeprecatedBehaviorForBareKeys && value === undefined) { | ||
bareKeys.push(key); | ||
continue; | ||
} | ||
parsed[key] = coerce(key, value); | ||
} | ||
|
||
return { parsed, bareKeys }; | ||
} | ||
|
||
export function parseWebViewWebPreferences (preferences: string) { | ||
return parseCommaSeparatedKeyValue(preferences, false).parsed; | ||
} | ||
|
||
const allowedWebPreferences = ['zoomFactor', 'nodeIntegration', 'enableRemoteModule', 'preload', 'javascript', 'contextIsolation', 'webviewTag'] as const; | ||
type AllowedWebPreference = (typeof allowedWebPreferences)[number]; | ||
|
||
/** | ||
* Parses a feature string that has the format used in window.open(). | ||
* | ||
* `useSoonToBeDeprecatedBehaviorForBareKeys` — In the html spec, windowFeatures keys | ||
* without values are interpreted as `true`. Previous versions of Electron did | ||
* not respect this. In order to not break any applications, this will be | ||
* flipped in the next major version. | ||
*/ | ||
export function parseFeatures ( | ||
features: string, | ||
useSoonToBeDeprecatedBehaviorForBareKeys: boolean = true | ||
) { | ||
const { parsed, bareKeys } = parseCommaSeparatedKeyValue(features, useSoonToBeDeprecatedBehaviorForBareKeys); | ||
|
||
const webPreferences: { [K in AllowedWebPreference]?: any } = {}; | ||
allowedWebPreferences.forEach((key) => { | ||
if (parsed[key] === undefined) return; | ||
webPreferences[key] = parsed[key]; | ||
delete parsed[key]; | ||
}); | ||
|
||
if (parsed.left !== undefined) parsed.x = parsed.left; | ||
if (parsed.top !== undefined) parsed.y = parsed.top; | ||
|
||
return { | ||
options: parsed as Omit<BrowserWindowConstructorOptions, 'webPreferences'> & { [key: string]: CoercedValue }, | ||
webPreferences, | ||
additionalFeatures: bareKeys | ||
}; | ||
} |
Oops, something went wrong.