Update dashboard, kb, memory +4 more (+28 ~18 -1)
This commit is contained in:
89
node_modules/puppeteer-core/src/common/AriaQueryHandler.ts
generated
vendored
Normal file
89
node_modules/puppeteer-core/src/common/AriaQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {ElementHandle} from '../api/ElementHandle.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
|
||||
|
||||
import {QueryHandler, type QuerySelector} from './QueryHandler.js';
|
||||
import type {AwaitableIterable} from './types.js';
|
||||
|
||||
interface ARIASelector {
|
||||
name?: string;
|
||||
role?: string;
|
||||
}
|
||||
|
||||
const isKnownAttribute = (
|
||||
attribute: string,
|
||||
): attribute is keyof ARIASelector => {
|
||||
return ['name', 'role'].includes(attribute);
|
||||
};
|
||||
|
||||
/**
|
||||
* The selectors consist of an accessible name to query for and optionally
|
||||
* further aria attributes on the form `[<attribute>=<value>]`.
|
||||
* Currently, we only support the `name` and `role` attribute.
|
||||
* The following examples showcase how the syntax works wrt. querying:
|
||||
*
|
||||
* - 'title[role="heading"]' queries for elements with name 'title' and role 'heading'.
|
||||
* - '[role="image"]' queries for elements with role 'image' and any name.
|
||||
* - 'label' queries for elements with name 'label' and any role.
|
||||
* - '[name=""][role="button"]' queries for elements with no name and role 'button'.
|
||||
*/
|
||||
const ATTRIBUTE_REGEXP =
|
||||
/\[\s*(?<attribute>\w+)\s*=\s*(?<quote>"|')(?<value>\\.|.*?(?=\k<quote>))\k<quote>\s*\]/g;
|
||||
const parseARIASelector = (selector: string): ARIASelector => {
|
||||
if (selector.length > 10_000) {
|
||||
throw new Error(`Selector ${selector} is too long`);
|
||||
}
|
||||
|
||||
const queryOptions: ARIASelector = {};
|
||||
const defaultName = selector.replace(
|
||||
ATTRIBUTE_REGEXP,
|
||||
(_, attribute, __, value) => {
|
||||
assert(
|
||||
isKnownAttribute(attribute),
|
||||
`Unknown aria attribute "${attribute}" in selector`,
|
||||
);
|
||||
queryOptions[attribute] = value;
|
||||
return '';
|
||||
},
|
||||
);
|
||||
if (defaultName && !queryOptions.name) {
|
||||
queryOptions.name = defaultName;
|
||||
}
|
||||
return queryOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class ARIAQueryHandler extends QueryHandler {
|
||||
static override querySelector: QuerySelector = async (
|
||||
node,
|
||||
selector,
|
||||
{ariaQuerySelector},
|
||||
) => {
|
||||
return await ariaQuerySelector(node, selector);
|
||||
};
|
||||
|
||||
static override async *queryAll(
|
||||
element: ElementHandle<Node>,
|
||||
selector: string,
|
||||
): AwaitableIterable<ElementHandle<Node>> {
|
||||
const {name, role} = parseARIASelector(selector);
|
||||
yield* element.queryAXTree(name, role);
|
||||
}
|
||||
|
||||
static override queryOne = async (
|
||||
element: ElementHandle<Node>,
|
||||
selector: string,
|
||||
): Promise<ElementHandle<Node> | null> => {
|
||||
return (
|
||||
(await AsyncIterableUtil.first(this.queryAll(element, selector))) ?? null
|
||||
);
|
||||
};
|
||||
}
|
||||
174
node_modules/puppeteer-core/src/common/BrowserConnector.ts
generated
vendored
Normal file
174
node_modules/puppeteer-core/src/common/BrowserConnector.ts
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {Browser} from '../api/Browser.js';
|
||||
import {_connectToBiDiBrowser} from '../bidi/BrowserConnector.js';
|
||||
import {_connectToCdpBrowser} from '../cdp/BrowserConnector.js';
|
||||
import {environment, isNode} from '../environment.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {isErrorLike} from '../util/ErrorLike.js';
|
||||
|
||||
import type {ConnectionTransport} from './ConnectionTransport.js';
|
||||
import type {ConnectOptions} from './ConnectOptions.js';
|
||||
|
||||
const getWebSocketTransportClass = async () => {
|
||||
return isNode
|
||||
? (await import('../node/NodeWebSocketTransport.js')).NodeWebSocketTransport
|
||||
: (await import('../common/BrowserWebSocketTransport.js'))
|
||||
.BrowserWebSocketTransport;
|
||||
};
|
||||
|
||||
/**
|
||||
* Users should never call this directly; it's called when calling
|
||||
* `puppeteer.connect`. This method attaches Puppeteer to an existing browser instance.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export async function _connectToBrowser(
|
||||
options: ConnectOptions,
|
||||
): Promise<Browser> {
|
||||
const {connectionTransport, endpointUrl} =
|
||||
await getConnectionTransport(options);
|
||||
|
||||
if (options.protocol === 'webDriverBiDi') {
|
||||
const bidiBrowser = await _connectToBiDiBrowser(
|
||||
connectionTransport,
|
||||
endpointUrl,
|
||||
options,
|
||||
);
|
||||
return bidiBrowser;
|
||||
} else {
|
||||
const cdpBrowser = await _connectToCdpBrowser(
|
||||
connectionTransport,
|
||||
endpointUrl,
|
||||
options,
|
||||
);
|
||||
return cdpBrowser;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes a websocket connection by given options and returns both transport and
|
||||
* endpoint url the transport is connected to.
|
||||
*/
|
||||
async function getConnectionTransport(
|
||||
options: ConnectOptions,
|
||||
): Promise<{connectionTransport: ConnectionTransport; endpointUrl: string}> {
|
||||
const {
|
||||
browserWSEndpoint,
|
||||
browserURL,
|
||||
channel,
|
||||
transport,
|
||||
headers = {},
|
||||
} = options;
|
||||
|
||||
assert(
|
||||
Number(!!browserWSEndpoint) +
|
||||
Number(!!browserURL) +
|
||||
Number(!!transport) +
|
||||
Number(!!channel) ===
|
||||
1,
|
||||
'Exactly one of browserWSEndpoint, browserURL, transport or channel must be passed to puppeteer.connect',
|
||||
);
|
||||
|
||||
if (transport) {
|
||||
return {connectionTransport: transport, endpointUrl: ''};
|
||||
} else if (browserWSEndpoint) {
|
||||
const WebSocketClass = await getWebSocketTransportClass();
|
||||
const connectionTransport: ConnectionTransport =
|
||||
await WebSocketClass.create(browserWSEndpoint, headers);
|
||||
return {
|
||||
connectionTransport: connectionTransport,
|
||||
endpointUrl: browserWSEndpoint,
|
||||
};
|
||||
} else if (browserURL) {
|
||||
const connectionURL = await getWSEndpoint(browserURL);
|
||||
const WebSocketClass = await getWebSocketTransportClass();
|
||||
const connectionTransport: ConnectionTransport =
|
||||
await WebSocketClass.create(connectionURL);
|
||||
return {
|
||||
connectionTransport: connectionTransport,
|
||||
endpointUrl: connectionURL,
|
||||
};
|
||||
} else if (options.channel && isNode) {
|
||||
const {detectBrowserPlatform, resolveDefaultUserDataDir, Browser} =
|
||||
await import('@puppeteer/browsers');
|
||||
const platform = detectBrowserPlatform();
|
||||
if (!platform) {
|
||||
throw new Error('Could not detect required browser platform');
|
||||
}
|
||||
const {convertPuppeteerChannelToBrowsersChannel} =
|
||||
await import('../node/LaunchOptions.js');
|
||||
const {join} = await import('node:path');
|
||||
const userDataDir = resolveDefaultUserDataDir(
|
||||
Browser.CHROME,
|
||||
platform,
|
||||
convertPuppeteerChannelToBrowsersChannel(options.channel),
|
||||
);
|
||||
const portPath = join(userDataDir, 'DevToolsActivePort');
|
||||
try {
|
||||
const fileContent = await environment.value.fs.promises.readFile(
|
||||
portPath,
|
||||
'ascii',
|
||||
);
|
||||
const [rawPort, rawPath] = fileContent
|
||||
.split('\n')
|
||||
.map(line => {
|
||||
return line.trim();
|
||||
})
|
||||
.filter(line => {
|
||||
return !!line;
|
||||
});
|
||||
if (!rawPort || !rawPath) {
|
||||
throw new Error(`Invalid DevToolsActivePort '${fileContent}' found`);
|
||||
}
|
||||
const port = parseInt(rawPort, 10);
|
||||
if (isNaN(port) || port <= 0 || port > 65535) {
|
||||
throw new Error(`Invalid port '${rawPort}' found`);
|
||||
}
|
||||
const browserWSEndpoint = `ws://localhost:${port}${rawPath}`;
|
||||
const WebSocketClass = await getWebSocketTransportClass();
|
||||
const connectionTransport = await WebSocketClass.create(
|
||||
browserWSEndpoint,
|
||||
headers,
|
||||
);
|
||||
return {
|
||||
connectionTransport: connectionTransport,
|
||||
endpointUrl: browserWSEndpoint,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Could not find DevToolsActivePort for ${options.channel} at ${portPath}`,
|
||||
{
|
||||
cause: error,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
throw new Error('Invalid connection options');
|
||||
}
|
||||
|
||||
async function getWSEndpoint(browserURL: string): Promise<string> {
|
||||
const endpointURL = new URL('/json/version', browserURL);
|
||||
|
||||
try {
|
||||
const result = await globalThis.fetch(endpointURL.toString(), {
|
||||
method: 'GET',
|
||||
});
|
||||
if (!result.ok) {
|
||||
throw new Error(`HTTP ${result.statusText}`);
|
||||
}
|
||||
const data = await result.json();
|
||||
return data.webSocketDebuggerUrl;
|
||||
} catch (error) {
|
||||
if (isErrorLike(error)) {
|
||||
error.message =
|
||||
`Failed to fetch browser webSocket URL from ${endpointURL}: ` +
|
||||
error.message;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
50
node_modules/puppeteer-core/src/common/BrowserWebSocketTransport.ts
generated
vendored
Normal file
50
node_modules/puppeteer-core/src/common/BrowserWebSocketTransport.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import type {ConnectionTransport} from './ConnectionTransport.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class BrowserWebSocketTransport implements ConnectionTransport {
|
||||
static create(url: string): Promise<BrowserWebSocketTransport> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const ws = new WebSocket(url);
|
||||
|
||||
ws.addEventListener('open', () => {
|
||||
return resolve(new BrowserWebSocketTransport(ws));
|
||||
});
|
||||
ws.addEventListener('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
#ws: WebSocket;
|
||||
onmessage?: (message: string) => void;
|
||||
onclose?: () => void;
|
||||
|
||||
constructor(ws: WebSocket) {
|
||||
this.#ws = ws;
|
||||
this.#ws.addEventListener('message', event => {
|
||||
if (this.onmessage) {
|
||||
this.onmessage.call(null, event.data);
|
||||
}
|
||||
});
|
||||
this.#ws.addEventListener('close', () => {
|
||||
if (this.onclose) {
|
||||
this.onclose.call(null);
|
||||
}
|
||||
});
|
||||
// Silently ignore all errors - we don't know what to do with them.
|
||||
this.#ws.addEventListener('error', () => {});
|
||||
}
|
||||
|
||||
send(message: string): void {
|
||||
this.#ws.send(message);
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.#ws.close();
|
||||
}
|
||||
}
|
||||
29
node_modules/puppeteer-core/src/common/CSSQueryHandler.ts
generated
vendored
Normal file
29
node_modules/puppeteer-core/src/common/CSSQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {PuppeteerInjectedUtil} from '../injected/injected.js';
|
||||
|
||||
import {QueryHandler} from './QueryHandler.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class CSSQueryHandler extends QueryHandler {
|
||||
static override querySelector = (
|
||||
element: Node,
|
||||
selector: string,
|
||||
{cssQuerySelector}: PuppeteerInjectedUtil,
|
||||
): Node | null => {
|
||||
return cssQuerySelector(element, selector);
|
||||
};
|
||||
static override querySelectorAll = (
|
||||
element: Node,
|
||||
selector: string,
|
||||
{cssQuerySelectorAll}: PuppeteerInjectedUtil,
|
||||
): Iterable<Node> => {
|
||||
return cssQuerySelectorAll(element, selector);
|
||||
};
|
||||
}
|
||||
174
node_modules/puppeteer-core/src/common/CallbackRegistry.ts
generated
vendored
Normal file
174
node_modules/puppeteer-core/src/common/CallbackRegistry.ts
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {Deferred} from '../util/Deferred.js';
|
||||
import {rewriteError} from '../util/ErrorLike.js';
|
||||
import type {GetIdFn} from '../util/incremental-id-generator.js';
|
||||
|
||||
import {ProtocolError, TargetCloseError} from './Errors.js';
|
||||
import {debugError} from './util.js';
|
||||
|
||||
/**
|
||||
* Manages callbacks and their IDs for the protocol request/response communication.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class CallbackRegistry {
|
||||
readonly #callbacks = new Map<number, Callback>();
|
||||
readonly #idGenerator: GetIdFn;
|
||||
|
||||
constructor(idGenerator: GetIdFn) {
|
||||
this.#idGenerator = idGenerator;
|
||||
}
|
||||
|
||||
create(
|
||||
label: string,
|
||||
timeout: number | undefined,
|
||||
request: (id: number) => void,
|
||||
): Promise<unknown> {
|
||||
const callback = new Callback(this.#idGenerator(), label, timeout);
|
||||
this.#callbacks.set(callback.id, callback);
|
||||
try {
|
||||
request(callback.id);
|
||||
} catch (error) {
|
||||
// We still throw sync errors synchronously and clean up the scheduled
|
||||
// callback.
|
||||
callback.promise.catch(debugError).finally(() => {
|
||||
this.#callbacks.delete(callback.id);
|
||||
});
|
||||
callback.reject(error as Error);
|
||||
throw error;
|
||||
}
|
||||
// Must only have sync code up until here.
|
||||
return callback.promise.finally(() => {
|
||||
this.#callbacks.delete(callback.id);
|
||||
});
|
||||
}
|
||||
|
||||
reject(id: number, message: string, originalMessage?: string): void {
|
||||
const callback = this.#callbacks.get(id);
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
this._reject(callback, message, originalMessage);
|
||||
}
|
||||
|
||||
rejectRaw(id: number, error: object): void {
|
||||
const callback = this.#callbacks.get(id);
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
callback.reject(error as any);
|
||||
}
|
||||
|
||||
_reject(
|
||||
callback: Callback,
|
||||
errorMessage: string | ProtocolError,
|
||||
originalMessage?: string,
|
||||
): void {
|
||||
let error: ProtocolError;
|
||||
let message: string;
|
||||
if (errorMessage instanceof ProtocolError) {
|
||||
error = errorMessage;
|
||||
error.cause = callback.error;
|
||||
message = errorMessage.message;
|
||||
} else {
|
||||
error = callback.error;
|
||||
message = errorMessage;
|
||||
}
|
||||
|
||||
callback.reject(
|
||||
rewriteError(
|
||||
error,
|
||||
`Protocol error (${callback.label}): ${message}`,
|
||||
originalMessage,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
resolve(id: number, value: unknown): void {
|
||||
const callback = this.#callbacks.get(id);
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
callback.resolve(value);
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
for (const callback of this.#callbacks.values()) {
|
||||
// TODO: probably we can accept error messages as params.
|
||||
this._reject(callback, new TargetCloseError('Target closed'));
|
||||
}
|
||||
this.#callbacks.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getPendingProtocolErrors(): Error[] {
|
||||
const result: Error[] = [];
|
||||
for (const callback of this.#callbacks.values()) {
|
||||
result.push(
|
||||
new Error(
|
||||
`${callback.label} timed out. Trace: ${callback.error.stack}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
export class Callback {
|
||||
#id: number;
|
||||
#error = new ProtocolError();
|
||||
#deferred = Deferred.create<unknown>();
|
||||
#timer?: ReturnType<typeof setTimeout>;
|
||||
#label: string;
|
||||
|
||||
constructor(id: number, label: string, timeout?: number) {
|
||||
this.#id = id;
|
||||
this.#label = label;
|
||||
if (timeout) {
|
||||
this.#timer = setTimeout(() => {
|
||||
this.#deferred.reject(
|
||||
rewriteError(
|
||||
this.#error,
|
||||
`${label} timed out. Increase the 'protocolTimeout' setting in launch/connect calls for a higher timeout if needed.`,
|
||||
),
|
||||
);
|
||||
}, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
resolve(value: unknown): void {
|
||||
clearTimeout(this.#timer);
|
||||
this.#deferred.resolve(value);
|
||||
}
|
||||
|
||||
reject(error: Error): void {
|
||||
clearTimeout(this.#timer);
|
||||
this.#deferred.reject(error);
|
||||
}
|
||||
|
||||
get id(): number {
|
||||
return this.#id;
|
||||
}
|
||||
|
||||
get promise(): Promise<unknown> {
|
||||
return this.#deferred.valueOrThrow();
|
||||
}
|
||||
|
||||
get error(): ProtocolError {
|
||||
return this.#error;
|
||||
}
|
||||
|
||||
get label(): string {
|
||||
return this.#label;
|
||||
}
|
||||
}
|
||||
199
node_modules/puppeteer-core/src/common/Configuration.ts
generated
vendored
Normal file
199
node_modules/puppeteer-core/src/common/Configuration.ts
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {SupportedBrowser} from './SupportedBrowser.js';
|
||||
|
||||
/**
|
||||
* Defines experiment options for Puppeteer.
|
||||
*
|
||||
* See individual properties for more information.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ExperimentsConfiguration = Record<string, never>;
|
||||
|
||||
/**
|
||||
* Defines options to configure Puppeteer's behavior during installation and
|
||||
* runtime.
|
||||
*
|
||||
* See individual properties for more information.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface Configuration {
|
||||
/**
|
||||
* Defines the directory to be used by Puppeteer for caching.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CACHE_DIR`.
|
||||
*
|
||||
* @defaultValue `path.join(os.homedir(), '.cache', 'puppeteer')`
|
||||
*/
|
||||
cacheDirectory?: string;
|
||||
/**
|
||||
* Specifies an executable path to be used in
|
||||
* {@link PuppeteerNode.launch | puppeteer.launch}.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_EXECUTABLE_PATH`.
|
||||
*
|
||||
* @defaultValue **Auto-computed.**
|
||||
*/
|
||||
executablePath?: string;
|
||||
/**
|
||||
* Specifies which browser you'd like Puppeteer to use.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_BROWSER`.
|
||||
*
|
||||
* @defaultValue `chrome`
|
||||
*/
|
||||
defaultBrowser?: SupportedBrowser;
|
||||
/**
|
||||
* Defines the directory to be used by Puppeteer for creating temporary files.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_TMP_DIR`.
|
||||
*
|
||||
* @defaultValue `os.tmpdir()`
|
||||
*/
|
||||
temporaryDirectory?: string;
|
||||
/**
|
||||
* Tells Puppeteer to not download during installation.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_SKIP_DOWNLOAD`.
|
||||
*/
|
||||
skipDownload?: boolean;
|
||||
/**
|
||||
* Tells Puppeteer to log at the given level.
|
||||
*
|
||||
* @defaultValue `warn`
|
||||
*/
|
||||
logLevel?: 'silent' | 'error' | 'warn';
|
||||
/**
|
||||
* Defines experimental options for Puppeteer.
|
||||
*/
|
||||
experiments?: ExperimentsConfiguration;
|
||||
|
||||
chrome?: ChromeSettings;
|
||||
['chrome-headless-shell']?: ChromeHeadlessShellSettings;
|
||||
firefox?: FirefoxSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ChromeSettings {
|
||||
/**
|
||||
* Tells Puppeteer to not download the browser during installation.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CHROME_SKIP_DOWNLOAD`.
|
||||
*
|
||||
* @defaultValue false
|
||||
*/
|
||||
skipDownload?: boolean;
|
||||
/**
|
||||
* Specifies the URL prefix that is used to download the browser.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CHROME_DOWNLOAD_BASE_URL`.
|
||||
*
|
||||
* @remarks
|
||||
* This must include the protocol and may even need a path prefix.
|
||||
* This must **not** include a trailing slash similar to the default.
|
||||
*
|
||||
* @defaultValue https://storage.googleapis.com/chrome-for-testing-public
|
||||
*/
|
||||
downloadBaseUrl?: string;
|
||||
/**
|
||||
* Specifies a certain version of the browser you'd like Puppeteer to use.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CHROME_VERSION`
|
||||
* or `PUPPETEER_SKIP_CHROME_DOWNLOAD`.
|
||||
*
|
||||
* See {@link PuppeteerNode.launch | puppeteer.launch} on how executable path
|
||||
* is inferred.
|
||||
*
|
||||
* @example 119.0.6045.105
|
||||
* @defaultValue The pinned browser version supported by the current Puppeteer
|
||||
* version.
|
||||
*/
|
||||
version?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ChromeHeadlessShellSettings {
|
||||
/**
|
||||
* Tells Puppeteer to not download the browser during installation.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CHROME_HEADLESS_SHELL_SKIP_DOWNLOAD`
|
||||
* or `PUPPETEER_SKIP_CHROME_HEADLESS_SHELL_DOWNLOAD`.
|
||||
*
|
||||
* @defaultValue false
|
||||
*/
|
||||
skipDownload?: boolean;
|
||||
/**
|
||||
* Specifies the URL prefix that is used to download the browser.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CHROME_HEADLESS_SHELL_DOWNLOAD_BASE_URL`.
|
||||
*
|
||||
* @remarks
|
||||
* This must include the protocol and may even need a path prefix.
|
||||
* This must **not** include a trailing slash similar to the default.
|
||||
*
|
||||
* @defaultValue https://storage.googleapis.com/chrome-for-testing-public
|
||||
*/
|
||||
downloadBaseUrl?: string;
|
||||
/**
|
||||
* Specifies a certain version of the browser you'd like Puppeteer to use.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_CHROME_HEADLESS_SHELL_VERSION`.
|
||||
*
|
||||
* See {@link PuppeteerNode.launch | puppeteer.launch} on how executable path
|
||||
* is inferred.
|
||||
*
|
||||
* @example 119.0.6045.105
|
||||
* @defaultValue The pinned browser version supported by the current Puppeteer
|
||||
* version.
|
||||
*/
|
||||
version?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface FirefoxSettings {
|
||||
/**
|
||||
* Tells Puppeteer to not download the browser during installation.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_FIREFOX_SKIP_DOWNLOAD`.
|
||||
*
|
||||
* @defaultValue true
|
||||
*/
|
||||
skipDownload?: boolean;
|
||||
/**
|
||||
* Specifies the URL prefix that is used to download the browser.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_FIREFOX_DOWNLOAD_BASE_URL`.
|
||||
*
|
||||
* @remarks
|
||||
* This must include the protocol and may even need a path prefix.
|
||||
* This must **not** include a trailing slash similar to the default.
|
||||
*
|
||||
* @defaultValue https://archive.mozilla.org/pub/firefox/releases
|
||||
*/
|
||||
downloadBaseUrl?: string;
|
||||
/**
|
||||
* Specifies a certain version of the browser you'd like Puppeteer to use.
|
||||
*
|
||||
* Can be overridden by `PUPPETEER_FIREFOX_VERSION`.
|
||||
*
|
||||
* See {@link PuppeteerNode.launch | puppeteer.launch} on how executable path
|
||||
* is inferred.
|
||||
*
|
||||
* @example stable_129.0
|
||||
* @defaultValue The pinned browser version supported by the current Puppeteer
|
||||
* version.
|
||||
*/
|
||||
version?: string;
|
||||
}
|
||||
157
node_modules/puppeteer-core/src/common/ConnectOptions.ts
generated
vendored
Normal file
157
node_modules/puppeteer-core/src/common/ConnectOptions.ts
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {Session} from 'webdriver-bidi-protocol';
|
||||
|
||||
import type {
|
||||
IsPageTargetCallback,
|
||||
TargetFilterCallback,
|
||||
} from '../api/Browser.js';
|
||||
|
||||
import type {ConnectionTransport} from './ConnectionTransport.js';
|
||||
import type {DownloadBehavior} from './DownloadBehavior.js';
|
||||
import type {Viewport} from './Viewport.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ProtocolType = 'cdp' | 'webDriverBiDi';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type SupportedWebDriverCapability = Exclude<
|
||||
Session.CapabilityRequest,
|
||||
'unhandledPromptBehavior' | 'acceptInsecureCerts'
|
||||
>;
|
||||
|
||||
/**
|
||||
* WebDriver BiDi capabilities that are not set by Puppeteer itself.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface SupportedWebDriverCapabilities {
|
||||
firstMatch?: SupportedWebDriverCapability[];
|
||||
alwaysMatch?: SupportedWebDriverCapability;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ChromeReleaseChannel =
|
||||
| 'chrome'
|
||||
| 'chrome-beta'
|
||||
| 'chrome-canary'
|
||||
| 'chrome-dev';
|
||||
|
||||
/**
|
||||
* Generic browser options that can be passed when launching any browser or when
|
||||
* connecting to an existing browser instance.
|
||||
* @public
|
||||
*/
|
||||
export interface ConnectOptions {
|
||||
/**
|
||||
* Whether to ignore HTTPS errors during navigation.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
acceptInsecureCerts?: boolean;
|
||||
/**
|
||||
* If specified, puppeteer looks for an open WebSocket at the well-known
|
||||
* default user data directory for the specified channel and attempts to
|
||||
* connect to it using ws://localhost:$ActivePort/devtools/browser. Only works
|
||||
* for Chrome and when run in Node.js.
|
||||
*
|
||||
* This option is experimental when used with puppeteer.connect().
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
channel?: ChromeReleaseChannel;
|
||||
/**
|
||||
* Experimental setting to disable monitoring network events by default. When
|
||||
* set to `false`, parts of Puppeteer that depend on network events would not
|
||||
* work such as HTTPRequest and HTTPResponse.
|
||||
*
|
||||
* @experimental
|
||||
* @defaultValue `true`
|
||||
*/
|
||||
networkEnabled?: boolean;
|
||||
/**
|
||||
* Sets the viewport for each page.
|
||||
*
|
||||
* @defaultValue '\{width: 800, height: 600\}'
|
||||
*/
|
||||
defaultViewport?: Viewport | null;
|
||||
/**
|
||||
* Sets the download behavior for the context.
|
||||
*/
|
||||
downloadBehavior?: DownloadBehavior;
|
||||
/**
|
||||
* Slows down Puppeteer operations by the specified amount of milliseconds to
|
||||
* aid debugging.
|
||||
*/
|
||||
slowMo?: number;
|
||||
/**
|
||||
* Callback to decide if Puppeteer should connect to a given target or not.
|
||||
*/
|
||||
targetFilter?: TargetFilterCallback;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_isPageTarget?: IsPageTargetCallback;
|
||||
|
||||
/**
|
||||
* Whether to handle the DevTools windows as pages in Puppeteer. Supported
|
||||
* only in Chrome with CDP.
|
||||
*
|
||||
* @defaultValue 'false'
|
||||
*/
|
||||
handleDevToolsAsPage?: boolean;
|
||||
|
||||
/**
|
||||
* @defaultValue Determined at run time:
|
||||
*
|
||||
* - Launching Chrome - 'cdp'.
|
||||
*
|
||||
* - Launching Firefox - 'webDriverBiDi'.
|
||||
*
|
||||
* - Connecting to a browser - 'cdp'.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
protocol?: ProtocolType;
|
||||
/**
|
||||
* Timeout setting for individual protocol (CDP) calls.
|
||||
*
|
||||
* @defaultValue `180_000`
|
||||
*/
|
||||
protocolTimeout?: number;
|
||||
|
||||
browserWSEndpoint?: string;
|
||||
browserURL?: string;
|
||||
transport?: ConnectionTransport;
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Custom ID generator for CDP / BiDi messages. Useful if the same transport
|
||||
* is shared for multiple connections.
|
||||
*/
|
||||
idGenerator?: () => number;
|
||||
|
||||
/**
|
||||
* Headers to use for the web socket connection.
|
||||
* @remarks
|
||||
* Only works in the Node.js environment.
|
||||
*/
|
||||
headers?: Record<string, string>;
|
||||
|
||||
/**
|
||||
* WebDriver BiDi capabilities passed to BiDi `session.new`.
|
||||
*
|
||||
* @remarks
|
||||
* Only works for `protocol="webDriverBiDi"` and {@link Puppeteer.connect}.
|
||||
*/
|
||||
capabilities?: SupportedWebDriverCapabilities;
|
||||
}
|
||||
15
node_modules/puppeteer-core/src/common/ConnectionTransport.ts
generated
vendored
Normal file
15
node_modules/puppeteer-core/src/common/ConnectionTransport.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ConnectionTransport {
|
||||
send(message: string): void;
|
||||
close(): void;
|
||||
onmessage?: (message: string) => void;
|
||||
onclose?: () => void;
|
||||
}
|
||||
146
node_modules/puppeteer-core/src/common/ConsoleMessage.ts
generated
vendored
Normal file
146
node_modules/puppeteer-core/src/common/ConsoleMessage.ts
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {Protocol} from 'devtools-protocol';
|
||||
|
||||
import type {Frame} from '../api/Frame.js';
|
||||
import type {JSHandle} from '../api/JSHandle.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ConsoleMessageLocation {
|
||||
/**
|
||||
* URL of the resource if known or `undefined` otherwise.
|
||||
*/
|
||||
url?: string;
|
||||
|
||||
/**
|
||||
* 0-based line number in the resource if known or `undefined` otherwise.
|
||||
*/
|
||||
lineNumber?: number;
|
||||
|
||||
/**
|
||||
* 0-based column number in the resource if known or `undefined` otherwise.
|
||||
*/
|
||||
columnNumber?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* The supported types for console messages.
|
||||
* @public
|
||||
*/
|
||||
export type ConsoleMessageType =
|
||||
| 'log'
|
||||
| 'debug'
|
||||
| 'info'
|
||||
| 'error'
|
||||
| 'warn'
|
||||
| 'dir'
|
||||
| 'dirxml'
|
||||
| 'table'
|
||||
| 'trace'
|
||||
| 'clear'
|
||||
| 'startGroup'
|
||||
| 'startGroupCollapsed'
|
||||
| 'endGroup'
|
||||
| 'assert'
|
||||
| 'profile'
|
||||
| 'profileEnd'
|
||||
| 'count'
|
||||
| 'timeEnd'
|
||||
| 'verbose';
|
||||
|
||||
/**
|
||||
* ConsoleMessage objects are dispatched by page via the 'console' event.
|
||||
* @public
|
||||
*/
|
||||
export class ConsoleMessage {
|
||||
#type: ConsoleMessageType;
|
||||
#text: string;
|
||||
#args: JSHandle[];
|
||||
#stackTraceLocations: ConsoleMessageLocation[];
|
||||
#frame?: Frame;
|
||||
#rawStackTrace?: Protocol.Runtime.StackTrace;
|
||||
#targetId?: string;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(
|
||||
type: ConsoleMessageType,
|
||||
text: string,
|
||||
args: JSHandle[],
|
||||
stackTraceLocations: ConsoleMessageLocation[],
|
||||
frame?: Frame,
|
||||
rawStackTrace?: Protocol.Runtime.StackTrace,
|
||||
targetId?: string,
|
||||
) {
|
||||
this.#type = type;
|
||||
this.#text = text;
|
||||
this.#args = args;
|
||||
this.#stackTraceLocations = stackTraceLocations;
|
||||
this.#frame = frame;
|
||||
this.#rawStackTrace = rawStackTrace;
|
||||
this.#targetId = targetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the console message.
|
||||
*/
|
||||
type(): ConsoleMessageType {
|
||||
return this.#type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The text of the console message.
|
||||
*/
|
||||
text(): string {
|
||||
return this.#text;
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of arguments passed to the console.
|
||||
*/
|
||||
args(): JSHandle[] {
|
||||
return this.#args;
|
||||
}
|
||||
|
||||
/**
|
||||
* The location of the console message.
|
||||
*/
|
||||
location(): ConsoleMessageLocation {
|
||||
return (
|
||||
this.#stackTraceLocations[0] ??
|
||||
(this.#frame ? {url: this.#frame.url()} : {})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The array of locations on the stack of the console message.
|
||||
*/
|
||||
stackTrace(): ConsoleMessageLocation[] {
|
||||
return this.#stackTraceLocations;
|
||||
}
|
||||
|
||||
/**
|
||||
* The underlying protocol stack trace if available.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
_rawStackTrace(): Protocol.Runtime.StackTrace | undefined {
|
||||
return this.#rawStackTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* The targetId from which this console message originated.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
_targetId(): string | undefined {
|
||||
return this.#targetId;
|
||||
}
|
||||
}
|
||||
241
node_modules/puppeteer-core/src/common/Cookie.ts
generated
vendored
Normal file
241
node_modules/puppeteer-core/src/common/Cookie.ts
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the cookie's 'SameSite' status:
|
||||
* https://tools.ietf.org/html/draft-west-first-party-cookies
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CookieSameSite = 'Strict' | 'Lax' | 'None' | 'Default';
|
||||
|
||||
/**
|
||||
* Represents the cookie's 'Priority' status:
|
||||
* https://tools.ietf.org/html/draft-west-cookie-priority-00
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CookiePriority = 'Low' | 'Medium' | 'High';
|
||||
|
||||
/**
|
||||
* Represents the source scheme of the origin that originally set the cookie. A value of
|
||||
* "Unset" allows protocol clients to emulate legacy cookie scope for the scheme.
|
||||
* This is a temporary ability and it will be removed in the future.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CookieSourceScheme = 'Unset' | 'NonSecure' | 'Secure';
|
||||
|
||||
/**
|
||||
* Represents a cookie partition key in Chrome.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface CookiePartitionKey {
|
||||
/**
|
||||
* The site of the top-level URL the browser was visiting at the start of the request
|
||||
* to the endpoint that set the cookie.
|
||||
*
|
||||
* In Chrome, maps to the CDP's `topLevelSite` partition key.
|
||||
*/
|
||||
sourceOrigin: string;
|
||||
/**
|
||||
* Indicates if the cookie has any ancestors that are cross-site to
|
||||
* the topLevelSite.
|
||||
*
|
||||
* Supported only in Chrome.
|
||||
*/
|
||||
hasCrossSiteAncestor?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a cookie object.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface Cookie extends CookieData {
|
||||
/**
|
||||
* Cookie path.
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
* Cookie expiration date as the number of seconds since the UNIX epoch. Set to `-1` for
|
||||
* session cookies
|
||||
*/
|
||||
expires: number;
|
||||
/**
|
||||
* Cookie size.
|
||||
*/
|
||||
size: number;
|
||||
/**
|
||||
* True if cookie is secure.
|
||||
*/
|
||||
secure: boolean;
|
||||
/**
|
||||
* True in case of session cookie.
|
||||
*/
|
||||
session: boolean;
|
||||
/**
|
||||
* True if cookie partition key is opaque. Supported only in Chrome.
|
||||
*/
|
||||
partitionKeyOpaque?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie parameter object used to set cookies in the page-level cookies
|
||||
* API.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface CookieParam {
|
||||
/**
|
||||
* Cookie name.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Cookie value.
|
||||
*/
|
||||
value: string;
|
||||
/**
|
||||
* The request-URI to associate with the setting of the cookie. This value can affect
|
||||
* the default domain, path, and source scheme values of the created cookie.
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* Cookie domain.
|
||||
*/
|
||||
domain?: string;
|
||||
/**
|
||||
* Cookie path.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* True if cookie is secure.
|
||||
*/
|
||||
secure?: boolean;
|
||||
/**
|
||||
* True if cookie is http-only.
|
||||
*/
|
||||
httpOnly?: boolean;
|
||||
/**
|
||||
* Cookie SameSite type.
|
||||
*/
|
||||
sameSite?: CookieSameSite;
|
||||
/**
|
||||
* Cookie expiration date, session cookie if not set
|
||||
*/
|
||||
expires?: number;
|
||||
/**
|
||||
* Cookie Priority. Supported only in Chrome.
|
||||
*/
|
||||
priority?: CookiePriority;
|
||||
/**
|
||||
* @deprecated Always ignored.
|
||||
*/
|
||||
sameParty?: boolean;
|
||||
/**
|
||||
* Cookie source scheme type. Supported only in Chrome.
|
||||
*/
|
||||
sourceScheme?: CookieSourceScheme;
|
||||
/**
|
||||
* Cookie partition key. In Chrome, it matches the top-level site the
|
||||
* partitioned cookie is available in. In Firefox, it matches the
|
||||
* source origin in the
|
||||
* {@link https://w3c.github.io/webdriver-bidi/#type-storage-PartitionKey | PartitionKey }.
|
||||
*/
|
||||
partitionKey?: CookiePartitionKey | string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie parameter object used to set cookies in the browser-level cookies
|
||||
* API.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface CookieData {
|
||||
/**
|
||||
* Cookie name.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Cookie value.
|
||||
*/
|
||||
value: string;
|
||||
/**
|
||||
* Cookie domain.
|
||||
*/
|
||||
domain: string;
|
||||
/**
|
||||
* Cookie path.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* True if cookie is secure.
|
||||
*/
|
||||
secure?: boolean;
|
||||
/**
|
||||
* True if cookie is http-only.
|
||||
*/
|
||||
httpOnly?: boolean;
|
||||
/**
|
||||
* Cookie SameSite type.
|
||||
*/
|
||||
sameSite?: CookieSameSite;
|
||||
/**
|
||||
* Cookie expiration date, session cookie if not set
|
||||
*/
|
||||
expires?: number;
|
||||
/**
|
||||
* Cookie Priority. Supported only in Chrome.
|
||||
*/
|
||||
priority?: CookiePriority;
|
||||
/**
|
||||
* @deprecated Always set to false. Supported only in Chrome.
|
||||
*/
|
||||
sameParty?: boolean;
|
||||
/**
|
||||
* Cookie source scheme type. Supported only in Chrome.
|
||||
*/
|
||||
sourceScheme?: CookieSourceScheme;
|
||||
/**
|
||||
* Cookie partition key. In Chrome, it matches the top-level site the
|
||||
* partitioned cookie is available in. In Firefox, it matches the
|
||||
* source origin in the
|
||||
* {@link https://w3c.github.io/webdriver-bidi/#type-storage-PartitionKey | PartitionKey }.
|
||||
*/
|
||||
partitionKey?: CookiePartitionKey | string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface DeleteCookiesRequest {
|
||||
/**
|
||||
* Name of the cookies to remove.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* If specified, deletes all the cookies with the given name where domain and path match
|
||||
* provided URL. Otherwise, deletes only cookies related to the current page's domain.
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* If specified, deletes only cookies with the exact domain.
|
||||
*/
|
||||
domain?: string;
|
||||
/**
|
||||
* If specified, deletes only cookies with the exact path.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* If specified, deletes cookies in the given partition key. In
|
||||
* Chrome, partitionKey matches the top-level site the partitioned
|
||||
* cookie is available in.
|
||||
* In Firefox, it matches the source origin in the
|
||||
* {@link https://w3c.github.io/webdriver-bidi/#type-storage-PartitionKey | PartitionKey }.
|
||||
*/
|
||||
partitionKey?: CookiePartitionKey | string;
|
||||
}
|
||||
164
node_modules/puppeteer-core/src/common/CustomQueryHandler.ts
generated
vendored
Normal file
164
node_modules/puppeteer-core/src/common/CustomQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {PuppeteerInjectedUtil} from '../injected/injected.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {interpolateFunction, stringifyFunction} from '../util/Function.js';
|
||||
|
||||
import {
|
||||
QueryHandler,
|
||||
type QuerySelector,
|
||||
type QuerySelectorAll,
|
||||
} from './QueryHandler.js';
|
||||
import {scriptInjector} from './ScriptInjector.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface CustomQueryHandler {
|
||||
/**
|
||||
* Searches for a {@link https://developer.mozilla.org/en-US/docs/Web/API/Node | Node} matching the given `selector` from {@link https://developer.mozilla.org/en-US/docs/Web/API/Node | node}.
|
||||
*/
|
||||
queryOne?: (node: Node, selector: string) => Node | null;
|
||||
/**
|
||||
* Searches for some {@link https://developer.mozilla.org/en-US/docs/Web/API/Node | Nodes} matching the given `selector` from {@link https://developer.mozilla.org/en-US/docs/Web/API/Node | node}.
|
||||
*/
|
||||
queryAll?: (node: Node, selector: string) => Iterable<Node>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The registry of {@link CustomQueryHandler | custom query handlers}.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* Puppeteer.customQueryHandlers.register('lit', { … });
|
||||
* const aHandle = await page.$('lit/…');
|
||||
* ```
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class CustomQueryHandlerRegistry {
|
||||
#handlers = new Map<
|
||||
string,
|
||||
[registerScript: string, Handler: typeof QueryHandler]
|
||||
>();
|
||||
|
||||
get(name: string): typeof QueryHandler | undefined {
|
||||
const handler = this.#handlers.get(name);
|
||||
return handler ? handler[1] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link CustomQueryHandler | custom query handler}.
|
||||
*
|
||||
* @remarks
|
||||
* After registration, the handler can be used everywhere where a selector is
|
||||
* expected by prepending the selection string with `<name>/`. The name is
|
||||
* only allowed to consist of lower- and upper case latin letters.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* Puppeteer.customQueryHandlers.register('lit', { … });
|
||||
* const aHandle = await page.$('lit/…');
|
||||
* ```
|
||||
*
|
||||
* @param name - Name to register under.
|
||||
* @param queryHandler - {@link CustomQueryHandler | Custom query handler} to
|
||||
* register.
|
||||
*/
|
||||
register(name: string, handler: CustomQueryHandler): void {
|
||||
assert(
|
||||
!this.#handlers.has(name),
|
||||
`Cannot register over existing handler: ${name}`,
|
||||
);
|
||||
assert(
|
||||
/^[a-zA-Z]+$/.test(name),
|
||||
`Custom query handler names may only contain [a-zA-Z]`,
|
||||
);
|
||||
assert(
|
||||
handler.queryAll || handler.queryOne,
|
||||
`At least one query method must be implemented.`,
|
||||
);
|
||||
|
||||
const Handler = class extends QueryHandler {
|
||||
static override querySelectorAll: QuerySelectorAll = interpolateFunction(
|
||||
(node, selector, PuppeteerUtil) => {
|
||||
return PuppeteerUtil.customQuerySelectors
|
||||
.get(PLACEHOLDER('name'))!
|
||||
.querySelectorAll(node, selector);
|
||||
},
|
||||
{name: JSON.stringify(name)},
|
||||
);
|
||||
static override querySelector: QuerySelector = interpolateFunction(
|
||||
(node, selector, PuppeteerUtil) => {
|
||||
return PuppeteerUtil.customQuerySelectors
|
||||
.get(PLACEHOLDER('name'))!
|
||||
.querySelector(node, selector);
|
||||
},
|
||||
{name: JSON.stringify(name)},
|
||||
);
|
||||
};
|
||||
const registerScript = interpolateFunction(
|
||||
(PuppeteerUtil: PuppeteerInjectedUtil) => {
|
||||
PuppeteerUtil.customQuerySelectors.register(PLACEHOLDER('name'), {
|
||||
queryAll: PLACEHOLDER('queryAll'),
|
||||
queryOne: PLACEHOLDER('queryOne'),
|
||||
});
|
||||
},
|
||||
{
|
||||
name: JSON.stringify(name),
|
||||
queryAll: handler.queryAll
|
||||
? stringifyFunction(handler.queryAll)
|
||||
: String(undefined),
|
||||
queryOne: handler.queryOne
|
||||
? stringifyFunction(handler.queryOne)
|
||||
: String(undefined),
|
||||
},
|
||||
).toString();
|
||||
|
||||
this.#handlers.set(name, [registerScript, Handler]);
|
||||
scriptInjector.append(registerScript);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the {@link CustomQueryHandler | custom query handler} for the
|
||||
* given name.
|
||||
*
|
||||
* @throws `Error` if there is no handler under the given name.
|
||||
*/
|
||||
unregister(name: string): void {
|
||||
const handler = this.#handlers.get(name);
|
||||
if (!handler) {
|
||||
throw new Error(`Cannot unregister unknown handler: ${name}`);
|
||||
}
|
||||
scriptInjector.pop(handler[0]);
|
||||
this.#handlers.delete(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all {@link CustomQueryHandler | custom query handlers}.
|
||||
*/
|
||||
names(): string[] {
|
||||
return [...this.#handlers.keys()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters all custom query handlers.
|
||||
*/
|
||||
clear(): void {
|
||||
for (const [registerScript] of this.#handlers) {
|
||||
scriptInjector.pop(registerScript);
|
||||
}
|
||||
this.#handlers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const customQueryHandlers = new CustomQueryHandlerRegistry();
|
||||
126
node_modules/puppeteer-core/src/common/Debug.ts
generated
vendored
Normal file
126
node_modules/puppeteer-core/src/common/Debug.ts
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type Debug from 'debug';
|
||||
|
||||
import {isNode} from '../environment.js';
|
||||
|
||||
declare global {
|
||||
const __PUPPETEER_DEBUG: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
let debugModule: typeof Debug | null = null;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export async function importDebug(): Promise<typeof Debug> {
|
||||
if (!debugModule) {
|
||||
debugModule = (await import('debug')).default;
|
||||
}
|
||||
return debugModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* A debug function that can be used in any environment.
|
||||
*
|
||||
* @remarks
|
||||
* If used in Node, it falls back to the
|
||||
* {@link https://www.npmjs.com/package/debug | debug module}. In the browser it
|
||||
* uses `console.log`.
|
||||
*
|
||||
* In Node, use the `DEBUG` environment variable to control logging:
|
||||
*
|
||||
* ```
|
||||
* DEBUG=* // logs all channels
|
||||
* DEBUG=foo // logs the `foo` channel
|
||||
* DEBUG=foo* // logs any channels starting with `foo`
|
||||
* ```
|
||||
*
|
||||
* In the browser, set `window.__PUPPETEER_DEBUG` to a string:
|
||||
*
|
||||
* ```
|
||||
* window.__PUPPETEER_DEBUG='*'; // logs all channels
|
||||
* window.__PUPPETEER_DEBUG='foo'; // logs the `foo` channel
|
||||
* window.__PUPPETEER_DEBUG='foo*'; // logs any channels starting with `foo`
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```
|
||||
* const log = debug('Page');
|
||||
*
|
||||
* log('new page created')
|
||||
* // logs "Page: new page created"
|
||||
* ```
|
||||
*
|
||||
* @param prefix - this will be prefixed to each log.
|
||||
* @returns a function that can be called to log to that debug channel.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export const debug = (prefix: string): ((...args: unknown[]) => void) => {
|
||||
if (isNode) {
|
||||
return async (...logArgs: unknown[]) => {
|
||||
if (captureLogs) {
|
||||
capturedLogs.push(prefix + logArgs);
|
||||
}
|
||||
(await importDebug())(prefix)(logArgs);
|
||||
};
|
||||
}
|
||||
|
||||
return (...logArgs: unknown[]): void => {
|
||||
const debugLevel = (globalThis as any).__PUPPETEER_DEBUG;
|
||||
if (!debugLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
const everythingShouldBeLogged = debugLevel === '*';
|
||||
|
||||
const prefixMatchesDebugLevel =
|
||||
everythingShouldBeLogged ||
|
||||
/**
|
||||
* If the debug level is `foo*`, that means we match any prefix that
|
||||
* starts with `foo`. If the level is `foo`, we match only the prefix
|
||||
* `foo`.
|
||||
*/
|
||||
(debugLevel.endsWith('*')
|
||||
? prefix.startsWith(debugLevel)
|
||||
: prefix === debugLevel);
|
||||
|
||||
if (!prefixMatchesDebugLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`${prefix}:`, ...logArgs);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
let capturedLogs: string[] = [];
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
let captureLogs = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function setLogCapture(value: boolean): void {
|
||||
capturedLogs = [];
|
||||
captureLogs = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function getCapturedLogs(): string[] {
|
||||
return capturedLogs;
|
||||
}
|
||||
1751
node_modules/puppeteer-core/src/common/Device.ts
generated
vendored
Normal file
1751
node_modules/puppeteer-core/src/common/Device.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
31
node_modules/puppeteer-core/src/common/DownloadBehavior.ts
generated
vendored
Normal file
31
node_modules/puppeteer-core/src/common/DownloadBehavior.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type DownloadPolicy = 'deny' | 'allow' | 'allowAndName' | 'default';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface DownloadBehavior {
|
||||
/**
|
||||
* Whether to allow all or deny all download requests, or use default behavior if
|
||||
* available.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this to `allowAndName` will name all files according to their download guids.
|
||||
*/
|
||||
policy: DownloadPolicy;
|
||||
/**
|
||||
* The default path to save downloaded files to.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this is required if behavior is set to `allow` or `allowAndName`.
|
||||
*/
|
||||
downloadPath?: string;
|
||||
}
|
||||
98
node_modules/puppeteer-core/src/common/Errors.ts
generated
vendored
Normal file
98
node_modules/puppeteer-core/src/common/Errors.ts
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2018 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* The base class for all Puppeteer-specific errors
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class PuppeteerError extends Error {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(message?: string, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get [Symbol.toStringTag](): string {
|
||||
return this.constructor.name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TimeoutError is emitted whenever certain operations are terminated due to
|
||||
* timeout.
|
||||
*
|
||||
* @remarks
|
||||
* Example operations are {@link Page.waitForSelector | page.waitForSelector} or
|
||||
* {@link PuppeteerNode.launch | puppeteer.launch}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class TimeoutError extends PuppeteerError {}
|
||||
|
||||
/**
|
||||
* TouchError is thrown when an attempt is made to move or end a touch that does
|
||||
* not exist.
|
||||
* @public
|
||||
*/
|
||||
export class TouchError extends PuppeteerError {}
|
||||
|
||||
/**
|
||||
* ProtocolError is emitted whenever there is an error from the protocol.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class ProtocolError extends PuppeteerError {
|
||||
#code?: number;
|
||||
#originalMessage = '';
|
||||
|
||||
set code(code: number | undefined) {
|
||||
this.#code = code;
|
||||
}
|
||||
/**
|
||||
* @readonly
|
||||
* @public
|
||||
*/
|
||||
get code(): number | undefined {
|
||||
return this.#code;
|
||||
}
|
||||
|
||||
set originalMessage(originalMessage: string) {
|
||||
this.#originalMessage = originalMessage;
|
||||
}
|
||||
/**
|
||||
* @readonly
|
||||
* @public
|
||||
*/
|
||||
get originalMessage(): string {
|
||||
return this.#originalMessage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puppeteer will throw this error if a method is not
|
||||
* supported by the currently used protocol
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class UnsupportedOperation extends PuppeteerError {}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class TargetCloseError extends ProtocolError {}
|
||||
|
||||
/**
|
||||
* Thrown if underlying protocol connection has been closed.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class ConnectionClosedError extends ProtocolError {}
|
||||
193
node_modules/puppeteer-core/src/common/EventEmitter.ts
generated
vendored
Normal file
193
node_modules/puppeteer-core/src/common/EventEmitter.ts
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import mitt, {type Emitter} from '../../third_party/mitt/mitt.js';
|
||||
import {disposeSymbol} from '../util/disposable.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type EventType = string | symbol;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type Handler<T = unknown> = (event: T) => void;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface CommonEventEmitter<Events extends Record<EventType, unknown>> {
|
||||
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): this;
|
||||
off<Key extends keyof Events>(
|
||||
type: Key,
|
||||
handler?: Handler<Events[Key]>,
|
||||
): this;
|
||||
emit<Key extends keyof Events>(type: Key, event: Events[Key]): boolean;
|
||||
once<Key extends keyof Events>(
|
||||
type: Key,
|
||||
handler: Handler<Events[Key]>,
|
||||
): this;
|
||||
listenerCount(event: keyof Events): number;
|
||||
|
||||
removeAllListeners(event?: keyof Events): this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type EventsWithWildcard<Events extends Record<EventType, unknown>> =
|
||||
Events & {
|
||||
'*': Events[keyof Events];
|
||||
};
|
||||
|
||||
/**
|
||||
* The EventEmitter class that many Puppeteer classes extend.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This allows you to listen to events that Puppeteer classes fire and act
|
||||
* accordingly. Therefore you'll mostly use {@link EventEmitter.on | on} and
|
||||
* {@link EventEmitter.off | off} to bind
|
||||
* and unbind to event listeners.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class EventEmitter<
|
||||
Events extends Record<EventType, unknown>,
|
||||
> implements CommonEventEmitter<EventsWithWildcard<Events>> {
|
||||
#emitter: Emitter<EventsWithWildcard<Events>> | EventEmitter<Events>;
|
||||
#handlers = new Map<keyof Events | '*', Array<Handler<any>>>();
|
||||
|
||||
/**
|
||||
* If you pass an emitter, the returned emitter will wrap the passed emitter.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
constructor(
|
||||
emitter: Emitter<EventsWithWildcard<Events>> | EventEmitter<Events> = mitt(
|
||||
new Map(),
|
||||
),
|
||||
) {
|
||||
this.#emitter = emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind an event listener to fire when an event occurs.
|
||||
* @param type - the event type you'd like to listen to. Can be a string or symbol.
|
||||
* @param handler - the function to be called when the event occurs.
|
||||
* @returns `this` to enable you to chain method calls.
|
||||
*/
|
||||
on<Key extends keyof EventsWithWildcard<Events>>(
|
||||
type: Key,
|
||||
handler: Handler<EventsWithWildcard<Events>[Key]>,
|
||||
): this {
|
||||
const handlers = this.#handlers.get(type);
|
||||
if (handlers === undefined) {
|
||||
this.#handlers.set(type, [handler]);
|
||||
} else {
|
||||
handlers.push(handler);
|
||||
}
|
||||
|
||||
this.#emitter.on(type, handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an event listener from firing.
|
||||
* @param type - the event type you'd like to stop listening to.
|
||||
* @param handler - the function that should be removed.
|
||||
* @returns `this` to enable you to chain method calls.
|
||||
*/
|
||||
off<Key extends keyof EventsWithWildcard<Events>>(
|
||||
type: Key,
|
||||
handler?: Handler<EventsWithWildcard<Events>[Key]>,
|
||||
): this {
|
||||
const handlers = this.#handlers.get(type) ?? [];
|
||||
if (handler === undefined) {
|
||||
for (const handler of handlers) {
|
||||
this.#emitter.off(type, handler);
|
||||
}
|
||||
this.#handlers.delete(type);
|
||||
return this;
|
||||
}
|
||||
const index = handlers.lastIndexOf(handler);
|
||||
if (index > -1) {
|
||||
this.#emitter.off(type, ...handlers.splice(index, 1));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event and call any associated listeners.
|
||||
*
|
||||
* @param type - the event you'd like to emit
|
||||
* @param eventData - any data you'd like to emit with the event
|
||||
* @returns `true` if there are any listeners, `false` if there are not.
|
||||
*/
|
||||
emit<Key extends keyof EventsWithWildcard<Events>>(
|
||||
type: Key,
|
||||
event: EventsWithWildcard<Events>[Key],
|
||||
): boolean {
|
||||
this.#emitter.emit(type, event);
|
||||
return this.listenerCount(type) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `on` but the listener will only be fired once and then it will be removed.
|
||||
* @param type - the event you'd like to listen to
|
||||
* @param handler - the handler function to run when the event occurs
|
||||
* @returns `this` to enable you to chain method calls.
|
||||
*/
|
||||
once<Key extends keyof EventsWithWildcard<Events>>(
|
||||
type: Key,
|
||||
handler: Handler<EventsWithWildcard<Events>[Key]>,
|
||||
): this {
|
||||
const onceHandler: Handler<EventsWithWildcard<Events>[Key]> = eventData => {
|
||||
handler(eventData);
|
||||
this.off(type, onceHandler);
|
||||
};
|
||||
|
||||
return this.on(type, onceHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of listeners for a given event.
|
||||
*
|
||||
* @param type - the event to get the listener count for
|
||||
* @returns the number of listeners bound to the given event
|
||||
*/
|
||||
listenerCount(type: keyof EventsWithWildcard<Events>): number {
|
||||
return this.#handlers.get(type)?.length || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all listeners. If given an event argument, it will remove only
|
||||
* listeners for that event.
|
||||
*
|
||||
* @param type - the event to remove listeners for.
|
||||
* @returns `this` to enable you to chain method calls.
|
||||
*/
|
||||
removeAllListeners(type?: keyof EventsWithWildcard<Events>): this {
|
||||
if (type !== undefined) {
|
||||
return this.off(type);
|
||||
}
|
||||
this[disposeSymbol]();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
[disposeSymbol](): void {
|
||||
for (const [type, handlers] of this.#handlers) {
|
||||
for (const handler of handlers) {
|
||||
this.#emitter.off(type, handler);
|
||||
}
|
||||
}
|
||||
this.#handlers.clear();
|
||||
}
|
||||
}
|
||||
87
node_modules/puppeteer-core/src/common/FileChooser.ts
generated
vendored
Normal file
87
node_modules/puppeteer-core/src/common/FileChooser.ts
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {ElementHandle} from '../api/ElementHandle.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
|
||||
/**
|
||||
* File choosers let you react to the page requesting for a file.
|
||||
*
|
||||
* @remarks
|
||||
* `FileChooser` instances are returned via the {@link Page.waitForFileChooser} method.
|
||||
*
|
||||
* In browsers, only one file chooser can be opened at a time.
|
||||
* All file choosers must be accepted or canceled. Not doing so will prevent
|
||||
* subsequent file choosers from appearing.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const [fileChooser] = await Promise.all([
|
||||
* page.waitForFileChooser(),
|
||||
* page.click('#upload-file-button'), // some button that triggers file selection
|
||||
* ]);
|
||||
* await fileChooser.accept(['/tmp/myfile.pdf']);
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class FileChooser {
|
||||
#element: ElementHandle<HTMLInputElement>;
|
||||
#multiple: boolean;
|
||||
#handled = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(element: ElementHandle<HTMLInputElement>, multiple: boolean) {
|
||||
this.#element = element;
|
||||
this.#multiple = multiple;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether file chooser allow for
|
||||
* {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-multiple | multiple}
|
||||
* file selection.
|
||||
*/
|
||||
isMultiple(): boolean {
|
||||
return this.#multiple;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept the file chooser request with the given file paths.
|
||||
*
|
||||
* @remarks This will not validate whether the file paths exists. Also, if a
|
||||
* path is relative, then it is resolved against the
|
||||
* {@link https://nodejs.org/api/process.html#process_process_cwd | current working directory}.
|
||||
* For locals script connecting to remote chrome environments, paths must be
|
||||
* absolute.
|
||||
*/
|
||||
async accept(paths: string[]): Promise<void> {
|
||||
assert(
|
||||
!this.#handled,
|
||||
'Cannot accept FileChooser which is already handled!',
|
||||
);
|
||||
this.#handled = true;
|
||||
await this.#element.uploadFile(...paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the file chooser without selecting any files.
|
||||
*/
|
||||
async cancel(): Promise<void> {
|
||||
assert(
|
||||
!this.#handled,
|
||||
'Cannot cancel FileChooser which is already handled!',
|
||||
);
|
||||
this.#handled = true;
|
||||
// XXX: These events should converted to trusted events. Perhaps do this
|
||||
// in `DOM.setFileInputFiles`?
|
||||
await this.#element.evaluate(element => {
|
||||
element.dispatchEvent(new Event('cancel', {bubbles: true}));
|
||||
});
|
||||
}
|
||||
}
|
||||
80
node_modules/puppeteer-core/src/common/GetQueryHandler.ts
generated
vendored
Normal file
80
node_modules/puppeteer-core/src/common/GetQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {ARIAQueryHandler} from './AriaQueryHandler.js';
|
||||
import {CSSQueryHandler} from './CSSQueryHandler.js';
|
||||
import {customQueryHandlers} from './CustomQueryHandler.js';
|
||||
import {PierceQueryHandler} from './PierceQueryHandler.js';
|
||||
import {PQueryHandler} from './PQueryHandler.js';
|
||||
import {parsePSelectors} from './PSelectorParser.js';
|
||||
import type {QueryHandler} from './QueryHandler.js';
|
||||
import {PollingOptions} from './QueryHandler.js';
|
||||
import {TextQueryHandler} from './TextQueryHandler.js';
|
||||
import {XPathQueryHandler} from './XPathQueryHandler.js';
|
||||
|
||||
const BUILTIN_QUERY_HANDLERS = {
|
||||
aria: ARIAQueryHandler,
|
||||
pierce: PierceQueryHandler,
|
||||
xpath: XPathQueryHandler,
|
||||
text: TextQueryHandler,
|
||||
} as const;
|
||||
|
||||
const QUERY_SEPARATORS = ['=', '/'];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function getQueryHandlerAndSelector(selector: string): {
|
||||
updatedSelector: string;
|
||||
polling: PollingOptions;
|
||||
QueryHandler: typeof QueryHandler;
|
||||
} {
|
||||
for (const handlerMap of [
|
||||
customQueryHandlers.names().map(name => {
|
||||
return [name, customQueryHandlers.get(name)!] as const;
|
||||
}),
|
||||
Object.entries(BUILTIN_QUERY_HANDLERS),
|
||||
]) {
|
||||
for (const [name, QueryHandler] of handlerMap) {
|
||||
for (const separator of QUERY_SEPARATORS) {
|
||||
const prefix = `${name}${separator}`;
|
||||
if (selector.startsWith(prefix)) {
|
||||
selector = selector.slice(prefix.length);
|
||||
return {
|
||||
updatedSelector: selector,
|
||||
polling:
|
||||
name === 'aria' ? PollingOptions.RAF : PollingOptions.MUTATION,
|
||||
QueryHandler,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
const [pSelector, isPureCSS, hasPseudoClasses, hasAria] =
|
||||
parsePSelectors(selector);
|
||||
if (isPureCSS) {
|
||||
return {
|
||||
updatedSelector: selector,
|
||||
polling: hasPseudoClasses
|
||||
? PollingOptions.RAF
|
||||
: PollingOptions.MUTATION,
|
||||
QueryHandler: CSSQueryHandler,
|
||||
};
|
||||
}
|
||||
return {
|
||||
updatedSelector: JSON.stringify(pSelector),
|
||||
polling: hasAria ? PollingOptions.RAF : PollingOptions.MUTATION,
|
||||
QueryHandler: PQueryHandler,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
updatedSelector: selector,
|
||||
polling: PollingOptions.MUTATION,
|
||||
QueryHandler: CSSQueryHandler,
|
||||
};
|
||||
}
|
||||
}
|
||||
76
node_modules/puppeteer-core/src/common/HandleIterator.ts
generated
vendored
Normal file
76
node_modules/puppeteer-core/src/common/HandleIterator.ts
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {JSHandle} from '../api/JSHandle.js';
|
||||
import {DisposableStack, disposeSymbol} from '../util/disposable.js';
|
||||
|
||||
import type {AwaitableIterable, HandleFor} from './types.js';
|
||||
|
||||
const DEFAULT_BATCH_SIZE = 20;
|
||||
|
||||
/**
|
||||
* This will transpose an iterator JSHandle into a fast, Puppeteer-side iterator
|
||||
* of JSHandles.
|
||||
*
|
||||
* @param size - The number of elements to transpose. This should be something
|
||||
* reasonable.
|
||||
*/
|
||||
async function* fastTransposeIteratorHandle<T>(
|
||||
iterator: JSHandle<AwaitableIterator<T>>,
|
||||
size: number,
|
||||
) {
|
||||
using array = await iterator.evaluateHandle(async (iterator, size) => {
|
||||
const results = [];
|
||||
while (results.length < size) {
|
||||
const result = await iterator.next();
|
||||
if (result.done) {
|
||||
break;
|
||||
}
|
||||
results.push(result.value);
|
||||
}
|
||||
return results;
|
||||
}, size);
|
||||
const properties = (await array.getProperties()) as Map<string, HandleFor<T>>;
|
||||
const handles = properties.values();
|
||||
using stack = new DisposableStack();
|
||||
stack.defer(() => {
|
||||
for (using handle of handles) {
|
||||
handle[disposeSymbol]();
|
||||
}
|
||||
});
|
||||
yield* handles;
|
||||
return properties.size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will transpose an iterator JSHandle in batches based on the default size
|
||||
* of {@link fastTransposeIteratorHandle}.
|
||||
*/
|
||||
|
||||
async function* transposeIteratorHandle<T>(
|
||||
iterator: JSHandle<AwaitableIterator<T>>,
|
||||
) {
|
||||
let size = DEFAULT_BATCH_SIZE;
|
||||
while (!(yield* fastTransposeIteratorHandle(iterator, size))) {
|
||||
size <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
type AwaitableIterator<T> = Iterator<T> | AsyncIterator<T>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export async function* transposeIterableHandle<T>(
|
||||
handle: JSHandle<AwaitableIterable<T>>,
|
||||
): AsyncIterableIterator<HandleFor<T>> {
|
||||
using generatorHandle = await handle.evaluateHandle(iterable => {
|
||||
return (async function* () {
|
||||
yield* iterable;
|
||||
})();
|
||||
});
|
||||
yield* transposeIteratorHandle(generatorHandle);
|
||||
}
|
||||
37
node_modules/puppeteer-core/src/common/LazyArg.ts
generated
vendored
Normal file
37
node_modules/puppeteer-core/src/common/LazyArg.ts
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {JSHandle} from '../api/JSHandle.js';
|
||||
import type {PuppeteerInjectedUtil} from '../injected/injected.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface PuppeteerUtilWrapper {
|
||||
puppeteerUtil: Promise<JSHandle<PuppeteerInjectedUtil>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class LazyArg<T, Context = PuppeteerUtilWrapper> {
|
||||
static create = <T>(
|
||||
get: (context: PuppeteerUtilWrapper) => Promise<T> | T,
|
||||
): T => {
|
||||
// We don't want to introduce LazyArg to the type system, otherwise we would
|
||||
// have to make it public.
|
||||
return new LazyArg(get) as unknown as T;
|
||||
};
|
||||
|
||||
#get: (context: Context) => Promise<T> | T;
|
||||
private constructor(get: (context: Context) => Promise<T> | T) {
|
||||
this.#get = get;
|
||||
}
|
||||
|
||||
async get(context: Context): Promise<T> {
|
||||
return await this.#get(context);
|
||||
}
|
||||
}
|
||||
38
node_modules/puppeteer-core/src/common/NetworkManagerEvents.ts
generated
vendored
Normal file
38
node_modules/puppeteer-core/src/common/NetworkManagerEvents.ts
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {HTTPRequest} from '../api/HTTPRequest.js';
|
||||
import type {HTTPResponse} from '../api/HTTPResponse.js';
|
||||
|
||||
import type {EventType} from './EventEmitter.js';
|
||||
|
||||
/**
|
||||
* We use symbols to prevent any external parties listening to these events.
|
||||
* They are internal to Puppeteer.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
export namespace NetworkManagerEvent {
|
||||
export const Request = Symbol('NetworkManager.Request');
|
||||
export const RequestServedFromCache = Symbol(
|
||||
'NetworkManager.RequestServedFromCache',
|
||||
);
|
||||
export const Response = Symbol('NetworkManager.Response');
|
||||
export const RequestFailed = Symbol('NetworkManager.RequestFailed');
|
||||
export const RequestFinished = Symbol('NetworkManager.RequestFinished');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface NetworkManagerEvents extends Record<EventType, unknown> {
|
||||
[NetworkManagerEvent.Request]: HTTPRequest;
|
||||
[NetworkManagerEvent.RequestServedFromCache]: HTTPRequest;
|
||||
[NetworkManagerEvent.Response]: HTTPResponse;
|
||||
[NetworkManagerEvent.RequestFailed]: HTTPRequest;
|
||||
[NetworkManagerEvent.RequestFinished]: HTTPRequest;
|
||||
}
|
||||
274
node_modules/puppeteer-core/src/common/PDFOptions.ts
generated
vendored
Normal file
274
node_modules/puppeteer-core/src/common/PDFOptions.ts
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface PDFMargin {
|
||||
top?: string | number;
|
||||
bottom?: string | number;
|
||||
left?: string | number;
|
||||
right?: string | number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type LowerCasePaperFormat =
|
||||
| 'letter'
|
||||
| 'legal'
|
||||
| 'tabloid'
|
||||
| 'ledger'
|
||||
| 'a0'
|
||||
| 'a1'
|
||||
| 'a2'
|
||||
| 'a3'
|
||||
| 'a4'
|
||||
| 'a5'
|
||||
| 'a6';
|
||||
|
||||
/**
|
||||
* All the valid paper format types when printing a PDF.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* The sizes of each format are as follows:
|
||||
*
|
||||
* - `Letter`: 8.5in x 11in / 21.59cm x 27.94cm
|
||||
*
|
||||
* - `Legal`: 8.5in x 14in / 21.59cm x 35.56cm
|
||||
*
|
||||
* - `Tabloid`: 11in x 17in / 27.94cm x 43.18cm
|
||||
*
|
||||
* - `Ledger`: 17in x 11in / 43.18cm x 27.94cm
|
||||
*
|
||||
* - `A0`: 33.1102in x 46.811in / 84.1cm x 118.9cm
|
||||
*
|
||||
* - `A1`: 23.3858in x 33.1102in / 59.4cm x 84.1cm
|
||||
*
|
||||
* - `A2`: 16.5354in x 23.3858in / 42cm x 59.4cm
|
||||
*
|
||||
* - `A3`: 11.6929in x 16.5354in / 29.7cm x 42cm
|
||||
*
|
||||
* - `A4`: 8.2677in x 11.6929in / 21cm x 29.7cm
|
||||
*
|
||||
* - `A5`: 5.8268in x 8.2677in / 14.8cm x 21cm
|
||||
*
|
||||
* - `A6`: 4.1339in x 5.8268in / 10.5cm x 14.8cm
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type PaperFormat =
|
||||
| Uppercase<LowerCasePaperFormat>
|
||||
| Capitalize<LowerCasePaperFormat>
|
||||
| LowerCasePaperFormat;
|
||||
|
||||
/**
|
||||
* Valid options to configure PDF generation via {@link Page.pdf}.
|
||||
* @public
|
||||
*/
|
||||
export interface PDFOptions {
|
||||
/**
|
||||
* Scales the rendering of the web page. Amount must be between `0.1` and `2`.
|
||||
* @defaultValue `1`
|
||||
*/
|
||||
scale?: number;
|
||||
/**
|
||||
* Whether to show the header and footer.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
displayHeaderFooter?: boolean;
|
||||
/**
|
||||
* HTML template for the print header. Should be valid HTML with the following
|
||||
* classes used to inject values into them:
|
||||
*
|
||||
* - `date` formatted print date
|
||||
*
|
||||
* - `title` document title
|
||||
*
|
||||
* - `url` document location
|
||||
*
|
||||
* - `pageNumber` current page number
|
||||
*
|
||||
* - `totalPages` total pages in the document
|
||||
*/
|
||||
headerTemplate?: string;
|
||||
/**
|
||||
* HTML template for the print footer. Has the same constraints and support
|
||||
* for special classes as {@link PDFOptions.headerTemplate}.
|
||||
*/
|
||||
footerTemplate?: string;
|
||||
/**
|
||||
* Set to `true` to print background graphics.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
printBackground?: boolean;
|
||||
/**
|
||||
* Whether to print in landscape orientation.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
landscape?: boolean;
|
||||
/**
|
||||
* Paper ranges to print, e.g. `1-5, 8, 11-13`.
|
||||
* @defaultValue The empty string, which means all pages are printed.
|
||||
*/
|
||||
pageRanges?: string;
|
||||
/**
|
||||
* @remarks
|
||||
* If set, this takes priority over the `width` and `height` options.
|
||||
* @defaultValue `letter`.
|
||||
*/
|
||||
format?: PaperFormat;
|
||||
/**
|
||||
* Sets the width of paper. You can pass in a number or a string with a unit.
|
||||
*/
|
||||
width?: string | number;
|
||||
/**
|
||||
* Sets the height of paper. You can pass in a number or a string with a unit.
|
||||
*/
|
||||
height?: string | number;
|
||||
/**
|
||||
* Give any CSS `@page` size declared in the page priority over what is
|
||||
* declared in the `width` or `height` or `format` option.
|
||||
* @defaultValue `false`, which will scale the content to fit the paper size.
|
||||
*/
|
||||
preferCSSPageSize?: boolean;
|
||||
/**
|
||||
* Set the PDF margins.
|
||||
* @defaultValue `undefined` no margins are set.
|
||||
*/
|
||||
margin?: PDFMargin;
|
||||
/**
|
||||
* The path to save the file to.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* If the path is relative, it's resolved relative to the current working directory.
|
||||
*
|
||||
* @defaultValue `undefined`, which means the PDF will not be written to disk.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* Hides default white background and allows generating pdfs with transparency.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
omitBackground?: boolean;
|
||||
/**
|
||||
* Generate tagged (accessible) PDF.
|
||||
*
|
||||
* @defaultValue `true`
|
||||
* @experimental
|
||||
*/
|
||||
tagged?: boolean;
|
||||
/**
|
||||
* Generate document outline.
|
||||
*
|
||||
* @defaultValue `false`
|
||||
* @experimental
|
||||
*/
|
||||
outline?: boolean;
|
||||
/**
|
||||
* Timeout in milliseconds. Pass `0` to disable timeout.
|
||||
*
|
||||
* The default value can be changed by using {@link Page.setDefaultTimeout}
|
||||
*
|
||||
* @defaultValue `30_000`
|
||||
*/
|
||||
timeout?: number;
|
||||
/**
|
||||
* If true, waits for `document.fonts.ready` to resolve. This might require
|
||||
* activating the page using {@link Page.bringToFront} if the page is in the
|
||||
* background.
|
||||
*
|
||||
* @defaultValue `true`
|
||||
*/
|
||||
waitForFonts?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface PaperFormatDimensions {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface ParsedPDFOptionsInterface {
|
||||
width: number;
|
||||
height: number;
|
||||
margin: {
|
||||
top: number;
|
||||
bottom: number;
|
||||
left: number;
|
||||
right: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type ParsedPDFOptions = Required<
|
||||
Omit<PDFOptions, 'path' | 'format' | 'timeout'> & ParsedPDFOptionsInterface
|
||||
>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @remarks All A series paper format sizes in inches are calculated from centimeters
|
||||
* rounded mathematically to four decimal places.
|
||||
*/
|
||||
export const paperFormats: Record<
|
||||
LowerCasePaperFormat,
|
||||
Record<'cm' | 'in', PaperFormatDimensions>
|
||||
> = {
|
||||
letter: {
|
||||
cm: {width: 21.59, height: 27.94},
|
||||
in: {width: 8.5, height: 11},
|
||||
},
|
||||
legal: {
|
||||
cm: {width: 21.59, height: 35.56},
|
||||
in: {width: 8.5, height: 14},
|
||||
},
|
||||
tabloid: {
|
||||
cm: {width: 27.94, height: 43.18},
|
||||
in: {width: 11, height: 17},
|
||||
},
|
||||
ledger: {
|
||||
cm: {width: 43.18, height: 27.94},
|
||||
in: {width: 17, height: 11},
|
||||
},
|
||||
a0: {
|
||||
cm: {width: 84.1, height: 118.9},
|
||||
in: {width: 33.1102, height: 46.811},
|
||||
},
|
||||
a1: {
|
||||
cm: {width: 59.4, height: 84.1},
|
||||
in: {width: 23.3858, height: 33.1102},
|
||||
},
|
||||
a2: {
|
||||
cm: {width: 42, height: 59.4},
|
||||
in: {width: 16.5354, height: 23.3858},
|
||||
},
|
||||
a3: {
|
||||
cm: {width: 29.7, height: 42},
|
||||
in: {width: 11.6929, height: 16.5354},
|
||||
},
|
||||
a4: {
|
||||
cm: {width: 21, height: 29.7},
|
||||
in: {width: 8.2677, height: 11.6929},
|
||||
},
|
||||
a5: {
|
||||
cm: {width: 14.8, height: 21},
|
||||
in: {width: 5.8268, height: 8.2677},
|
||||
},
|
||||
a6: {
|
||||
cm: {width: 10.5, height: 14.8},
|
||||
in: {width: 4.1339, height: 5.8268},
|
||||
},
|
||||
} as const;
|
||||
31
node_modules/puppeteer-core/src/common/PQueryHandler.ts
generated
vendored
Normal file
31
node_modules/puppeteer-core/src/common/PQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
QueryHandler,
|
||||
type QuerySelector,
|
||||
type QuerySelectorAll,
|
||||
} from './QueryHandler.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class PQueryHandler extends QueryHandler {
|
||||
static override querySelectorAll: QuerySelectorAll = (
|
||||
element,
|
||||
selector,
|
||||
{pQuerySelectorAll},
|
||||
) => {
|
||||
return pQuerySelectorAll(element, selector);
|
||||
};
|
||||
static override querySelector: QuerySelector = (
|
||||
element,
|
||||
selector,
|
||||
{pQuerySelector},
|
||||
) => {
|
||||
return pQuerySelector(element, selector);
|
||||
};
|
||||
}
|
||||
121
node_modules/puppeteer-core/src/common/PSelectorParser.ts
generated
vendored
Normal file
121
node_modules/puppeteer-core/src/common/PSelectorParser.ts
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
type Token,
|
||||
tokenize,
|
||||
TOKENS,
|
||||
stringify,
|
||||
} from '../../third_party/parsel-js/parsel-js.js';
|
||||
import type {
|
||||
ComplexPSelector,
|
||||
ComplexPSelectorList,
|
||||
CompoundPSelector,
|
||||
} from '../injected/PQuerySelector.js';
|
||||
import {PCombinator} from '../injected/PQuerySelector.js';
|
||||
|
||||
TOKENS['nesting'] = /&/g;
|
||||
TOKENS['combinator'] = /\s*(>>>>?|[\s>+~])\s*/g;
|
||||
|
||||
const ESCAPE_REGEXP = /\\[\s\S]/g;
|
||||
const unquote = (text: string): string => {
|
||||
if (text.length <= 1) {
|
||||
return text;
|
||||
}
|
||||
if ((text[0] === '"' || text[0] === "'") && text.endsWith(text[0])) {
|
||||
text = text.slice(1, -1);
|
||||
}
|
||||
return text.replace(ESCAPE_REGEXP, match => {
|
||||
return match[1] as string;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function parsePSelectors(
|
||||
selector: string,
|
||||
): [
|
||||
selector: ComplexPSelectorList,
|
||||
isPureCSS: boolean,
|
||||
hasPseudoClasses: boolean,
|
||||
hasAria: boolean,
|
||||
] {
|
||||
let isPureCSS = true;
|
||||
let hasAria = false;
|
||||
let hasPseudoClasses = false;
|
||||
const tokens = tokenize(selector);
|
||||
if (tokens.length === 0) {
|
||||
return [[], isPureCSS, hasPseudoClasses, false];
|
||||
}
|
||||
let compoundSelector: CompoundPSelector = [];
|
||||
let complexSelector: ComplexPSelector = [compoundSelector];
|
||||
const selectors: ComplexPSelectorList = [complexSelector];
|
||||
const storage: Token[] = [];
|
||||
for (const token of tokens) {
|
||||
switch (token.type) {
|
||||
case 'combinator':
|
||||
switch (token.content) {
|
||||
case PCombinator.Descendent:
|
||||
isPureCSS = false;
|
||||
if (storage.length) {
|
||||
compoundSelector.push(stringify(storage));
|
||||
storage.splice(0);
|
||||
}
|
||||
compoundSelector = [];
|
||||
complexSelector.push(PCombinator.Descendent);
|
||||
complexSelector.push(compoundSelector);
|
||||
continue;
|
||||
case PCombinator.Child:
|
||||
isPureCSS = false;
|
||||
if (storage.length) {
|
||||
compoundSelector.push(stringify(storage));
|
||||
storage.splice(0);
|
||||
}
|
||||
compoundSelector = [];
|
||||
complexSelector.push(PCombinator.Child);
|
||||
complexSelector.push(compoundSelector);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 'pseudo-element':
|
||||
if (!token.name.startsWith('-p-')) {
|
||||
break;
|
||||
}
|
||||
isPureCSS = false;
|
||||
if (storage.length) {
|
||||
compoundSelector.push(stringify(storage));
|
||||
storage.splice(0);
|
||||
}
|
||||
const name = token.name.slice(3);
|
||||
if (name === 'aria') {
|
||||
hasAria = true;
|
||||
}
|
||||
compoundSelector.push({
|
||||
name,
|
||||
value: unquote(token.argument ?? ''),
|
||||
});
|
||||
continue;
|
||||
case 'pseudo-class':
|
||||
hasPseudoClasses = true;
|
||||
break;
|
||||
case 'comma':
|
||||
if (storage.length) {
|
||||
compoundSelector.push(stringify(storage));
|
||||
storage.splice(0);
|
||||
}
|
||||
compoundSelector = [];
|
||||
complexSelector = [compoundSelector];
|
||||
selectors.push(complexSelector);
|
||||
continue;
|
||||
}
|
||||
storage.push(token);
|
||||
}
|
||||
if (storage.length) {
|
||||
compoundSelector.push(stringify(storage));
|
||||
}
|
||||
return [selectors, isPureCSS, hasPseudoClasses, hasAria];
|
||||
}
|
||||
29
node_modules/puppeteer-core/src/common/PierceQueryHandler.ts
generated
vendored
Normal file
29
node_modules/puppeteer-core/src/common/PierceQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {PuppeteerInjectedUtil} from '../injected/injected.js';
|
||||
|
||||
import {QueryHandler} from './QueryHandler.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class PierceQueryHandler extends QueryHandler {
|
||||
static override querySelector = (
|
||||
element: Node,
|
||||
selector: string,
|
||||
{pierceQuerySelector}: PuppeteerInjectedUtil,
|
||||
): Node | null => {
|
||||
return pierceQuerySelector(element, selector);
|
||||
};
|
||||
static override querySelectorAll = (
|
||||
element: Node,
|
||||
selector: string,
|
||||
{pierceQuerySelectorAll}: PuppeteerInjectedUtil,
|
||||
): Iterable<Node> => {
|
||||
return pierceQuerySelectorAll(element, selector);
|
||||
};
|
||||
}
|
||||
125
node_modules/puppeteer-core/src/common/Puppeteer.ts
generated
vendored
Normal file
125
node_modules/puppeteer-core/src/common/Puppeteer.ts
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {Browser} from '../api/Browser.js';
|
||||
|
||||
import {_connectToBrowser} from './BrowserConnector.js';
|
||||
import type {ConnectOptions} from './ConnectOptions.js';
|
||||
import {
|
||||
type CustomQueryHandler,
|
||||
customQueryHandlers,
|
||||
} from './CustomQueryHandler.js';
|
||||
|
||||
/**
|
||||
* Settings that are common to the Puppeteer class, regardless of environment.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export interface CommonPuppeteerSettings {
|
||||
isPuppeteerCore: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main Puppeteer class.
|
||||
*
|
||||
* IMPORTANT: if you are using Puppeteer in a Node environment, you will get an
|
||||
* instance of {@link PuppeteerNode} when you import or require `puppeteer`.
|
||||
* That class extends `Puppeteer`, so has all the methods documented below as
|
||||
* well as all that are defined on {@link PuppeteerNode}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class Puppeteer {
|
||||
/**
|
||||
* Operations for {@link CustomQueryHandler | custom query handlers}. See
|
||||
* {@link CustomQueryHandlerRegistry}.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
static customQueryHandlers = customQueryHandlers;
|
||||
|
||||
/**
|
||||
* Registers a {@link CustomQueryHandler | custom query handler}.
|
||||
*
|
||||
* @remarks
|
||||
* After registration, the handler can be used everywhere where a selector is
|
||||
* expected by prepending the selection string with `<name>/`. The name is only
|
||||
* allowed to consist of lower- and upper case latin letters.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```
|
||||
* import {Puppeteer}, puppeteer from 'puppeteer';
|
||||
*
|
||||
* Puppeteer.registerCustomQueryHandler('text', { … });
|
||||
* const aHandle = await page.$('text/…');
|
||||
* ```
|
||||
*
|
||||
* @param name - The name that the custom query handler will be registered
|
||||
* under.
|
||||
* @param queryHandler - The {@link CustomQueryHandler | custom query handler}
|
||||
* to register.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
static registerCustomQueryHandler(
|
||||
name: string,
|
||||
queryHandler: CustomQueryHandler,
|
||||
): void {
|
||||
return this.customQueryHandlers.register(name, queryHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a custom query handler for a given name.
|
||||
*/
|
||||
static unregisterCustomQueryHandler(name: string): void {
|
||||
return this.customQueryHandlers.unregister(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all custom query handlers.
|
||||
*/
|
||||
static customQueryHandlerNames(): string[] {
|
||||
return this.customQueryHandlers.names();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters all custom query handlers.
|
||||
*/
|
||||
static clearCustomQueryHandlers(): void {
|
||||
return this.customQueryHandlers.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_isPuppeteerCore: boolean;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected _changedBrowsers = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(settings: CommonPuppeteerSettings) {
|
||||
this._isPuppeteerCore = settings.isPuppeteerCore;
|
||||
|
||||
this.connect = this.connect.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method attaches Puppeteer to an existing browser instance.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* @param options - Set of configurable options to set on the browser.
|
||||
* @returns Promise which resolves to browser instance.
|
||||
*/
|
||||
connect(options: ConnectOptions): Promise<Browser> {
|
||||
return _connectToBrowser(options);
|
||||
}
|
||||
}
|
||||
220
node_modules/puppeteer-core/src/common/QueryHandler.ts
generated
vendored
Normal file
220
node_modules/puppeteer-core/src/common/QueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {ElementHandle} from '../api/ElementHandle.js';
|
||||
import {_isElementHandle} from '../api/ElementHandleSymbol.js';
|
||||
import type {Frame} from '../api/Frame.js';
|
||||
import type {WaitForSelectorOptions} from '../api/Page.js';
|
||||
import type {PuppeteerInjectedUtil} from '../injected/injected.js';
|
||||
import {isErrorLike} from '../util/ErrorLike.js';
|
||||
import {interpolateFunction, stringifyFunction} from '../util/Function.js';
|
||||
|
||||
import {TimeoutError} from './Errors.js';
|
||||
import {transposeIterableHandle} from './HandleIterator.js';
|
||||
import {LazyArg} from './LazyArg.js';
|
||||
import type {Awaitable, AwaitableIterable} from './types.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type QuerySelectorAll = (
|
||||
node: Node,
|
||||
selector: string,
|
||||
PuppeteerUtil: PuppeteerInjectedUtil,
|
||||
) => AwaitableIterable<Node>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type QuerySelector = (
|
||||
node: Node,
|
||||
selector: string,
|
||||
PuppeteerUtil: PuppeteerInjectedUtil,
|
||||
) => Awaitable<Node | null>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const enum PollingOptions {
|
||||
RAF = 'raf',
|
||||
MUTATION = 'mutation',
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class QueryHandler {
|
||||
// Either one of these may be implemented, but at least one must be.
|
||||
static querySelectorAll?: QuerySelectorAll;
|
||||
static querySelector?: QuerySelector;
|
||||
|
||||
static get _querySelector(): QuerySelector {
|
||||
if (this.querySelector) {
|
||||
return this.querySelector;
|
||||
}
|
||||
if (!this.querySelectorAll) {
|
||||
throw new Error('Cannot create default `querySelector`.');
|
||||
}
|
||||
|
||||
return (this.querySelector = interpolateFunction(
|
||||
async (node, selector, PuppeteerUtil) => {
|
||||
const querySelectorAll: QuerySelectorAll =
|
||||
PLACEHOLDER('querySelectorAll');
|
||||
const results = querySelectorAll(node, selector, PuppeteerUtil);
|
||||
for await (const result of results) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
{
|
||||
querySelectorAll: stringifyFunction(this.querySelectorAll),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
static get _querySelectorAll(): QuerySelectorAll {
|
||||
if (this.querySelectorAll) {
|
||||
return this.querySelectorAll;
|
||||
}
|
||||
if (!this.querySelector) {
|
||||
throw new Error('Cannot create default `querySelectorAll`.');
|
||||
}
|
||||
|
||||
return (this.querySelectorAll = interpolateFunction(
|
||||
async function* (node, selector, PuppeteerUtil) {
|
||||
const querySelector: QuerySelector = PLACEHOLDER('querySelector');
|
||||
const result = await querySelector(node, selector, PuppeteerUtil);
|
||||
if (result) {
|
||||
yield result;
|
||||
}
|
||||
},
|
||||
{
|
||||
querySelector: stringifyFunction(this.querySelector),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for multiple nodes given a selector and {@link ElementHandle}.
|
||||
*
|
||||
* Akin to {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll | Document.querySelectorAll()}.
|
||||
*/
|
||||
static async *queryAll(
|
||||
element: ElementHandle<Node>,
|
||||
selector: string,
|
||||
): AwaitableIterable<ElementHandle<Node>> {
|
||||
using handle = await element.evaluateHandle(
|
||||
this._querySelectorAll,
|
||||
selector,
|
||||
LazyArg.create(context => {
|
||||
return context.puppeteerUtil;
|
||||
}),
|
||||
);
|
||||
yield* transposeIterableHandle(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for a single node given a selector and {@link ElementHandle}.
|
||||
*
|
||||
* Akin to {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector}.
|
||||
*/
|
||||
static async queryOne(
|
||||
element: ElementHandle<Node>,
|
||||
selector: string,
|
||||
): Promise<ElementHandle<Node> | null> {
|
||||
using result = await element.evaluateHandle(
|
||||
this._querySelector,
|
||||
selector,
|
||||
LazyArg.create(context => {
|
||||
return context.puppeteerUtil;
|
||||
}),
|
||||
);
|
||||
if (!(_isElementHandle in result)) {
|
||||
return null;
|
||||
}
|
||||
return result.move();
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until a single node appears for a given selector and
|
||||
* {@link ElementHandle}.
|
||||
*
|
||||
* This will always query the handle in the Puppeteer world and migrate the
|
||||
* result to the main world.
|
||||
*/
|
||||
static async waitFor(
|
||||
elementOrFrame: ElementHandle<Node> | Frame,
|
||||
selector: string,
|
||||
options: WaitForSelectorOptions & {
|
||||
polling?: PollingOptions;
|
||||
},
|
||||
): Promise<ElementHandle<Node> | null> {
|
||||
let frame!: Frame;
|
||||
using element = await (async () => {
|
||||
if (!(_isElementHandle in elementOrFrame)) {
|
||||
frame = elementOrFrame;
|
||||
return;
|
||||
}
|
||||
frame = elementOrFrame.frame;
|
||||
return await frame.isolatedRealm().adoptHandle(elementOrFrame);
|
||||
})();
|
||||
|
||||
const {visible = false, hidden = false, timeout, signal} = options;
|
||||
const polling = visible || hidden ? PollingOptions.RAF : options.polling;
|
||||
|
||||
try {
|
||||
signal?.throwIfAborted();
|
||||
|
||||
using handle = await frame.isolatedRealm().waitForFunction(
|
||||
async (PuppeteerUtil, query, selector, root, visible) => {
|
||||
const querySelector = PuppeteerUtil.createFunction(
|
||||
query,
|
||||
) as QuerySelector;
|
||||
const node = await querySelector(
|
||||
root ?? document,
|
||||
selector,
|
||||
PuppeteerUtil,
|
||||
);
|
||||
return PuppeteerUtil.checkVisibility(node, visible);
|
||||
},
|
||||
{
|
||||
polling,
|
||||
root: element,
|
||||
timeout,
|
||||
signal,
|
||||
},
|
||||
LazyArg.create(context => {
|
||||
return context.puppeteerUtil;
|
||||
}),
|
||||
stringifyFunction(this._querySelector),
|
||||
selector,
|
||||
element,
|
||||
visible ? true : hidden ? false : undefined,
|
||||
);
|
||||
|
||||
if (signal?.aborted) {
|
||||
throw signal.reason;
|
||||
}
|
||||
|
||||
if (!(_isElementHandle in handle)) {
|
||||
return null;
|
||||
}
|
||||
return await frame.mainRealm().transferHandle(handle);
|
||||
} catch (error) {
|
||||
if (!isErrorLike(error)) {
|
||||
throw error;
|
||||
}
|
||||
if (error.name === 'AbortError') {
|
||||
throw error;
|
||||
}
|
||||
const waitForSelectorError = new (
|
||||
error instanceof TimeoutError ? TimeoutError : Error
|
||||
)(`Waiting for selector \`${selector}\` failed`);
|
||||
waitForSelectorError.cause = error;
|
||||
throw waitForSelectorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
node_modules/puppeteer-core/src/common/ScriptInjector.ts
generated
vendored
Normal file
57
node_modules/puppeteer-core/src/common/ScriptInjector.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2024 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import {source as injectedSource} from '../generated/injected.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class ScriptInjector {
|
||||
#updated = false;
|
||||
#amendments = new Set<string>();
|
||||
|
||||
// Appends a statement of the form `(PuppeteerUtil) => {...}`.
|
||||
append(statement: string): void {
|
||||
this.#update(() => {
|
||||
this.#amendments.add(statement);
|
||||
});
|
||||
}
|
||||
|
||||
pop(statement: string): void {
|
||||
this.#update(() => {
|
||||
this.#amendments.delete(statement);
|
||||
});
|
||||
}
|
||||
|
||||
inject(inject: (script: string) => void, force = false): void {
|
||||
if (this.#updated || force) {
|
||||
inject(this.#get());
|
||||
}
|
||||
this.#updated = false;
|
||||
}
|
||||
|
||||
#update(callback: () => void): void {
|
||||
callback();
|
||||
this.#updated = true;
|
||||
}
|
||||
|
||||
#get(): string {
|
||||
return `(() => {
|
||||
const module = {};
|
||||
${injectedSource}
|
||||
${[...this.#amendments]
|
||||
.map(statement => {
|
||||
return `(${statement})(module.exports.default);`;
|
||||
})
|
||||
.join('')}
|
||||
return module.exports.default;
|
||||
})()`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const scriptInjector = new ScriptInjector();
|
||||
78
node_modules/puppeteer-core/src/common/SecurityDetails.ts
generated
vendored
Normal file
78
node_modules/puppeteer-core/src/common/SecurityDetails.ts
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {Protocol} from 'devtools-protocol';
|
||||
|
||||
/**
|
||||
* The SecurityDetails class represents the security details of a
|
||||
* response that was received over a secure connection.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class SecurityDetails {
|
||||
#subjectName: string;
|
||||
#issuer: string;
|
||||
#validFrom: number;
|
||||
#validTo: number;
|
||||
#protocol: string;
|
||||
#sanList: string[];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(securityPayload: Protocol.Network.SecurityDetails) {
|
||||
this.#subjectName = securityPayload.subjectName;
|
||||
this.#issuer = securityPayload.issuer;
|
||||
this.#validFrom = securityPayload.validFrom;
|
||||
this.#validTo = securityPayload.validTo;
|
||||
this.#protocol = securityPayload.protocol;
|
||||
this.#sanList = securityPayload.sanList;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the issuer of the certificate.
|
||||
*/
|
||||
issuer(): string {
|
||||
return this.#issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link https://en.wikipedia.org/wiki/Unix_time | Unix timestamp}
|
||||
* marking the start of the certificate's validity.
|
||||
*/
|
||||
validFrom(): number {
|
||||
return this.#validFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link https://en.wikipedia.org/wiki/Unix_time | Unix timestamp}
|
||||
* marking the end of the certificate's validity.
|
||||
*/
|
||||
validTo(): number {
|
||||
return this.#validTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* The security protocol being used, e.g. "TLS 1.2".
|
||||
*/
|
||||
protocol(): string {
|
||||
return this.#protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the subject to which the certificate was issued.
|
||||
*/
|
||||
subjectName(): string {
|
||||
return this.#subjectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of {@link https://en.wikipedia.org/wiki/Subject_Alternative_Name | subject alternative names (SANs)} of the certificate.
|
||||
*/
|
||||
subjectAlternativeNames(): string[] {
|
||||
return this.#sanList;
|
||||
}
|
||||
}
|
||||
12
node_modules/puppeteer-core/src/common/SupportedBrowser.ts
generated
vendored
Normal file
12
node_modules/puppeteer-core/src/common/SupportedBrowser.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Browsers supported by Puppeteer.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type SupportedBrowser = 'chrome' | 'firefox';
|
||||
29
node_modules/puppeteer-core/src/common/TaskQueue.ts
generated
vendored
Normal file
29
node_modules/puppeteer-core/src/common/TaskQueue.ts
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class TaskQueue {
|
||||
#chain: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
this.#chain = Promise.resolve();
|
||||
}
|
||||
|
||||
postTask<T>(task: () => Promise<T>): Promise<T> {
|
||||
const result = this.#chain.then(task);
|
||||
this.#chain = result.then(
|
||||
() => {
|
||||
return undefined;
|
||||
},
|
||||
() => {
|
||||
return undefined;
|
||||
},
|
||||
);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
20
node_modules/puppeteer-core/src/common/TextQueryHandler.ts
generated
vendored
Normal file
20
node_modules/puppeteer-core/src/common/TextQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {QueryHandler, type QuerySelectorAll} from './QueryHandler.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class TextQueryHandler extends QueryHandler {
|
||||
static override querySelectorAll: QuerySelectorAll = (
|
||||
element,
|
||||
selector,
|
||||
{textQuerySelectorAll},
|
||||
) => {
|
||||
return textQuerySelectorAll(element, selector);
|
||||
};
|
||||
}
|
||||
45
node_modules/puppeteer-core/src/common/TimeoutSettings.ts
generated
vendored
Normal file
45
node_modules/puppeteer-core/src/common/TimeoutSettings.ts
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
const DEFAULT_TIMEOUT = 30000;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class TimeoutSettings {
|
||||
#defaultTimeout: number | null;
|
||||
#defaultNavigationTimeout: number | null;
|
||||
|
||||
constructor() {
|
||||
this.#defaultTimeout = null;
|
||||
this.#defaultNavigationTimeout = null;
|
||||
}
|
||||
|
||||
setDefaultTimeout(timeout: number): void {
|
||||
this.#defaultTimeout = timeout;
|
||||
}
|
||||
|
||||
setDefaultNavigationTimeout(timeout: number): void {
|
||||
this.#defaultNavigationTimeout = timeout;
|
||||
}
|
||||
|
||||
navigationTimeout(): number {
|
||||
if (this.#defaultNavigationTimeout !== null) {
|
||||
return this.#defaultNavigationTimeout;
|
||||
}
|
||||
if (this.#defaultTimeout !== null) {
|
||||
return this.#defaultTimeout;
|
||||
}
|
||||
return DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
timeout(): number {
|
||||
if (this.#defaultTimeout !== null) {
|
||||
return this.#defaultTimeout;
|
||||
}
|
||||
return DEFAULT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
671
node_modules/puppeteer-core/src/common/USKeyboardLayout.ts
generated
vendored
Normal file
671
node_modules/puppeteer-core/src/common/USKeyboardLayout.ts
generated
vendored
Normal file
@@ -0,0 +1,671 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface KeyDefinition {
|
||||
keyCode?: number;
|
||||
shiftKeyCode?: number;
|
||||
key?: string;
|
||||
shiftKey?: string;
|
||||
code?: string;
|
||||
text?: string;
|
||||
shiftText?: string;
|
||||
location?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* All the valid keys that can be passed to functions that take user input, such
|
||||
* as {@link Keyboard.press | keyboard.press }
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type KeyInput =
|
||||
| '0'
|
||||
| '1'
|
||||
| '2'
|
||||
| '3'
|
||||
| '4'
|
||||
| '5'
|
||||
| '6'
|
||||
| '7'
|
||||
| '8'
|
||||
| '9'
|
||||
| 'Power'
|
||||
| 'Eject'
|
||||
| 'Abort'
|
||||
| 'Help'
|
||||
| 'Backspace'
|
||||
| 'Tab'
|
||||
| 'Numpad5'
|
||||
| 'NumpadEnter'
|
||||
| 'Enter'
|
||||
| '\r'
|
||||
| '\n'
|
||||
| 'ShiftLeft'
|
||||
| 'ShiftRight'
|
||||
| 'ControlLeft'
|
||||
| 'ControlRight'
|
||||
| 'AltLeft'
|
||||
| 'AltRight'
|
||||
| 'Pause'
|
||||
| 'CapsLock'
|
||||
| 'Escape'
|
||||
| 'Convert'
|
||||
| 'NonConvert'
|
||||
| 'Space'
|
||||
| 'Numpad9'
|
||||
| 'PageUp'
|
||||
| 'Numpad3'
|
||||
| 'PageDown'
|
||||
| 'End'
|
||||
| 'Numpad1'
|
||||
| 'Home'
|
||||
| 'Numpad7'
|
||||
| 'ArrowLeft'
|
||||
| 'Numpad4'
|
||||
| 'Numpad8'
|
||||
| 'ArrowUp'
|
||||
| 'ArrowRight'
|
||||
| 'Numpad6'
|
||||
| 'Numpad2'
|
||||
| 'ArrowDown'
|
||||
| 'Select'
|
||||
| 'Open'
|
||||
| 'PrintScreen'
|
||||
| 'Insert'
|
||||
| 'Numpad0'
|
||||
| 'Delete'
|
||||
| 'NumpadDecimal'
|
||||
| 'Digit0'
|
||||
| 'Digit1'
|
||||
| 'Digit2'
|
||||
| 'Digit3'
|
||||
| 'Digit4'
|
||||
| 'Digit5'
|
||||
| 'Digit6'
|
||||
| 'Digit7'
|
||||
| 'Digit8'
|
||||
| 'Digit9'
|
||||
| 'KeyA'
|
||||
| 'KeyB'
|
||||
| 'KeyC'
|
||||
| 'KeyD'
|
||||
| 'KeyE'
|
||||
| 'KeyF'
|
||||
| 'KeyG'
|
||||
| 'KeyH'
|
||||
| 'KeyI'
|
||||
| 'KeyJ'
|
||||
| 'KeyK'
|
||||
| 'KeyL'
|
||||
| 'KeyM'
|
||||
| 'KeyN'
|
||||
| 'KeyO'
|
||||
| 'KeyP'
|
||||
| 'KeyQ'
|
||||
| 'KeyR'
|
||||
| 'KeyS'
|
||||
| 'KeyT'
|
||||
| 'KeyU'
|
||||
| 'KeyV'
|
||||
| 'KeyW'
|
||||
| 'KeyX'
|
||||
| 'KeyY'
|
||||
| 'KeyZ'
|
||||
| 'MetaLeft'
|
||||
| 'MetaRight'
|
||||
| 'ContextMenu'
|
||||
| 'NumpadMultiply'
|
||||
| 'NumpadAdd'
|
||||
| 'NumpadSubtract'
|
||||
| 'NumpadDivide'
|
||||
| 'F1'
|
||||
| 'F2'
|
||||
| 'F3'
|
||||
| 'F4'
|
||||
| 'F5'
|
||||
| 'F6'
|
||||
| 'F7'
|
||||
| 'F8'
|
||||
| 'F9'
|
||||
| 'F10'
|
||||
| 'F11'
|
||||
| 'F12'
|
||||
| 'F13'
|
||||
| 'F14'
|
||||
| 'F15'
|
||||
| 'F16'
|
||||
| 'F17'
|
||||
| 'F18'
|
||||
| 'F19'
|
||||
| 'F20'
|
||||
| 'F21'
|
||||
| 'F22'
|
||||
| 'F23'
|
||||
| 'F24'
|
||||
| 'NumLock'
|
||||
| 'ScrollLock'
|
||||
| 'AudioVolumeMute'
|
||||
| 'AudioVolumeDown'
|
||||
| 'AudioVolumeUp'
|
||||
| 'MediaTrackNext'
|
||||
| 'MediaTrackPrevious'
|
||||
| 'MediaStop'
|
||||
| 'MediaPlayPause'
|
||||
| 'Semicolon'
|
||||
| 'Equal'
|
||||
| 'NumpadEqual'
|
||||
| 'Comma'
|
||||
| 'Minus'
|
||||
| 'Period'
|
||||
| 'Slash'
|
||||
| 'Backquote'
|
||||
| 'BracketLeft'
|
||||
| 'Backslash'
|
||||
| 'BracketRight'
|
||||
| 'Quote'
|
||||
| 'AltGraph'
|
||||
| 'Props'
|
||||
| 'Cancel'
|
||||
| 'Clear'
|
||||
| 'Shift'
|
||||
| 'Control'
|
||||
| 'Alt'
|
||||
| 'Accept'
|
||||
| 'ModeChange'
|
||||
| ' '
|
||||
| 'Print'
|
||||
| 'Execute'
|
||||
| '\u0000'
|
||||
| 'a'
|
||||
| 'b'
|
||||
| 'c'
|
||||
| 'd'
|
||||
| 'e'
|
||||
| 'f'
|
||||
| 'g'
|
||||
| 'h'
|
||||
| 'i'
|
||||
| 'j'
|
||||
| 'k'
|
||||
| 'l'
|
||||
| 'm'
|
||||
| 'n'
|
||||
| 'o'
|
||||
| 'p'
|
||||
| 'q'
|
||||
| 'r'
|
||||
| 's'
|
||||
| 't'
|
||||
| 'u'
|
||||
| 'v'
|
||||
| 'w'
|
||||
| 'x'
|
||||
| 'y'
|
||||
| 'z'
|
||||
| 'Meta'
|
||||
| '*'
|
||||
| '+'
|
||||
| '-'
|
||||
| '/'
|
||||
| ';'
|
||||
| '='
|
||||
| ','
|
||||
| '.'
|
||||
| '`'
|
||||
| '['
|
||||
| '\\'
|
||||
| ']'
|
||||
| "'"
|
||||
| 'Attn'
|
||||
| 'CrSel'
|
||||
| 'ExSel'
|
||||
| 'EraseEof'
|
||||
| 'Play'
|
||||
| 'ZoomOut'
|
||||
| ')'
|
||||
| '!'
|
||||
| '@'
|
||||
| '#'
|
||||
| '$'
|
||||
| '%'
|
||||
| '^'
|
||||
| '&'
|
||||
| '('
|
||||
| 'A'
|
||||
| 'B'
|
||||
| 'C'
|
||||
| 'D'
|
||||
| 'E'
|
||||
| 'F'
|
||||
| 'G'
|
||||
| 'H'
|
||||
| 'I'
|
||||
| 'J'
|
||||
| 'K'
|
||||
| 'L'
|
||||
| 'M'
|
||||
| 'N'
|
||||
| 'O'
|
||||
| 'P'
|
||||
| 'Q'
|
||||
| 'R'
|
||||
| 'S'
|
||||
| 'T'
|
||||
| 'U'
|
||||
| 'V'
|
||||
| 'W'
|
||||
| 'X'
|
||||
| 'Y'
|
||||
| 'Z'
|
||||
| ':'
|
||||
| '<'
|
||||
| '_'
|
||||
| '>'
|
||||
| '?'
|
||||
| '~'
|
||||
| '{'
|
||||
| '|'
|
||||
| '}'
|
||||
| '"'
|
||||
| 'SoftLeft'
|
||||
| 'SoftRight'
|
||||
| 'Camera'
|
||||
| 'Call'
|
||||
| 'EndCall'
|
||||
| 'VolumeDown'
|
||||
| 'VolumeUp';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const _keyDefinitions: Readonly<Record<KeyInput, KeyDefinition>> = {
|
||||
'0': {keyCode: 48, key: '0', code: 'Digit0'},
|
||||
'1': {keyCode: 49, key: '1', code: 'Digit1'},
|
||||
'2': {keyCode: 50, key: '2', code: 'Digit2'},
|
||||
'3': {keyCode: 51, key: '3', code: 'Digit3'},
|
||||
'4': {keyCode: 52, key: '4', code: 'Digit4'},
|
||||
'5': {keyCode: 53, key: '5', code: 'Digit5'},
|
||||
'6': {keyCode: 54, key: '6', code: 'Digit6'},
|
||||
'7': {keyCode: 55, key: '7', code: 'Digit7'},
|
||||
'8': {keyCode: 56, key: '8', code: 'Digit8'},
|
||||
'9': {keyCode: 57, key: '9', code: 'Digit9'},
|
||||
Power: {key: 'Power', code: 'Power'},
|
||||
Eject: {key: 'Eject', code: 'Eject'},
|
||||
Abort: {keyCode: 3, code: 'Abort', key: 'Cancel'},
|
||||
Help: {keyCode: 6, code: 'Help', key: 'Help'},
|
||||
Backspace: {keyCode: 8, code: 'Backspace', key: 'Backspace'},
|
||||
Tab: {keyCode: 9, code: 'Tab', key: 'Tab'},
|
||||
Numpad5: {
|
||||
keyCode: 12,
|
||||
shiftKeyCode: 101,
|
||||
key: 'Clear',
|
||||
code: 'Numpad5',
|
||||
shiftKey: '5',
|
||||
location: 3,
|
||||
},
|
||||
NumpadEnter: {
|
||||
keyCode: 13,
|
||||
code: 'NumpadEnter',
|
||||
key: 'Enter',
|
||||
text: '\r',
|
||||
location: 3,
|
||||
},
|
||||
Enter: {keyCode: 13, code: 'Enter', key: 'Enter', text: '\r'},
|
||||
'\r': {keyCode: 13, code: 'Enter', key: 'Enter', text: '\r'},
|
||||
'\n': {keyCode: 13, code: 'Enter', key: 'Enter', text: '\r'},
|
||||
ShiftLeft: {keyCode: 16, code: 'ShiftLeft', key: 'Shift', location: 1},
|
||||
ShiftRight: {keyCode: 16, code: 'ShiftRight', key: 'Shift', location: 2},
|
||||
ControlLeft: {
|
||||
keyCode: 17,
|
||||
code: 'ControlLeft',
|
||||
key: 'Control',
|
||||
location: 1,
|
||||
},
|
||||
ControlRight: {
|
||||
keyCode: 17,
|
||||
code: 'ControlRight',
|
||||
key: 'Control',
|
||||
location: 2,
|
||||
},
|
||||
AltLeft: {keyCode: 18, code: 'AltLeft', key: 'Alt', location: 1},
|
||||
AltRight: {keyCode: 18, code: 'AltRight', key: 'Alt', location: 2},
|
||||
Pause: {keyCode: 19, code: 'Pause', key: 'Pause'},
|
||||
CapsLock: {keyCode: 20, code: 'CapsLock', key: 'CapsLock'},
|
||||
Escape: {keyCode: 27, code: 'Escape', key: 'Escape'},
|
||||
Convert: {keyCode: 28, code: 'Convert', key: 'Convert'},
|
||||
NonConvert: {keyCode: 29, code: 'NonConvert', key: 'NonConvert'},
|
||||
Space: {keyCode: 32, code: 'Space', key: ' '},
|
||||
Numpad9: {
|
||||
keyCode: 33,
|
||||
shiftKeyCode: 105,
|
||||
key: 'PageUp',
|
||||
code: 'Numpad9',
|
||||
shiftKey: '9',
|
||||
location: 3,
|
||||
},
|
||||
PageUp: {keyCode: 33, code: 'PageUp', key: 'PageUp'},
|
||||
Numpad3: {
|
||||
keyCode: 34,
|
||||
shiftKeyCode: 99,
|
||||
key: 'PageDown',
|
||||
code: 'Numpad3',
|
||||
shiftKey: '3',
|
||||
location: 3,
|
||||
},
|
||||
PageDown: {keyCode: 34, code: 'PageDown', key: 'PageDown'},
|
||||
End: {keyCode: 35, code: 'End', key: 'End'},
|
||||
Numpad1: {
|
||||
keyCode: 35,
|
||||
shiftKeyCode: 97,
|
||||
key: 'End',
|
||||
code: 'Numpad1',
|
||||
shiftKey: '1',
|
||||
location: 3,
|
||||
},
|
||||
Home: {keyCode: 36, code: 'Home', key: 'Home'},
|
||||
Numpad7: {
|
||||
keyCode: 36,
|
||||
shiftKeyCode: 103,
|
||||
key: 'Home',
|
||||
code: 'Numpad7',
|
||||
shiftKey: '7',
|
||||
location: 3,
|
||||
},
|
||||
ArrowLeft: {keyCode: 37, code: 'ArrowLeft', key: 'ArrowLeft'},
|
||||
Numpad4: {
|
||||
keyCode: 37,
|
||||
shiftKeyCode: 100,
|
||||
key: 'ArrowLeft',
|
||||
code: 'Numpad4',
|
||||
shiftKey: '4',
|
||||
location: 3,
|
||||
},
|
||||
Numpad8: {
|
||||
keyCode: 38,
|
||||
shiftKeyCode: 104,
|
||||
key: 'ArrowUp',
|
||||
code: 'Numpad8',
|
||||
shiftKey: '8',
|
||||
location: 3,
|
||||
},
|
||||
ArrowUp: {keyCode: 38, code: 'ArrowUp', key: 'ArrowUp'},
|
||||
ArrowRight: {keyCode: 39, code: 'ArrowRight', key: 'ArrowRight'},
|
||||
Numpad6: {
|
||||
keyCode: 39,
|
||||
shiftKeyCode: 102,
|
||||
key: 'ArrowRight',
|
||||
code: 'Numpad6',
|
||||
shiftKey: '6',
|
||||
location: 3,
|
||||
},
|
||||
Numpad2: {
|
||||
keyCode: 40,
|
||||
shiftKeyCode: 98,
|
||||
key: 'ArrowDown',
|
||||
code: 'Numpad2',
|
||||
shiftKey: '2',
|
||||
location: 3,
|
||||
},
|
||||
ArrowDown: {keyCode: 40, code: 'ArrowDown', key: 'ArrowDown'},
|
||||
Select: {keyCode: 41, code: 'Select', key: 'Select'},
|
||||
Open: {keyCode: 43, code: 'Open', key: 'Execute'},
|
||||
PrintScreen: {keyCode: 44, code: 'PrintScreen', key: 'PrintScreen'},
|
||||
Insert: {keyCode: 45, code: 'Insert', key: 'Insert'},
|
||||
Numpad0: {
|
||||
keyCode: 45,
|
||||
shiftKeyCode: 96,
|
||||
key: 'Insert',
|
||||
code: 'Numpad0',
|
||||
shiftKey: '0',
|
||||
location: 3,
|
||||
},
|
||||
Delete: {keyCode: 46, code: 'Delete', key: 'Delete'},
|
||||
NumpadDecimal: {
|
||||
keyCode: 46,
|
||||
shiftKeyCode: 110,
|
||||
code: 'NumpadDecimal',
|
||||
key: '\u0000',
|
||||
shiftKey: '.',
|
||||
location: 3,
|
||||
},
|
||||
Digit0: {keyCode: 48, code: 'Digit0', shiftKey: ')', key: '0'},
|
||||
Digit1: {keyCode: 49, code: 'Digit1', shiftKey: '!', key: '1'},
|
||||
Digit2: {keyCode: 50, code: 'Digit2', shiftKey: '@', key: '2'},
|
||||
Digit3: {keyCode: 51, code: 'Digit3', shiftKey: '#', key: '3'},
|
||||
Digit4: {keyCode: 52, code: 'Digit4', shiftKey: '$', key: '4'},
|
||||
Digit5: {keyCode: 53, code: 'Digit5', shiftKey: '%', key: '5'},
|
||||
Digit6: {keyCode: 54, code: 'Digit6', shiftKey: '^', key: '6'},
|
||||
Digit7: {keyCode: 55, code: 'Digit7', shiftKey: '&', key: '7'},
|
||||
Digit8: {keyCode: 56, code: 'Digit8', shiftKey: '*', key: '8'},
|
||||
Digit9: {keyCode: 57, code: 'Digit9', shiftKey: '(', key: '9'},
|
||||
KeyA: {keyCode: 65, code: 'KeyA', shiftKey: 'A', key: 'a'},
|
||||
KeyB: {keyCode: 66, code: 'KeyB', shiftKey: 'B', key: 'b'},
|
||||
KeyC: {keyCode: 67, code: 'KeyC', shiftKey: 'C', key: 'c'},
|
||||
KeyD: {keyCode: 68, code: 'KeyD', shiftKey: 'D', key: 'd'},
|
||||
KeyE: {keyCode: 69, code: 'KeyE', shiftKey: 'E', key: 'e'},
|
||||
KeyF: {keyCode: 70, code: 'KeyF', shiftKey: 'F', key: 'f'},
|
||||
KeyG: {keyCode: 71, code: 'KeyG', shiftKey: 'G', key: 'g'},
|
||||
KeyH: {keyCode: 72, code: 'KeyH', shiftKey: 'H', key: 'h'},
|
||||
KeyI: {keyCode: 73, code: 'KeyI', shiftKey: 'I', key: 'i'},
|
||||
KeyJ: {keyCode: 74, code: 'KeyJ', shiftKey: 'J', key: 'j'},
|
||||
KeyK: {keyCode: 75, code: 'KeyK', shiftKey: 'K', key: 'k'},
|
||||
KeyL: {keyCode: 76, code: 'KeyL', shiftKey: 'L', key: 'l'},
|
||||
KeyM: {keyCode: 77, code: 'KeyM', shiftKey: 'M', key: 'm'},
|
||||
KeyN: {keyCode: 78, code: 'KeyN', shiftKey: 'N', key: 'n'},
|
||||
KeyO: {keyCode: 79, code: 'KeyO', shiftKey: 'O', key: 'o'},
|
||||
KeyP: {keyCode: 80, code: 'KeyP', shiftKey: 'P', key: 'p'},
|
||||
KeyQ: {keyCode: 81, code: 'KeyQ', shiftKey: 'Q', key: 'q'},
|
||||
KeyR: {keyCode: 82, code: 'KeyR', shiftKey: 'R', key: 'r'},
|
||||
KeyS: {keyCode: 83, code: 'KeyS', shiftKey: 'S', key: 's'},
|
||||
KeyT: {keyCode: 84, code: 'KeyT', shiftKey: 'T', key: 't'},
|
||||
KeyU: {keyCode: 85, code: 'KeyU', shiftKey: 'U', key: 'u'},
|
||||
KeyV: {keyCode: 86, code: 'KeyV', shiftKey: 'V', key: 'v'},
|
||||
KeyW: {keyCode: 87, code: 'KeyW', shiftKey: 'W', key: 'w'},
|
||||
KeyX: {keyCode: 88, code: 'KeyX', shiftKey: 'X', key: 'x'},
|
||||
KeyY: {keyCode: 89, code: 'KeyY', shiftKey: 'Y', key: 'y'},
|
||||
KeyZ: {keyCode: 90, code: 'KeyZ', shiftKey: 'Z', key: 'z'},
|
||||
MetaLeft: {keyCode: 91, code: 'MetaLeft', key: 'Meta', location: 1},
|
||||
MetaRight: {keyCode: 92, code: 'MetaRight', key: 'Meta', location: 2},
|
||||
ContextMenu: {keyCode: 93, code: 'ContextMenu', key: 'ContextMenu'},
|
||||
NumpadMultiply: {
|
||||
keyCode: 106,
|
||||
code: 'NumpadMultiply',
|
||||
key: '*',
|
||||
location: 3,
|
||||
},
|
||||
NumpadAdd: {keyCode: 107, code: 'NumpadAdd', key: '+', location: 3},
|
||||
NumpadSubtract: {
|
||||
keyCode: 109,
|
||||
code: 'NumpadSubtract',
|
||||
key: '-',
|
||||
location: 3,
|
||||
},
|
||||
NumpadDivide: {keyCode: 111, code: 'NumpadDivide', key: '/', location: 3},
|
||||
F1: {keyCode: 112, code: 'F1', key: 'F1'},
|
||||
F2: {keyCode: 113, code: 'F2', key: 'F2'},
|
||||
F3: {keyCode: 114, code: 'F3', key: 'F3'},
|
||||
F4: {keyCode: 115, code: 'F4', key: 'F4'},
|
||||
F5: {keyCode: 116, code: 'F5', key: 'F5'},
|
||||
F6: {keyCode: 117, code: 'F6', key: 'F6'},
|
||||
F7: {keyCode: 118, code: 'F7', key: 'F7'},
|
||||
F8: {keyCode: 119, code: 'F8', key: 'F8'},
|
||||
F9: {keyCode: 120, code: 'F9', key: 'F9'},
|
||||
F10: {keyCode: 121, code: 'F10', key: 'F10'},
|
||||
F11: {keyCode: 122, code: 'F11', key: 'F11'},
|
||||
F12: {keyCode: 123, code: 'F12', key: 'F12'},
|
||||
F13: {keyCode: 124, code: 'F13', key: 'F13'},
|
||||
F14: {keyCode: 125, code: 'F14', key: 'F14'},
|
||||
F15: {keyCode: 126, code: 'F15', key: 'F15'},
|
||||
F16: {keyCode: 127, code: 'F16', key: 'F16'},
|
||||
F17: {keyCode: 128, code: 'F17', key: 'F17'},
|
||||
F18: {keyCode: 129, code: 'F18', key: 'F18'},
|
||||
F19: {keyCode: 130, code: 'F19', key: 'F19'},
|
||||
F20: {keyCode: 131, code: 'F20', key: 'F20'},
|
||||
F21: {keyCode: 132, code: 'F21', key: 'F21'},
|
||||
F22: {keyCode: 133, code: 'F22', key: 'F22'},
|
||||
F23: {keyCode: 134, code: 'F23', key: 'F23'},
|
||||
F24: {keyCode: 135, code: 'F24', key: 'F24'},
|
||||
NumLock: {keyCode: 144, code: 'NumLock', key: 'NumLock'},
|
||||
ScrollLock: {keyCode: 145, code: 'ScrollLock', key: 'ScrollLock'},
|
||||
AudioVolumeMute: {
|
||||
keyCode: 173,
|
||||
code: 'AudioVolumeMute',
|
||||
key: 'AudioVolumeMute',
|
||||
},
|
||||
AudioVolumeDown: {
|
||||
keyCode: 174,
|
||||
code: 'AudioVolumeDown',
|
||||
key: 'AudioVolumeDown',
|
||||
},
|
||||
AudioVolumeUp: {keyCode: 175, code: 'AudioVolumeUp', key: 'AudioVolumeUp'},
|
||||
MediaTrackNext: {
|
||||
keyCode: 176,
|
||||
code: 'MediaTrackNext',
|
||||
key: 'MediaTrackNext',
|
||||
},
|
||||
MediaTrackPrevious: {
|
||||
keyCode: 177,
|
||||
code: 'MediaTrackPrevious',
|
||||
key: 'MediaTrackPrevious',
|
||||
},
|
||||
MediaStop: {keyCode: 178, code: 'MediaStop', key: 'MediaStop'},
|
||||
MediaPlayPause: {
|
||||
keyCode: 179,
|
||||
code: 'MediaPlayPause',
|
||||
key: 'MediaPlayPause',
|
||||
},
|
||||
Semicolon: {keyCode: 186, code: 'Semicolon', shiftKey: ':', key: ';'},
|
||||
Equal: {keyCode: 187, code: 'Equal', shiftKey: '+', key: '='},
|
||||
NumpadEqual: {keyCode: 187, code: 'NumpadEqual', key: '=', location: 3},
|
||||
Comma: {keyCode: 188, code: 'Comma', shiftKey: '<', key: ','},
|
||||
Minus: {keyCode: 189, code: 'Minus', shiftKey: '_', key: '-'},
|
||||
Period: {keyCode: 190, code: 'Period', shiftKey: '>', key: '.'},
|
||||
Slash: {keyCode: 191, code: 'Slash', shiftKey: '?', key: '/'},
|
||||
Backquote: {keyCode: 192, code: 'Backquote', shiftKey: '~', key: '`'},
|
||||
BracketLeft: {keyCode: 219, code: 'BracketLeft', shiftKey: '{', key: '['},
|
||||
Backslash: {keyCode: 220, code: 'Backslash', shiftKey: '|', key: '\\'},
|
||||
BracketRight: {keyCode: 221, code: 'BracketRight', shiftKey: '}', key: ']'},
|
||||
Quote: {keyCode: 222, code: 'Quote', shiftKey: '"', key: "'"},
|
||||
AltGraph: {keyCode: 225, code: 'AltGraph', key: 'AltGraph'},
|
||||
Props: {keyCode: 247, code: 'Props', key: 'CrSel'},
|
||||
Cancel: {keyCode: 3, key: 'Cancel', code: 'Abort'},
|
||||
Clear: {keyCode: 12, key: 'Clear', code: 'Numpad5', location: 3},
|
||||
Shift: {keyCode: 16, key: 'Shift', code: 'ShiftLeft', location: 1},
|
||||
Control: {keyCode: 17, key: 'Control', code: 'ControlLeft', location: 1},
|
||||
Alt: {keyCode: 18, key: 'Alt', code: 'AltLeft', location: 1},
|
||||
Accept: {keyCode: 30, key: 'Accept'},
|
||||
ModeChange: {keyCode: 31, key: 'ModeChange'},
|
||||
' ': {keyCode: 32, key: ' ', code: 'Space'},
|
||||
Print: {keyCode: 42, key: 'Print'},
|
||||
Execute: {keyCode: 43, key: 'Execute', code: 'Open'},
|
||||
'\u0000': {keyCode: 46, key: '\u0000', code: 'NumpadDecimal', location: 3},
|
||||
a: {keyCode: 65, key: 'a', code: 'KeyA'},
|
||||
b: {keyCode: 66, key: 'b', code: 'KeyB'},
|
||||
c: {keyCode: 67, key: 'c', code: 'KeyC'},
|
||||
d: {keyCode: 68, key: 'd', code: 'KeyD'},
|
||||
e: {keyCode: 69, key: 'e', code: 'KeyE'},
|
||||
f: {keyCode: 70, key: 'f', code: 'KeyF'},
|
||||
g: {keyCode: 71, key: 'g', code: 'KeyG'},
|
||||
h: {keyCode: 72, key: 'h', code: 'KeyH'},
|
||||
i: {keyCode: 73, key: 'i', code: 'KeyI'},
|
||||
j: {keyCode: 74, key: 'j', code: 'KeyJ'},
|
||||
k: {keyCode: 75, key: 'k', code: 'KeyK'},
|
||||
l: {keyCode: 76, key: 'l', code: 'KeyL'},
|
||||
m: {keyCode: 77, key: 'm', code: 'KeyM'},
|
||||
n: {keyCode: 78, key: 'n', code: 'KeyN'},
|
||||
o: {keyCode: 79, key: 'o', code: 'KeyO'},
|
||||
p: {keyCode: 80, key: 'p', code: 'KeyP'},
|
||||
q: {keyCode: 81, key: 'q', code: 'KeyQ'},
|
||||
r: {keyCode: 82, key: 'r', code: 'KeyR'},
|
||||
s: {keyCode: 83, key: 's', code: 'KeyS'},
|
||||
t: {keyCode: 84, key: 't', code: 'KeyT'},
|
||||
u: {keyCode: 85, key: 'u', code: 'KeyU'},
|
||||
v: {keyCode: 86, key: 'v', code: 'KeyV'},
|
||||
w: {keyCode: 87, key: 'w', code: 'KeyW'},
|
||||
x: {keyCode: 88, key: 'x', code: 'KeyX'},
|
||||
y: {keyCode: 89, key: 'y', code: 'KeyY'},
|
||||
z: {keyCode: 90, key: 'z', code: 'KeyZ'},
|
||||
Meta: {keyCode: 91, key: 'Meta', code: 'MetaLeft', location: 1},
|
||||
'*': {keyCode: 106, key: '*', code: 'NumpadMultiply', location: 3},
|
||||
'+': {keyCode: 107, key: '+', code: 'NumpadAdd', location: 3},
|
||||
'-': {keyCode: 109, key: '-', code: 'NumpadSubtract', location: 3},
|
||||
'/': {keyCode: 111, key: '/', code: 'NumpadDivide', location: 3},
|
||||
';': {keyCode: 186, key: ';', code: 'Semicolon'},
|
||||
'=': {keyCode: 187, key: '=', code: 'Equal'},
|
||||
',': {keyCode: 188, key: ',', code: 'Comma'},
|
||||
'.': {keyCode: 190, key: '.', code: 'Period'},
|
||||
'`': {keyCode: 192, key: '`', code: 'Backquote'},
|
||||
'[': {keyCode: 219, key: '[', code: 'BracketLeft'},
|
||||
'\\': {keyCode: 220, key: '\\', code: 'Backslash'},
|
||||
']': {keyCode: 221, key: ']', code: 'BracketRight'},
|
||||
"'": {keyCode: 222, key: "'", code: 'Quote'},
|
||||
Attn: {keyCode: 246, key: 'Attn'},
|
||||
CrSel: {keyCode: 247, key: 'CrSel', code: 'Props'},
|
||||
ExSel: {keyCode: 248, key: 'ExSel'},
|
||||
EraseEof: {keyCode: 249, key: 'EraseEof'},
|
||||
Play: {keyCode: 250, key: 'Play'},
|
||||
ZoomOut: {keyCode: 251, key: 'ZoomOut'},
|
||||
')': {keyCode: 48, key: ')', code: 'Digit0'},
|
||||
'!': {keyCode: 49, key: '!', code: 'Digit1'},
|
||||
'@': {keyCode: 50, key: '@', code: 'Digit2'},
|
||||
'#': {keyCode: 51, key: '#', code: 'Digit3'},
|
||||
$: {keyCode: 52, key: '$', code: 'Digit4'},
|
||||
'%': {keyCode: 53, key: '%', code: 'Digit5'},
|
||||
'^': {keyCode: 54, key: '^', code: 'Digit6'},
|
||||
'&': {keyCode: 55, key: '&', code: 'Digit7'},
|
||||
'(': {keyCode: 57, key: '(', code: 'Digit9'},
|
||||
A: {keyCode: 65, key: 'A', code: 'KeyA'},
|
||||
B: {keyCode: 66, key: 'B', code: 'KeyB'},
|
||||
C: {keyCode: 67, key: 'C', code: 'KeyC'},
|
||||
D: {keyCode: 68, key: 'D', code: 'KeyD'},
|
||||
E: {keyCode: 69, key: 'E', code: 'KeyE'},
|
||||
F: {keyCode: 70, key: 'F', code: 'KeyF'},
|
||||
G: {keyCode: 71, key: 'G', code: 'KeyG'},
|
||||
H: {keyCode: 72, key: 'H', code: 'KeyH'},
|
||||
I: {keyCode: 73, key: 'I', code: 'KeyI'},
|
||||
J: {keyCode: 74, key: 'J', code: 'KeyJ'},
|
||||
K: {keyCode: 75, key: 'K', code: 'KeyK'},
|
||||
L: {keyCode: 76, key: 'L', code: 'KeyL'},
|
||||
M: {keyCode: 77, key: 'M', code: 'KeyM'},
|
||||
N: {keyCode: 78, key: 'N', code: 'KeyN'},
|
||||
O: {keyCode: 79, key: 'O', code: 'KeyO'},
|
||||
P: {keyCode: 80, key: 'P', code: 'KeyP'},
|
||||
Q: {keyCode: 81, key: 'Q', code: 'KeyQ'},
|
||||
R: {keyCode: 82, key: 'R', code: 'KeyR'},
|
||||
S: {keyCode: 83, key: 'S', code: 'KeyS'},
|
||||
T: {keyCode: 84, key: 'T', code: 'KeyT'},
|
||||
U: {keyCode: 85, key: 'U', code: 'KeyU'},
|
||||
V: {keyCode: 86, key: 'V', code: 'KeyV'},
|
||||
W: {keyCode: 87, key: 'W', code: 'KeyW'},
|
||||
X: {keyCode: 88, key: 'X', code: 'KeyX'},
|
||||
Y: {keyCode: 89, key: 'Y', code: 'KeyY'},
|
||||
Z: {keyCode: 90, key: 'Z', code: 'KeyZ'},
|
||||
':': {keyCode: 186, key: ':', code: 'Semicolon'},
|
||||
'<': {keyCode: 188, key: '<', code: 'Comma'},
|
||||
_: {keyCode: 189, key: '_', code: 'Minus'},
|
||||
'>': {keyCode: 190, key: '>', code: 'Period'},
|
||||
'?': {keyCode: 191, key: '?', code: 'Slash'},
|
||||
'~': {keyCode: 192, key: '~', code: 'Backquote'},
|
||||
'{': {keyCode: 219, key: '{', code: 'BracketLeft'},
|
||||
'|': {keyCode: 220, key: '|', code: 'Backslash'},
|
||||
'}': {keyCode: 221, key: '}', code: 'BracketRight'},
|
||||
'"': {keyCode: 222, key: '"', code: 'Quote'},
|
||||
SoftLeft: {key: 'SoftLeft', code: 'SoftLeft', location: 4},
|
||||
SoftRight: {key: 'SoftRight', code: 'SoftRight', location: 4},
|
||||
Camera: {keyCode: 44, key: 'Camera', code: 'Camera', location: 4},
|
||||
Call: {key: 'Call', code: 'Call', location: 4},
|
||||
EndCall: {keyCode: 95, key: 'EndCall', code: 'EndCall', location: 4},
|
||||
VolumeDown: {
|
||||
keyCode: 182,
|
||||
key: 'VolumeDown',
|
||||
code: 'VolumeDown',
|
||||
location: 4,
|
||||
},
|
||||
VolumeUp: {keyCode: 183, key: 'VolumeUp', code: 'VolumeUp', location: 4},
|
||||
};
|
||||
50
node_modules/puppeteer-core/src/common/Viewport.ts
generated
vendored
Normal file
50
node_modules/puppeteer-core/src/common/Viewport.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Viewport {
|
||||
/**
|
||||
* The page width in CSS pixels.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this value to `0` will reset this value to the system default.
|
||||
*/
|
||||
width: number;
|
||||
/**
|
||||
* The page height in CSS pixels.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this value to `0` will reset this value to the system default.
|
||||
*/
|
||||
height: number;
|
||||
/**
|
||||
* Specify device scale factor.
|
||||
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio | devicePixelRatio} for more info.
|
||||
*
|
||||
* @remarks
|
||||
* Setting this value to `0` will reset this value to the system default.
|
||||
*
|
||||
* @defaultValue `1`
|
||||
*/
|
||||
deviceScaleFactor?: number;
|
||||
/**
|
||||
* Whether the `meta viewport` tag is taken into account.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
isMobile?: boolean;
|
||||
/**
|
||||
* Specifies if the viewport is in landscape mode.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
isLandscape?: boolean;
|
||||
/**
|
||||
* Specify if the viewport supports touch events.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
hasTouch?: boolean;
|
||||
}
|
||||
273
node_modules/puppeteer-core/src/common/WaitTask.ts
generated
vendored
Normal file
273
node_modules/puppeteer-core/src/common/WaitTask.ts
generated
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {ElementHandle} from '../api/ElementHandle.js';
|
||||
import type {JSHandle} from '../api/JSHandle.js';
|
||||
import type {Realm} from '../api/Realm.js';
|
||||
import type {Poller} from '../injected/Poller.js';
|
||||
import {Deferred} from '../util/Deferred.js';
|
||||
import {isErrorLike} from '../util/ErrorLike.js';
|
||||
import {stringifyFunction} from '../util/Function.js';
|
||||
|
||||
import {TimeoutError} from './Errors.js';
|
||||
import {LazyArg} from './LazyArg.js';
|
||||
import type {HandleFor} from './types.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface WaitTaskOptions {
|
||||
polling: 'raf' | 'mutation' | number;
|
||||
root?: ElementHandle<Node>;
|
||||
timeout: number;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class WaitTask<T = unknown> {
|
||||
#world: Realm;
|
||||
#polling: 'raf' | 'mutation' | number;
|
||||
#root?: ElementHandle<Node>;
|
||||
|
||||
#fn: string;
|
||||
#args: unknown[];
|
||||
|
||||
#timeout?: NodeJS.Timeout;
|
||||
#genericError = new Error('Waiting failed');
|
||||
#timeoutError?: TimeoutError;
|
||||
|
||||
#result = Deferred.create<HandleFor<T>>();
|
||||
|
||||
#poller?: JSHandle<Poller<T>>;
|
||||
#signal?: AbortSignal;
|
||||
#reruns: AbortController[] = [];
|
||||
|
||||
constructor(
|
||||
world: Realm,
|
||||
options: WaitTaskOptions,
|
||||
fn: ((...args: unknown[]) => Promise<T>) | string,
|
||||
...args: unknown[]
|
||||
) {
|
||||
this.#world = world;
|
||||
this.#polling = options.polling;
|
||||
this.#root = options.root;
|
||||
this.#signal = options.signal;
|
||||
this.#signal?.addEventListener('abort', this.#onAbortSignal, {
|
||||
once: true,
|
||||
});
|
||||
|
||||
switch (typeof fn) {
|
||||
case 'string':
|
||||
this.#fn = `() => {return (${fn});}`;
|
||||
break;
|
||||
default:
|
||||
this.#fn = stringifyFunction(fn);
|
||||
break;
|
||||
}
|
||||
this.#args = args;
|
||||
|
||||
this.#world.taskManager.add(this);
|
||||
|
||||
if (options.timeout) {
|
||||
this.#timeoutError = new TimeoutError(
|
||||
`Waiting failed: ${options.timeout}ms exceeded`,
|
||||
);
|
||||
this.#timeout = setTimeout(() => {
|
||||
void this.terminate(this.#timeoutError);
|
||||
}, options.timeout);
|
||||
}
|
||||
|
||||
void this.rerun();
|
||||
}
|
||||
|
||||
get result(): Promise<HandleFor<T>> {
|
||||
return this.#result.valueOrThrow();
|
||||
}
|
||||
|
||||
async rerun(): Promise<void> {
|
||||
for (const prev of this.#reruns) {
|
||||
prev.abort();
|
||||
}
|
||||
this.#reruns.length = 0;
|
||||
const controller = new AbortController();
|
||||
this.#reruns.push(controller);
|
||||
try {
|
||||
switch (this.#polling) {
|
||||
case 'raf':
|
||||
this.#poller = await this.#world.evaluateHandle(
|
||||
({RAFPoller, createFunction}, fn, ...args) => {
|
||||
const fun = createFunction(fn);
|
||||
return new RAFPoller(() => {
|
||||
return fun(...args) as Promise<T>;
|
||||
});
|
||||
},
|
||||
LazyArg.create(context => {
|
||||
return context.puppeteerUtil;
|
||||
}),
|
||||
this.#fn,
|
||||
...this.#args,
|
||||
);
|
||||
break;
|
||||
case 'mutation':
|
||||
this.#poller = await this.#world.evaluateHandle(
|
||||
({MutationPoller, createFunction}, root, fn, ...args) => {
|
||||
const fun = createFunction(fn);
|
||||
return new MutationPoller(() => {
|
||||
return fun(...args) as Promise<T>;
|
||||
}, root || document);
|
||||
},
|
||||
LazyArg.create(context => {
|
||||
return context.puppeteerUtil;
|
||||
}),
|
||||
this.#root,
|
||||
this.#fn,
|
||||
...this.#args,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
this.#poller = await this.#world.evaluateHandle(
|
||||
({IntervalPoller, createFunction}, ms, fn, ...args) => {
|
||||
const fun = createFunction(fn);
|
||||
return new IntervalPoller(() => {
|
||||
return fun(...args) as Promise<T>;
|
||||
}, ms);
|
||||
},
|
||||
LazyArg.create(context => {
|
||||
return context.puppeteerUtil;
|
||||
}),
|
||||
this.#polling,
|
||||
this.#fn,
|
||||
...this.#args,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
await this.#poller.evaluate(poller => {
|
||||
void poller.start();
|
||||
});
|
||||
|
||||
const result = await this.#poller.evaluateHandle(poller => {
|
||||
return poller.result();
|
||||
});
|
||||
this.#result.resolve(result);
|
||||
|
||||
await this.terminate();
|
||||
} catch (error) {
|
||||
if (controller.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
const badError = this.getBadError(error);
|
||||
if (badError) {
|
||||
this.#genericError.cause = badError;
|
||||
await this.terminate(this.#genericError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async terminate(error?: Error): Promise<void> {
|
||||
this.#world.taskManager.delete(this);
|
||||
|
||||
this.#signal?.removeEventListener('abort', this.#onAbortSignal);
|
||||
|
||||
clearTimeout(this.#timeout);
|
||||
|
||||
if (error && !this.#result.finished()) {
|
||||
this.#result.reject(error);
|
||||
}
|
||||
|
||||
if (this.#poller) {
|
||||
try {
|
||||
await this.#poller.evaluate(async poller => {
|
||||
await poller.stop();
|
||||
});
|
||||
if (this.#poller) {
|
||||
await this.#poller.dispose();
|
||||
this.#poller = undefined;
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors since they most likely come from low-level cleanup.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not all errors lead to termination. They usually imply we need to rerun the task.
|
||||
*/
|
||||
getBadError(error: unknown): Error | undefined {
|
||||
if (isErrorLike(error)) {
|
||||
// When frame is detached the task should have been terminated by the IsolatedWorld.
|
||||
// This can fail if we were adding this task while the frame was detached,
|
||||
// so we terminate here instead.
|
||||
if (
|
||||
error.message.includes(
|
||||
'Execution context is not available in detached frame',
|
||||
)
|
||||
) {
|
||||
return new Error('Waiting failed: Frame detached');
|
||||
}
|
||||
|
||||
// When the page is navigated, the promise is rejected.
|
||||
// We will try again in the new execution context.
|
||||
if (error.message.includes('Execution context was destroyed')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We could have tried to evaluate in a context which was already
|
||||
// destroyed.
|
||||
if (error.message.includes('Cannot find context with specified id')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Errors coming from WebDriver BiDi. TODO: Adjust messages after
|
||||
// https://github.com/w3c/webdriver-bidi/issues/540 is resolved.
|
||||
if (error.message.includes('DiscardedBrowsingContextError')) {
|
||||
return;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
return new Error('WaitTask failed with an error', {
|
||||
cause: error,
|
||||
});
|
||||
}
|
||||
|
||||
#onAbortSignal = () => {
|
||||
void this.terminate(this.#signal?.reason);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class TaskManager {
|
||||
#tasks: Set<WaitTask> = new Set<WaitTask>();
|
||||
|
||||
add(task: WaitTask<any>): void {
|
||||
this.#tasks.add(task);
|
||||
}
|
||||
|
||||
delete(task: WaitTask<any>): void {
|
||||
this.#tasks.delete(task);
|
||||
}
|
||||
|
||||
terminateAll(error?: Error): void {
|
||||
for (const task of this.#tasks) {
|
||||
void task.terminate(error);
|
||||
}
|
||||
this.#tasks.clear();
|
||||
}
|
||||
|
||||
async rerunAll(): Promise<void> {
|
||||
await Promise.all(
|
||||
[...this.#tasks].map(task => {
|
||||
return task.rerun();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
35
node_modules/puppeteer-core/src/common/XPathQueryHandler.ts
generated
vendored
Normal file
35
node_modules/puppeteer-core/src/common/XPathQueryHandler.ts
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2023 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
QueryHandler,
|
||||
type QuerySelectorAll,
|
||||
type QuerySelector,
|
||||
} from './QueryHandler.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class XPathQueryHandler extends QueryHandler {
|
||||
static override querySelectorAll: QuerySelectorAll = (
|
||||
element,
|
||||
selector,
|
||||
{xpathQuerySelectorAll},
|
||||
) => {
|
||||
return xpathQuerySelectorAll(element, selector);
|
||||
};
|
||||
|
||||
static override querySelector: QuerySelector = (
|
||||
element: Node,
|
||||
selector: string,
|
||||
{xpathQuerySelectorAll},
|
||||
) => {
|
||||
for (const result of xpathQuerySelectorAll(element, selector, 1)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
43
node_modules/puppeteer-core/src/common/common.ts
generated
vendored
Normal file
43
node_modules/puppeteer-core/src/common/common.ts
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2022 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
export * from './BrowserWebSocketTransport.js';
|
||||
export * from './CallbackRegistry.js';
|
||||
export * from './AriaQueryHandler.js';
|
||||
export type * from './Configuration.js';
|
||||
export type * from './ConnectionTransport.js';
|
||||
export type * from './ConnectOptions.js';
|
||||
export * from './ConsoleMessage.js';
|
||||
export type * from './Cookie.js';
|
||||
export * from './CustomQueryHandler.js';
|
||||
export * from './Debug.js';
|
||||
export * from './Device.js';
|
||||
export * from './Errors.js';
|
||||
export * from './EventEmitter.js';
|
||||
export * from './FileChooser.js';
|
||||
export * from './GetQueryHandler.js';
|
||||
export * from './HandleIterator.js';
|
||||
export * from './LazyArg.js';
|
||||
export * from './NetworkManagerEvents.js';
|
||||
export * from './PDFOptions.js';
|
||||
export * from './PierceQueryHandler.js';
|
||||
export * from './PQueryHandler.js';
|
||||
export type * from './SupportedBrowser.js';
|
||||
export * from './PSelectorParser.js';
|
||||
export * from './Puppeteer.js';
|
||||
export * from './QueryHandler.js';
|
||||
export * from './ScriptInjector.js';
|
||||
export * from './SecurityDetails.js';
|
||||
export * from './TaskQueue.js';
|
||||
export * from './TextQueryHandler.js';
|
||||
export * from './TimeoutSettings.js';
|
||||
export type * from './types.js';
|
||||
export * from './USKeyboardLayout.js';
|
||||
export * from './util.js';
|
||||
export type * from './Viewport.js';
|
||||
export * from './WaitTask.js';
|
||||
export * from './XPathQueryHandler.js';
|
||||
export type * from './DownloadBehavior.js';
|
||||
128
node_modules/puppeteer-core/src/common/types.ts
generated
vendored
Normal file
128
node_modules/puppeteer-core/src/common/types.ts
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {ParseSelector} from 'typed-query-selector/parser.js';
|
||||
|
||||
import type {ElementHandle} from '../api/ElementHandle.js';
|
||||
import type {JSHandle} from '../api/JSHandle.js';
|
||||
|
||||
import type {LazyArg} from './LazyArg.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type AwaitablePredicate<T> = (value: T) => Awaitable<boolean>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Moveable {
|
||||
/**
|
||||
* Moves the resource when 'using'.
|
||||
*/
|
||||
move(): this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface Disposed {
|
||||
get disposed(): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface BindingPayload {
|
||||
type: string;
|
||||
name: string;
|
||||
seq: number;
|
||||
args: unknown[];
|
||||
/**
|
||||
* Determines whether the arguments of the payload are trivial.
|
||||
*/
|
||||
isTrivial: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type AwaitableIterator<T> = Iterator<T> | AsyncIterator<T>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type AwaitableIterable<T> = Iterable<T> | AsyncIterable<T>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type Awaitable<T> = T | PromiseLike<T>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type HandleFor<T> = T extends Node ? ElementHandle<T> : JSHandle<T>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type HandleOr<T> = HandleFor<T> | JSHandle<T> | T;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type FlattenHandle<T> = T extends HandleOr<infer U> ? U : never;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type FlattenLazyArg<T> = T extends LazyArg<infer U> ? U : T;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type InnerLazyParams<T extends unknown[]> = {
|
||||
[K in keyof T]: FlattenLazyArg<T[K]>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type InnerParams<T extends unknown[]> = {
|
||||
[K in keyof T]: FlattenHandle<T[K]>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ElementFor<
|
||||
TagName extends keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap,
|
||||
> = TagName extends keyof HTMLElementTagNameMap
|
||||
? HTMLElementTagNameMap[TagName]
|
||||
: TagName extends keyof SVGElementTagNameMap
|
||||
? SVGElementTagNameMap[TagName]
|
||||
: never;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type EvaluateFunc<T extends unknown[]> = (
|
||||
...params: InnerParams<T>
|
||||
) => Awaitable<unknown>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type EvaluateFuncWith<V, T extends unknown[]> = (
|
||||
...params: [V, ...InnerParams<T>]
|
||||
) => Awaitable<unknown>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NodeFor<ComplexSelector extends string> =
|
||||
ParseSelector<ComplexSelector>;
|
||||
477
node_modules/puppeteer-core/src/common/util.ts
generated
vendored
Normal file
477
node_modules/puppeteer-core/src/common/util.ts
generated
vendored
Normal file
@@ -0,0 +1,477 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2017 Google Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {OperatorFunction} from '../../third_party/rxjs/rxjs.js';
|
||||
import {
|
||||
filter,
|
||||
from,
|
||||
fromEvent,
|
||||
map,
|
||||
mergeMap,
|
||||
NEVER,
|
||||
Observable,
|
||||
timer,
|
||||
} from '../../third_party/rxjs/rxjs.js';
|
||||
import type {CDPSession} from '../api/CDPSession.js';
|
||||
import {environment} from '../environment.js';
|
||||
import {assert} from '../util/assert.js';
|
||||
import {mergeUint8Arrays, stringToTypedArray} from '../util/encoding.js';
|
||||
import {packageVersion} from '../util/version.js';
|
||||
|
||||
import {debug} from './Debug.js';
|
||||
import {TimeoutError} from './Errors.js';
|
||||
import type {EventEmitter, EventType} from './EventEmitter.js';
|
||||
import type {
|
||||
LowerCasePaperFormat,
|
||||
ParsedPDFOptions,
|
||||
PDFOptions,
|
||||
} from './PDFOptions.js';
|
||||
import {paperFormats} from './PDFOptions.js';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const debugError = debug('puppeteer:error');
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const DEFAULT_VIEWPORT = Object.freeze({width: 800, height: 600});
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const SOURCE_URL = Symbol('Source URL for Puppeteer evaluation scripts');
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export class PuppeteerURL {
|
||||
static INTERNAL_URL = 'pptr:internal';
|
||||
|
||||
static fromCallSite(
|
||||
functionName: string,
|
||||
site: NodeJS.CallSite,
|
||||
): PuppeteerURL {
|
||||
const url = new PuppeteerURL();
|
||||
url.#functionName = functionName;
|
||||
url.#siteString = site.toString();
|
||||
return url;
|
||||
}
|
||||
|
||||
static parse = (url: string): PuppeteerURL => {
|
||||
url = url.slice('pptr:'.length);
|
||||
const [functionName = '', siteString = ''] = url.split(';');
|
||||
const puppeteerUrl = new PuppeteerURL();
|
||||
puppeteerUrl.#functionName = functionName;
|
||||
puppeteerUrl.#siteString = decodeURIComponent(siteString);
|
||||
return puppeteerUrl;
|
||||
};
|
||||
|
||||
static isPuppeteerURL = (url: string): boolean => {
|
||||
return url.startsWith('pptr:');
|
||||
};
|
||||
|
||||
#functionName!: string;
|
||||
#siteString!: string;
|
||||
|
||||
get functionName(): string {
|
||||
return this.#functionName;
|
||||
}
|
||||
|
||||
get siteString(): string {
|
||||
return this.#siteString;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `pptr:${[
|
||||
this.#functionName,
|
||||
encodeURIComponent(this.#siteString),
|
||||
].join(';')}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const withSourcePuppeteerURLIfNone = <T extends NonNullable<unknown>>(
|
||||
functionName: string,
|
||||
object: T,
|
||||
): T => {
|
||||
if (Object.prototype.hasOwnProperty.call(object, SOURCE_URL)) {
|
||||
return object;
|
||||
}
|
||||
const original = Error.prepareStackTrace;
|
||||
Error.prepareStackTrace = (_, stack) => {
|
||||
// First element is the function.
|
||||
// Second element is the caller of this function.
|
||||
// Third element is the caller of the caller of this function
|
||||
// which is precisely what we want.
|
||||
return stack[2];
|
||||
};
|
||||
const site = new Error().stack as unknown as NodeJS.CallSite;
|
||||
Error.prepareStackTrace = original;
|
||||
return Object.assign(object, {
|
||||
[SOURCE_URL]: PuppeteerURL.fromCallSite(functionName, site),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const getSourcePuppeteerURLIfAvailable = <
|
||||
T extends NonNullable<unknown>,
|
||||
>(
|
||||
object: T,
|
||||
): PuppeteerURL | undefined => {
|
||||
if (Object.prototype.hasOwnProperty.call(object, SOURCE_URL)) {
|
||||
return object[SOURCE_URL as keyof T] as PuppeteerURL;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isString = (obj: unknown): obj is string => {
|
||||
return typeof obj === 'string' || obj instanceof String;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isNumber = (obj: unknown): obj is number => {
|
||||
return typeof obj === 'number' || obj instanceof Number;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isPlainObject = (obj: unknown): obj is Record<any, unknown> => {
|
||||
return typeof obj === 'object' && obj?.constructor === Object;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isRegExp = (obj: unknown): obj is RegExp => {
|
||||
return typeof obj === 'object' && obj?.constructor === RegExp;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isDate = (obj: unknown): obj is Date => {
|
||||
return typeof obj === 'object' && obj?.constructor === Date;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function evaluationString(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||
fun: Function | string,
|
||||
...args: unknown[]
|
||||
): string {
|
||||
if (isString(fun)) {
|
||||
assert(args.length === 0, 'Cannot evaluate a string with arguments');
|
||||
return fun;
|
||||
}
|
||||
|
||||
function serializeArgument(arg: unknown): string {
|
||||
if (Object.is(arg, undefined)) {
|
||||
return 'undefined';
|
||||
}
|
||||
return JSON.stringify(arg);
|
||||
}
|
||||
|
||||
return `(${fun})(${args.map(serializeArgument).join(',')})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export async function getReadableAsTypedArray(
|
||||
readable: ReadableStream<Uint8Array>,
|
||||
path?: string,
|
||||
): Promise<Uint8Array | null> {
|
||||
const buffers: Uint8Array[] = [];
|
||||
const reader = readable.getReader();
|
||||
if (path) {
|
||||
const fileHandle = await environment.value.fs.promises.open(path, 'w+');
|
||||
try {
|
||||
while (true) {
|
||||
const {done, value} = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
buffers.push(value);
|
||||
await fileHandle.writeFile(value);
|
||||
}
|
||||
} finally {
|
||||
await fileHandle.close();
|
||||
}
|
||||
} else {
|
||||
while (true) {
|
||||
const {done, value} = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
buffers.push(value);
|
||||
}
|
||||
}
|
||||
try {
|
||||
const concat = mergeUint8Arrays(buffers);
|
||||
if (concat.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return concat;
|
||||
} catch (error) {
|
||||
debugError(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export async function getReadableFromProtocolStream(
|
||||
client: CDPSession,
|
||||
handle: string,
|
||||
): Promise<ReadableStream<Uint8Array>> {
|
||||
return new ReadableStream({
|
||||
async pull(controller) {
|
||||
const {data, base64Encoded, eof} = await client.send('IO.read', {
|
||||
handle,
|
||||
});
|
||||
|
||||
controller.enqueue(stringToTypedArray(data, base64Encoded ?? false));
|
||||
if (eof) {
|
||||
await client.send('IO.close', {handle});
|
||||
controller.close();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function validateDialogType(
|
||||
type: string,
|
||||
): 'alert' | 'confirm' | 'prompt' | 'beforeunload' {
|
||||
let dialogType = null;
|
||||
const validDialogTypes = new Set([
|
||||
'alert',
|
||||
'confirm',
|
||||
'prompt',
|
||||
'beforeunload',
|
||||
]);
|
||||
|
||||
if (validDialogTypes.has(type)) {
|
||||
dialogType = type;
|
||||
}
|
||||
assert(dialogType, `Unknown javascript dialog type: ${type}`);
|
||||
return dialogType as 'alert' | 'confirm' | 'prompt' | 'beforeunload';
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function timeout(ms: number, cause?: Error): Observable<never> {
|
||||
return ms === 0
|
||||
? NEVER
|
||||
: timer(ms).pipe(
|
||||
map(() => {
|
||||
throw new TimeoutError(`Timed out after waiting ${ms}ms`, {cause});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const UTILITY_WORLD_NAME =
|
||||
'__puppeteer_utility_world__' + packageVersion;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const SOURCE_URL_REGEX =
|
||||
/^[\x20\t]*\/\/[@#] sourceURL=\s{0,10}(\S*?)\s{0,10}$/m;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function getSourceUrlComment(url: string): string {
|
||||
return `//# sourceURL=${url}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const NETWORK_IDLE_TIME = 500;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function parsePDFOptions(
|
||||
options: PDFOptions = {},
|
||||
lengthUnit: 'in' | 'cm' = 'in',
|
||||
): ParsedPDFOptions {
|
||||
const defaults: Omit<ParsedPDFOptions, 'width' | 'height' | 'margin'> = {
|
||||
scale: 1,
|
||||
displayHeaderFooter: false,
|
||||
headerTemplate: '',
|
||||
footerTemplate: '',
|
||||
printBackground: false,
|
||||
landscape: false,
|
||||
pageRanges: '',
|
||||
preferCSSPageSize: false,
|
||||
omitBackground: false,
|
||||
outline: false,
|
||||
tagged: true,
|
||||
waitForFonts: true,
|
||||
};
|
||||
|
||||
let width = 8.5;
|
||||
let height = 11;
|
||||
if (options.format) {
|
||||
const format =
|
||||
paperFormats[options.format.toLowerCase() as LowerCasePaperFormat][
|
||||
lengthUnit
|
||||
];
|
||||
assert(format, 'Unknown paper format: ' + options.format);
|
||||
width = format.width;
|
||||
height = format.height;
|
||||
} else {
|
||||
width = convertPrintParameterToInches(options.width, lengthUnit) ?? width;
|
||||
height =
|
||||
convertPrintParameterToInches(options.height, lengthUnit) ?? height;
|
||||
}
|
||||
|
||||
const margin = {
|
||||
top: convertPrintParameterToInches(options.margin?.top, lengthUnit) || 0,
|
||||
left: convertPrintParameterToInches(options.margin?.left, lengthUnit) || 0,
|
||||
bottom:
|
||||
convertPrintParameterToInches(options.margin?.bottom, lengthUnit) || 0,
|
||||
right:
|
||||
convertPrintParameterToInches(options.margin?.right, lengthUnit) || 0,
|
||||
};
|
||||
|
||||
// Quirk https://bugs.chromium.org/p/chromium/issues/detail?id=840455#c44
|
||||
if (options.outline) {
|
||||
options.tagged = true;
|
||||
}
|
||||
|
||||
return {
|
||||
...defaults,
|
||||
...options,
|
||||
width,
|
||||
height,
|
||||
margin,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const unitToPixels = {
|
||||
px: 1,
|
||||
in: 96,
|
||||
cm: 37.8,
|
||||
mm: 3.78,
|
||||
};
|
||||
|
||||
function convertPrintParameterToInches(
|
||||
parameter?: string | number,
|
||||
lengthUnit: 'in' | 'cm' = 'in',
|
||||
): number | undefined {
|
||||
if (typeof parameter === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
let pixels;
|
||||
if (isNumber(parameter)) {
|
||||
// Treat numbers as pixel values to be aligned with phantom's paperSize.
|
||||
pixels = parameter;
|
||||
} else if (isString(parameter)) {
|
||||
const text = parameter;
|
||||
let unit = text.substring(text.length - 2).toLowerCase();
|
||||
let valueText = '';
|
||||
if (unit in unitToPixels) {
|
||||
valueText = text.substring(0, text.length - 2);
|
||||
} else {
|
||||
// In case of unknown unit try to parse the whole parameter as number of pixels.
|
||||
// This is consistent with phantom's paperSize behavior.
|
||||
unit = 'px';
|
||||
valueText = text;
|
||||
}
|
||||
const value = Number(valueText);
|
||||
assert(!isNaN(value), 'Failed to parse parameter value: ' + text);
|
||||
pixels = value * unitToPixels[unit as keyof typeof unitToPixels];
|
||||
} else {
|
||||
throw new Error(
|
||||
'page.pdf() Cannot handle parameter type: ' + typeof parameter,
|
||||
);
|
||||
}
|
||||
return pixels / unitToPixels[lengthUnit];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function fromEmitterEvent<
|
||||
Events extends Record<EventType, unknown>,
|
||||
Event extends keyof Events,
|
||||
>(emitter: EventEmitter<Events>, eventName: Event): Observable<Events[Event]> {
|
||||
return new Observable(subscriber => {
|
||||
const listener = (event: Events[Event]) => {
|
||||
subscriber.next(event);
|
||||
};
|
||||
emitter.on(eventName, listener);
|
||||
return () => {
|
||||
emitter.off(eventName, listener);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function fromAbortSignal(
|
||||
signal?: AbortSignal,
|
||||
cause?: Error,
|
||||
): Observable<never> {
|
||||
return signal
|
||||
? fromEvent(signal, 'abort').pipe(
|
||||
map(() => {
|
||||
if (signal.reason instanceof Error) {
|
||||
signal.reason.cause = cause;
|
||||
throw signal.reason;
|
||||
}
|
||||
|
||||
throw new Error(signal.reason, {cause});
|
||||
}),
|
||||
)
|
||||
: NEVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function filterAsync<T>(
|
||||
predicate: (value: T) => boolean | PromiseLike<boolean>,
|
||||
): OperatorFunction<T, T> {
|
||||
return mergeMap<T, Observable<T>>((value): Observable<T> => {
|
||||
return from(Promise.resolve(predicate(value))).pipe(
|
||||
filter(isMatch => {
|
||||
return isMatch;
|
||||
}),
|
||||
map(() => {
|
||||
return value;
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user