chore: remove unneeded files, reuse events between browsers, no implicit any (#191)
This commit is contained in:
Родитель
d96cd76852
Коммит
f1f9dc166b
|
@ -1,6 +0,0 @@
|
|||
export interface ConnectionTransport {
|
||||
send(s: string): void;
|
||||
close(): void;
|
||||
onmessage?: (message: string) => void,
|
||||
onclose?: () => void,
|
||||
}
|
|
@ -15,7 +15,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export const DeviceDescriptors = [
|
||||
import * as types from './types';
|
||||
|
||||
export type DeviceDescriptor = {
|
||||
name: string,
|
||||
userAgent: string,
|
||||
viewport: types.Viewport,
|
||||
};
|
||||
|
||||
export const DeviceDescriptors: DeviceDescriptor[] = [
|
||||
{
|
||||
'name': 'Blackberry PlayBook',
|
||||
'userAgent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
|
||||
|
|
|
@ -171,7 +171,7 @@ export class Browser extends EventEmitter {
|
|||
const existingTarget = this._allTargets().find(predicate);
|
||||
if (existingTarget)
|
||||
return existingTarget;
|
||||
let resolve;
|
||||
let resolve: (target: Target) => void;
|
||||
const targetPromise = new Promise<Target>(x => resolve = x);
|
||||
this.chromium.on(Events.Chromium.TargetCreated, check);
|
||||
this.chromium.on(Events.Chromium.TargetChanged, check);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
import * as debug from 'debug';
|
||||
import { EventEmitter } from 'events';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { assert } from '../helper';
|
||||
import { Protocol } from './protocol';
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import { LifecycleWatcher } from './LifecycleWatcher';
|
|||
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
|
||||
import { Page } from '../page';
|
||||
import { Protocol } from './protocol';
|
||||
import { Events as CommonEvents } from '../events';
|
||||
import { Events } from '../events';
|
||||
import { toConsoleMessageLocation, exceptionToError, releaseObject } from './protocolHelper';
|
||||
import * as dialog from '../dialog';
|
||||
import { PageDelegate } from '../page';
|
||||
|
@ -85,18 +85,18 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
(this._page as any).accessibility = new Accessibility(client);
|
||||
(this._page as any).coverage = new Coverage(client);
|
||||
(this._page as any).pdf = new PDF(client);
|
||||
(this._page as any).workers = new Workers(client, this._page._addConsoleMessage.bind(this._page), error => this._page.emit(CommonEvents.Page.PageError, error));
|
||||
(this._page as any).workers = new Workers(client, this._page._addConsoleMessage.bind(this._page), error => this._page.emit(Events.Page.PageError, error));
|
||||
(this._page as any).overrides = new Overrides(client);
|
||||
(this._page as any).interception = new Interception(this._networkManager);
|
||||
|
||||
this._networkManager.on(NetworkManagerEvents.Request, event => this._page.emit(CommonEvents.Page.Request, event));
|
||||
this._networkManager.on(NetworkManagerEvents.Response, event => this._page.emit(CommonEvents.Page.Response, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFailed, event => this._page.emit(CommonEvents.Page.RequestFailed, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFinished, event => this._page.emit(CommonEvents.Page.RequestFinished, event));
|
||||
this._networkManager.on(NetworkManagerEvents.Request, event => this._page.emit(Events.Page.Request, event));
|
||||
this._networkManager.on(NetworkManagerEvents.Response, event => this._page.emit(Events.Page.Response, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFailed, event => this._page.emit(Events.Page.RequestFailed, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFinished, event => this._page.emit(Events.Page.RequestFinished, event));
|
||||
|
||||
this._client.on('Inspector.targetCrashed', event => this._onTargetCrashed());
|
||||
this._client.on('Log.entryAdded', event => this._onLogEntryAdded(event));
|
||||
this._client.on('Page.domContentEventFired', event => this._page.emit(CommonEvents.Page.DOMContentLoaded));
|
||||
this._client.on('Page.domContentEventFired', event => this._page.emit(Events.Page.DOMContentLoaded));
|
||||
this._client.on('Page.fileChooserOpened', event => this._onFileChooserOpened(event));
|
||||
this._client.on('Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId));
|
||||
this._client.on('Page.frameDetached', event => this._onFrameDetached(event.frameId));
|
||||
|
@ -104,7 +104,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
this._client.on('Page.frameStoppedLoading', event => this._onFrameStoppedLoading(event.frameId));
|
||||
this._client.on('Page.javascriptDialogOpening', event => this._onDialog(event));
|
||||
this._client.on('Page.lifecycleEvent', event => this._onLifecycleEvent(event));
|
||||
this._client.on('Page.loadEventFired', event => this._page.emit(CommonEvents.Page.Load));
|
||||
this._client.on('Page.loadEventFired', event => this._page.emit(Events.Page.Load));
|
||||
this._client.on('Page.navigatedWithinDocument', event => this._onFrameNavigatedWithinDocument(event.frameId, event.url));
|
||||
this._client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
|
||||
this._client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
||||
|
@ -280,10 +280,10 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
id: frameId,
|
||||
loaderId: '',
|
||||
};
|
||||
frame[frameDataSymbol] = data;
|
||||
(frame as any)[frameDataSymbol] = data;
|
||||
this._frames.set(frameId, frame);
|
||||
this.emit(FrameManagerEvents.FrameAttached, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameAttached, frame);
|
||||
this._page.emit(Events.Page.FrameAttached, frame);
|
||||
}
|
||||
|
||||
_onFrameNavigated(framePayload: Protocol.Page.Frame) {
|
||||
|
@ -311,7 +311,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
id: framePayload.id,
|
||||
loaderId: '',
|
||||
};
|
||||
frame[frameDataSymbol] = data;
|
||||
(frame as any)[frameDataSymbol] = data;
|
||||
}
|
||||
this._frames.set(framePayload.id, frame);
|
||||
this._mainFrame = frame;
|
||||
|
@ -321,7 +321,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._navigated(framePayload.url, framePayload.name);
|
||||
|
||||
this.emit(FrameManagerEvents.FrameNavigated, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameNavigated, frame);
|
||||
this._page.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
async _ensureIsolatedWorld(name: string) {
|
||||
|
@ -346,7 +346,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._navigated(url, frame.name());
|
||||
this.emit(FrameManagerEvents.FrameNavigatedWithinDocument, frame);
|
||||
this.emit(FrameManagerEvents.FrameNavigated, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameNavigated, frame);
|
||||
this._page.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onFrameDetached(frameId: string) {
|
||||
|
@ -355,16 +355,16 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
this._removeFramesRecursively(frame);
|
||||
}
|
||||
|
||||
_onExecutionContextCreated(contextPayload) {
|
||||
_onExecutionContextCreated(contextPayload: Protocol.Runtime.ExecutionContextDescription) {
|
||||
const frameId = contextPayload.auxData ? contextPayload.auxData.frameId : null;
|
||||
const frame = this._frames.get(frameId) || null;
|
||||
if (contextPayload.auxData && contextPayload.auxData['type'] === 'isolated')
|
||||
if (contextPayload.auxData && contextPayload.auxData.type === 'isolated')
|
||||
this._isolatedWorlds.add(contextPayload.name);
|
||||
const context = new js.ExecutionContext(new ExecutionContextDelegate(this._client, contextPayload));
|
||||
if (frame)
|
||||
context._domWorld = new dom.DOMWorld(context, new DOMWorldDelegate(this, frame));
|
||||
if (frame) {
|
||||
if (contextPayload.auxData && !!contextPayload.auxData['isDefault'])
|
||||
if (contextPayload.auxData && !!contextPayload.auxData.isDefault)
|
||||
frame._contextCreated('main', context);
|
||||
else if (contextPayload.name === UTILITY_WORLD_NAME)
|
||||
frame._contextCreated('utility', context);
|
||||
|
@ -398,7 +398,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._detach();
|
||||
this._frames.delete(this._frameData(frame).id);
|
||||
this.emit(FrameManagerEvents.FrameDetached, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameDetached, frame);
|
||||
this._page.emit(Events.Page.FrameDetached, frame);
|
||||
}
|
||||
|
||||
async _onConsoleAPI(event: Protocol.Runtime.consoleAPICalledPayload) {
|
||||
|
@ -435,7 +435,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
}
|
||||
|
||||
_onDialog(event : Protocol.Page.javascriptDialogOpeningPayload) {
|
||||
this._page.emit(CommonEvents.Page.Dialog, new dialog.Dialog(
|
||||
this._page.emit(Events.Page.Dialog, new dialog.Dialog(
|
||||
event.type as dialog.DialogType,
|
||||
event.message,
|
||||
async (accept: boolean, promptText?: string) => {
|
||||
|
@ -445,7 +445,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
}
|
||||
|
||||
_handleException(exceptionDetails: Protocol.Runtime.ExceptionDetails) {
|
||||
this._page.emit(CommonEvents.Page.PageError, exceptionToError(exceptionDetails));
|
||||
this._page.emit(Events.Page.PageError, exceptionToError(exceptionDetails));
|
||||
}
|
||||
|
||||
_onTargetCrashed() {
|
||||
|
@ -457,7 +457,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
if (args)
|
||||
args.map(arg => releaseObject(this._client, arg));
|
||||
if (source !== 'worker')
|
||||
this._page.emit(CommonEvents.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber}));
|
||||
this._page.emit(Events.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber}));
|
||||
}
|
||||
|
||||
async _onFileChooserOpened(event: Protocol.Page.fileChooserOpenedPayload) {
|
||||
|
@ -550,8 +550,8 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
}
|
||||
}
|
||||
|
||||
function assertNoLegacyNavigationOptions(options) {
|
||||
assert(options['networkIdleTimeout'] === undefined, 'ERROR: networkIdleTimeout option is no longer supported.');
|
||||
assert(options['networkIdleInflight'] === undefined, 'ERROR: networkIdleInflight option is no longer supported.');
|
||||
assert(options.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead');
|
||||
function assertNoLegacyNavigationOptions(options: frames.NavigateOptions) {
|
||||
assert((options as any)['networkIdleTimeout'] === undefined, 'ERROR: networkIdleTimeout option is no longer supported.');
|
||||
assert((options as any)['networkIdleInflight'] === undefined, 'ERROR: networkIdleInflight option is no longer supported.');
|
||||
assert((options as any).waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead');
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import { assert, debugError, helper } from '../helper';
|
|||
import * as types from '../types';
|
||||
import { PipeTransport } from './PipeTransport';
|
||||
import { WebSocketTransport } from './WebSocketTransport';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import * as util from 'util';
|
||||
|
||||
const mkdtempAsync = helper.promisify(fs.mkdtemp);
|
||||
|
@ -100,7 +100,7 @@ export class Launcher {
|
|||
else
|
||||
chromeArguments.push(...args);
|
||||
|
||||
let temporaryUserDataDir = null;
|
||||
let temporaryUserDataDir: string | null = null;
|
||||
|
||||
if (!chromeArguments.some(argument => argument.startsWith('--remote-debugging-')))
|
||||
chromeArguments.push(pipe ? '--remote-debugging-pipe' : '--remote-debugging-port=0');
|
||||
|
@ -139,7 +139,7 @@ export class Launcher {
|
|||
);
|
||||
|
||||
if (!chromeProcess.pid) {
|
||||
let reject;
|
||||
let reject: (e: Error) => void;
|
||||
const result = new Promise((f, r) => reject = r);
|
||||
chromeProcess.once('error', error => {
|
||||
reject(new Error('Failed to launch browser: ' + error));
|
||||
|
@ -160,7 +160,7 @@ export class Launcher {
|
|||
if (temporaryUserDataDir) {
|
||||
removeFolderAsync(temporaryUserDataDir)
|
||||
.then(() => fulfill())
|
||||
.catch(err => console.error(err));
|
||||
.catch((err: Error) => console.error(err));
|
||||
} else {
|
||||
fulfill();
|
||||
}
|
||||
|
@ -344,7 +344,8 @@ function waitForWSEndpoint(chromeProcess: childProcess.ChildProcess, timeout: nu
|
|||
}
|
||||
|
||||
function getWSEndpoint(browserURL: string): Promise<string> {
|
||||
let resolve, reject;
|
||||
let resolve: (url: string) => void;
|
||||
let reject: (e: Error) => void;
|
||||
const promise = new Promise<string>((res, rej) => { resolve = res; reject = rej; });
|
||||
|
||||
const endpointURL = URL.resolve(browserURL, '/json/version');
|
||||
|
@ -423,7 +424,7 @@ export function createBrowserFetcher(projectRoot: string, options: BrowserFetche
|
|||
...defaultOptions,
|
||||
...options,
|
||||
};
|
||||
assert(!!downloadURLs[options.platform], 'Unsupported platform: ' + options.platform);
|
||||
assert(!!(downloadURLs as any)[options.platform], 'Unsupported platform: ' + options.platform);
|
||||
|
||||
return new BrowserFetcher(options.path, options.platform, (platform: string, revision: string) => {
|
||||
let archiveName = '';
|
||||
|
@ -440,7 +441,7 @@ export function createBrowserFetcher(projectRoot: string, options: BrowserFetche
|
|||
executablePath = path.join(archiveName, 'chrome.exe');
|
||||
}
|
||||
return {
|
||||
downloadUrl: util.format(downloadURLs[platform], options.host, revision, archiveName),
|
||||
downloadUrl: util.format((downloadURLs as any)[platform], options.host, revision, archiveName),
|
||||
executablePath
|
||||
};
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
import { CDPSessionEvents } from './Connection';
|
||||
import { TimeoutError } from '../Errors';
|
||||
import { FrameManager, FrameManagerEvents } from './FrameManager';
|
||||
import { assert, helper, RegisteredListener } from '../helper';
|
||||
import { helper, RegisteredListener } from '../helper';
|
||||
import { NetworkManagerEvents } from './NetworkManager';
|
||||
import * as frames from '../frames';
|
||||
import * as network from '../network';
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class Multimap<T, V> {
|
||||
private _map: Map<T, Set<V>>;
|
||||
|
||||
constructor() {
|
||||
this._map = new Map();
|
||||
}
|
||||
|
||||
set(key: T, value: V) {
|
||||
let set = this._map.get(key);
|
||||
if (!set) {
|
||||
set = new Set();
|
||||
this._map.set(key, set);
|
||||
}
|
||||
set.add(value);
|
||||
}
|
||||
|
||||
get(key: T): Set<V> {
|
||||
let result = this._map.get(key);
|
||||
if (!result)
|
||||
result = new Set();
|
||||
return result;
|
||||
}
|
||||
|
||||
has(key: T): boolean {
|
||||
return this._map.has(key);
|
||||
}
|
||||
|
||||
hasValue(key: T, value: V): boolean {
|
||||
const set = this._map.get(key);
|
||||
if (!set)
|
||||
return false;
|
||||
return set.has(value);
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this._map.size;
|
||||
}
|
||||
|
||||
delete(key: T, value: V): boolean {
|
||||
const values = this.get(key);
|
||||
const result = values.delete(value);
|
||||
if (!values.size)
|
||||
this._map.delete(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
deleteAll(key: T) {
|
||||
this._map.delete(key);
|
||||
}
|
||||
|
||||
firstValue(key: T): V {
|
||||
const set = this._map.get(key);
|
||||
if (!set)
|
||||
return null;
|
||||
return set.values().next().value;
|
||||
}
|
||||
|
||||
firstKey(): T {
|
||||
return this._map.keys().next().value;
|
||||
}
|
||||
|
||||
valuesArray(): V[] {
|
||||
const result = [];
|
||||
for (const key of this._map.keys())
|
||||
result.push(...Array.from(this._map.get(key).values()));
|
||||
return result;
|
||||
}
|
||||
|
||||
keysArray(): T[] {
|
||||
return Array.from(this._map.keys());
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._map.clear();
|
||||
}
|
||||
}
|
|
@ -337,7 +337,7 @@ class InterceptableRequest {
|
|||
await this._client.send('Fetch.fulfillRequest', {
|
||||
requestId: this._interceptionId,
|
||||
responseCode: response.status || 200,
|
||||
responsePhrase: STATUS_TEXTS[response.status || 200],
|
||||
responsePhrase: STATUS_TEXTS[String(response.status || 200)],
|
||||
responseHeaders: headersArray(responseHeaders),
|
||||
body: responseBody ? responseBody.toString('base64') : undefined,
|
||||
}).catch(error => {
|
||||
|
@ -367,7 +367,7 @@ class InterceptableRequest {
|
|||
}
|
||||
}
|
||||
|
||||
const errorReasons = {
|
||||
const errorReasons: { [reason: string]: Protocol.Network.ErrorReason } = {
|
||||
'aborted': 'Aborted',
|
||||
'accessdenied': 'AccessDenied',
|
||||
'addressunreachable': 'AddressUnreachable',
|
||||
|
@ -401,7 +401,7 @@ function headersObject(headers: Protocol.Network.Headers): network.Headers {
|
|||
}
|
||||
|
||||
// List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes.
|
||||
const STATUS_TEXTS = {
|
||||
const STATUS_TEXTS: { [status: string]: string } = {
|
||||
'100': 'Continue',
|
||||
'101': 'Switching Protocols',
|
||||
'102': 'Processing',
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { debugError, helper, RegisteredListener } from '../helper';
|
||||
|
||||
export class PipeTransport implements ConnectionTransport {
|
||||
|
|
|
@ -14,13 +14,16 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Browser } from './Browser';
|
||||
import { BrowserFetcher, BrowserFetcherOptions, BrowserFetcherRevisionInfo, OnProgressCallback } from '../browserFetcher';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { DeviceDescriptors } from '../DeviceDescriptors';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { DeviceDescriptors, DeviceDescriptor } from '../DeviceDescriptors';
|
||||
import * as Errors from '../Errors';
|
||||
import { Launcher, LauncherBrowserOptions, LauncherChromeArgOptions, LauncherLaunchOptions, createBrowserFetcher } from './Launcher';
|
||||
|
||||
type Devices = { [name: string]: DeviceDescriptor } & DeviceDescriptor[];
|
||||
|
||||
export class Playwright {
|
||||
private _projectRoot: string;
|
||||
private _launcher: Launcher;
|
||||
|
@ -54,8 +57,8 @@ export class Playwright {
|
|||
return this._launcher.executablePath();
|
||||
}
|
||||
|
||||
get devices(): any {
|
||||
const result = DeviceDescriptors.slice();
|
||||
get devices(): Devices {
|
||||
const result = DeviceDescriptors.slice() as Devices;
|
||||
for (const device of DeviceDescriptors)
|
||||
result[device.name] = device;
|
||||
return result;
|
||||
|
|
|
@ -19,7 +19,7 @@ import * as types from '../types';
|
|||
import { Browser } from './Browser';
|
||||
import { BrowserContext } from './BrowserContext';
|
||||
import { CDPSession, CDPSessionEvents } from './Connection';
|
||||
import { Events as CommonEvents } from '../events';
|
||||
import { Events } from '../events';
|
||||
import { Worker } from './features/workers';
|
||||
import { Page } from '../page';
|
||||
import { Protocol } from './protocol';
|
||||
|
@ -65,10 +65,10 @@ export class Target {
|
|||
if (!opener || !opener._pagePromise || this.type() !== 'page')
|
||||
return true;
|
||||
const openerPage = await opener._pagePromise;
|
||||
if (!openerPage.listenerCount(CommonEvents.Page.Popup))
|
||||
if (!openerPage.listenerCount(Events.Page.Popup))
|
||||
return true;
|
||||
const popupPage = await this.page();
|
||||
openerPage.emit(CommonEvents.Page.Popup, popupPage);
|
||||
openerPage.emit(Events.Page.Popup, popupPage);
|
||||
return true;
|
||||
});
|
||||
this._isInitialized = this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
|
||||
|
@ -87,7 +87,7 @@ export class Target {
|
|||
const frameManager = new FrameManager(client, this._browserContext, this._ignoreHTTPSErrors);
|
||||
const page = frameManager.page();
|
||||
this._page = page;
|
||||
page[targetSymbol] = this;
|
||||
(page as any)[targetSymbol] = this;
|
||||
client.once(CDPSessionEvents.Disconnected, () => page._didDisconnect());
|
||||
client.on('Target.attachedToTarget', event => {
|
||||
if (event.targetInfo.type !== 'worker') {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
import * as WebSocket from 'ws';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
|
||||
export class WebSocketTransport implements ConnectionTransport {
|
||||
private _ws: WebSocket;
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true
|
||||
},
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
|
@ -20,6 +20,7 @@ import { assert, helper, RegisteredListener } from '../helper';
|
|||
import { filterCookies, NetworkCookie, SetNetworkCookieParam, rewriteCookies } from '../network';
|
||||
import { Connection, ConnectionEvents, JugglerSessionEvents } from './Connection';
|
||||
import { Events } from './events';
|
||||
import { Events as CommonEvents } from '../events';
|
||||
import { Permissions } from './features/permissions';
|
||||
import { Page } from '../page';
|
||||
import * as types from '../types';
|
||||
|
@ -164,9 +165,9 @@ export class Browser extends EventEmitter {
|
|||
this._targets.set(targetId, target);
|
||||
if (target.opener() && target.opener()._pagePromise) {
|
||||
const openerPage = await target.opener()._pagePromise;
|
||||
if (openerPage.listenerCount(Events.Page.Popup)) {
|
||||
if (openerPage.listenerCount(CommonEvents.Page.Popup)) {
|
||||
const popupPage = await target.page();
|
||||
openerPage.emit(Events.Page.Popup, popupPage);
|
||||
openerPage.emit(CommonEvents.Page.Popup, popupPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
import {assert} from '../helper';
|
||||
import {EventEmitter} from 'events';
|
||||
import * as debug from 'debug';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { Protocol } from './protocol';
|
||||
const debugProtocol = debug('playwright:protocol');
|
||||
|
||||
|
|
|
@ -27,8 +27,7 @@ import { NavigationWatchdog, NextNavigationWatchdog } from './NavigationWatchdog
|
|||
import { Page, PageDelegate } from '../page';
|
||||
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
|
||||
import { DOMWorldDelegate } from './JSHandle';
|
||||
import { Events } from './events';
|
||||
import { Events as CommonEvents } from '../events';
|
||||
import { Events } from '../events';
|
||||
import * as dialog from '../dialog';
|
||||
import { Protocol } from './protocol';
|
||||
import * as input from '../input';
|
||||
|
@ -89,10 +88,10 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
helper.addEventListener(this._session, 'Page.dialogOpened', this._onDialogOpened.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.bindingCalled', this._onBindingCalled.bind(this)),
|
||||
helper.addEventListener(this._session, 'Page.fileChooserOpened', this._onFileChooserOpened.bind(this)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.Request, request => this._page.emit(CommonEvents.Page.Request, request)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.Response, response => this._page.emit(CommonEvents.Page.Response, response)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.RequestFinished, request => this._page.emit(CommonEvents.Page.RequestFinished, request)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.RequestFailed, request => this._page.emit(CommonEvents.Page.RequestFailed, request)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.Request, request => this._page.emit(Events.Page.Request, request)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.Response, response => this._page.emit(Events.Page.Response, response)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.RequestFinished, request => this._page.emit(Events.Page.RequestFinished, request)),
|
||||
helper.addEventListener(this._networkManager, NetworkManagerEvents.RequestFailed, request => this._page.emit(Events.Page.RequestFailed, request)),
|
||||
];
|
||||
this._page = new Page(this, browserContext);
|
||||
(this._page as any).interception = new Interception(this._networkManager);
|
||||
|
@ -164,14 +163,14 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
data.lastCommittedNavigationId = params.navigationId;
|
||||
frame._firedLifecycleEvents.clear();
|
||||
this.emit(FrameManagerEvents.FrameNavigated, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameNavigated, frame);
|
||||
this._page.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onSameDocumentNavigation(params) {
|
||||
const frame = this._frames.get(params.frameId);
|
||||
frame._navigated(params.url, frame.name());
|
||||
this.emit(FrameManagerEvents.FrameNavigated, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameNavigated, frame);
|
||||
this._page.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onFrameAttached(params) {
|
||||
|
@ -188,7 +187,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
}
|
||||
this._frames.set(params.frameId, frame);
|
||||
this.emit(FrameManagerEvents.FrameAttached, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameAttached, frame);
|
||||
this._page.emit(Events.Page.FrameAttached, frame);
|
||||
}
|
||||
|
||||
_onFrameDetached(params) {
|
||||
|
@ -196,7 +195,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
this._frames.delete(params.frameId);
|
||||
frame._detach();
|
||||
this.emit(FrameManagerEvents.FrameDetached, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameDetached, frame);
|
||||
this._page.emit(Events.Page.FrameDetached, frame);
|
||||
}
|
||||
|
||||
_onEventFired({frameId, name}) {
|
||||
|
@ -205,14 +204,14 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._firedLifecycleEvents.add('load');
|
||||
if (frame === this._mainFrame) {
|
||||
this.emit(FrameManagerEvents.Load);
|
||||
this._page.emit(CommonEvents.Page.Load);
|
||||
this._page.emit(Events.Page.Load);
|
||||
}
|
||||
}
|
||||
if (name === 'DOMContentLoaded') {
|
||||
frame._firedLifecycleEvents.add('domcontentloaded');
|
||||
if (frame === this._mainFrame) {
|
||||
this.emit(FrameManagerEvents.DOMContentLoaded);
|
||||
this._page.emit(CommonEvents.Page.DOMContentLoaded);
|
||||
this._page.emit(Events.Page.DOMContentLoaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
*/
|
||||
import { Browser } from './Browser';
|
||||
import { BrowserFetcher, BrowserFetcherOptions, OnProgressCallback, BrowserFetcherRevisionInfo } from '../browserFetcher';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { DeviceDescriptors } from '../DeviceDescriptors';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { DeviceDescriptors, DeviceDescriptor } from '../DeviceDescriptors';
|
||||
import * as Errors from '../Errors';
|
||||
import { Launcher, createBrowserFetcher } from './Launcher';
|
||||
|
||||
type Devices = { [name: string]: DeviceDescriptor } & DeviceDescriptor[];
|
||||
|
||||
export class Playwright {
|
||||
private _projectRoot: string;
|
||||
private _launcher: Launcher;
|
||||
|
@ -54,8 +56,8 @@ export class Playwright {
|
|||
return this._launcher.executablePath();
|
||||
}
|
||||
|
||||
get devices(): any {
|
||||
const result = DeviceDescriptors.slice();
|
||||
get devices(): Devices {
|
||||
const result = DeviceDescriptors.slice() as Devices;
|
||||
for (const device of DeviceDescriptors)
|
||||
result[device.name] = device;
|
||||
return result;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import * as WebSocket from 'ws';
|
||||
|
||||
export class WebSocketTransport implements ConnectionTransport {
|
||||
|
|
|
@ -16,26 +16,6 @@
|
|||
*/
|
||||
|
||||
export const Events = {
|
||||
Page: {
|
||||
Close: 'close',
|
||||
Console: 'console',
|
||||
Dialog: 'dialog',
|
||||
FileChooser: 'filechooser',
|
||||
DOMContentLoaded: 'domcontentloaded',
|
||||
// Can't use just 'error' due to node.js special treatment of error events.
|
||||
// @see https://nodejs.org/api/events.html#events_error_events
|
||||
PageError: 'pageerror',
|
||||
Request: 'request',
|
||||
Response: 'response',
|
||||
RequestFailed: 'requestfailed',
|
||||
RequestFinished: 'requestfinished',
|
||||
FrameAttached: 'frameattached',
|
||||
FrameDetached: 'framedetached',
|
||||
FrameNavigated: 'framenavigated',
|
||||
Load: 'load',
|
||||
Popup: 'popup',
|
||||
},
|
||||
|
||||
Browser: {
|
||||
Disconnected: 'disconnected'
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ class Injected {
|
|||
|
||||
querySelector(selector: string, root: Node): Element | undefined {
|
||||
const parsed = this._parseSelector(selector);
|
||||
if (!root['querySelector'])
|
||||
if (!(root as any)['querySelector'])
|
||||
throw new Error('Node is not queryable.');
|
||||
let element = root as SelectorRoot;
|
||||
for (const { engine, selector } of parsed) {
|
||||
|
@ -33,7 +33,7 @@ class Injected {
|
|||
|
||||
querySelectorAll(selector: string, root: Node): Element[] {
|
||||
const parsed = this._parseSelector(selector);
|
||||
if (!root['querySelectorAll'])
|
||||
if (!(root as any)['querySelectorAll'])
|
||||
throw new Error('Node is not queryable.');
|
||||
let set = new Set<SelectorRoot>([ root as SelectorRoot ]);
|
||||
for (const { engine, selector } of parsed) {
|
||||
|
@ -105,7 +105,7 @@ class Injected {
|
|||
if (success)
|
||||
return Promise.resolve(success);
|
||||
|
||||
let fulfill;
|
||||
let fulfill: (result?: any) => void;
|
||||
const result = new Promise(x => fulfill = x);
|
||||
const observer = new MutationObserver(mutations => {
|
||||
if (timedOut) {
|
||||
|
@ -131,7 +131,7 @@ class Injected {
|
|||
if (timeout)
|
||||
setTimeout(() => timedOut = true, timeout);
|
||||
|
||||
let fulfill;
|
||||
let fulfill: (result?: any) => void;
|
||||
const result = new Promise(x => fulfill = x);
|
||||
onRaf();
|
||||
return result;
|
||||
|
@ -154,7 +154,7 @@ class Injected {
|
|||
if (timeout)
|
||||
setTimeout(() => timedOut = true, timeout);
|
||||
|
||||
let fulfill;
|
||||
let fulfill: (result?: any) => void;
|
||||
const result = new Promise(x => fulfill = x);
|
||||
onTimeout();
|
||||
return result;
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true
|
||||
},
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
|
@ -62,4 +62,11 @@ export type Viewport = {
|
|||
isMobile?: boolean;
|
||||
isLandscape?: boolean;
|
||||
hasTouch?: boolean;
|
||||
};
|
||||
|
||||
export interface ConnectionTransport {
|
||||
send(s: string): void;
|
||||
close(): void;
|
||||
onmessage?: (message: string) => void,
|
||||
onclose?: () => void,
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
import {assert} from '../helper';
|
||||
import * as debug from 'debug';
|
||||
import {EventEmitter} from 'events';
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { Protocol } from './protocol';
|
||||
|
||||
const debugProtocol = debug('playwright:protocol');
|
||||
|
|
|
@ -23,8 +23,7 @@ import * as js from '../javascript';
|
|||
import * as dom from '../dom';
|
||||
import * as network from '../network';
|
||||
import { TargetSession, TargetSessionEvents } from './Connection';
|
||||
import { Events } from './events';
|
||||
import { Events as CommonEvents } from '../events';
|
||||
import { Events } from '../events';
|
||||
import { ExecutionContextDelegate, EVALUATION_SCRIPT_URL } from './ExecutionContext';
|
||||
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
|
||||
import { Page, PageDelegate } from '../page';
|
||||
|
@ -78,10 +77,10 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
this._contextIdToContext = new Map();
|
||||
this._isolatedWorlds = new Set();
|
||||
this._page = new Page(this, browserContext);
|
||||
this._networkManager.on(NetworkManagerEvents.Request, event => this._page.emit(CommonEvents.Page.Request, event));
|
||||
this._networkManager.on(NetworkManagerEvents.Response, event => this._page.emit(CommonEvents.Page.Response, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFailed, event => this._page.emit(CommonEvents.Page.RequestFailed, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFinished, event => this._page.emit(CommonEvents.Page.RequestFinished, event));
|
||||
this._networkManager.on(NetworkManagerEvents.Request, event => this._page.emit(Events.Page.Request, event));
|
||||
this._networkManager.on(NetworkManagerEvents.Response, event => this._page.emit(Events.Page.Response, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFailed, event => this._page.emit(Events.Page.RequestFailed, event));
|
||||
this._networkManager.on(NetworkManagerEvents.RequestFinished, event => this._page.emit(Events.Page.RequestFinished, event));
|
||||
}
|
||||
|
||||
async initialize(session: TargetSession) {
|
||||
|
@ -128,9 +127,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
helper.addEventListener(this._session, 'Page.loadEventFired', event => this._onLifecycleEvent(event.frameId, 'load')),
|
||||
helper.addEventListener(this._session, 'Page.domContentEventFired', event => this._onLifecycleEvent(event.frameId, 'domcontentloaded')),
|
||||
helper.addEventListener(this._session, 'Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context)),
|
||||
helper.addEventListener(this._session, 'Page.loadEventFired', event => this._page.emit(Events.Page.Load)),
|
||||
helper.addEventListener(this._session, 'Console.messageAdded', event => this._onConsoleMessage(event)),
|
||||
helper.addEventListener(this._session, 'Page.domContentEventFired', event => this._page.emit(Events.Page.DOMContentLoaded)),
|
||||
helper.addEventListener(this._session, 'Dialog.javascriptDialogOpening', event => this._onDialog(event)),
|
||||
helper.addEventListener(this._session, 'Page.fileChooserOpened', event => this._onFileChooserOpened(event))
|
||||
];
|
||||
|
@ -158,9 +155,9 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._firedLifecycleEvents.add('load');
|
||||
this.emit(FrameManagerEvents.LifecycleEvent, frame);
|
||||
if (frame === this.mainFrame() && !hasDOMContentLoaded)
|
||||
this._page.emit(CommonEvents.Page.DOMContentLoaded);
|
||||
this._page.emit(Events.Page.DOMContentLoaded);
|
||||
if (frame === this.mainFrame() && !hasLoad)
|
||||
this._page.emit(CommonEvents.Page.Load);
|
||||
this._page.emit(Events.Page.Load);
|
||||
}
|
||||
|
||||
_onLifecycleEvent(frameId: string, event: frames.LifecycleEvent) {
|
||||
|
@ -171,9 +168,9 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
this.emit(FrameManagerEvents.LifecycleEvent, frame);
|
||||
if (frame === this.mainFrame()) {
|
||||
if (event === 'load')
|
||||
this._page.emit(CommonEvents.Page.Load);
|
||||
this._page.emit(Events.Page.Load);
|
||||
if (event === 'domcontentloaded')
|
||||
this._page.emit(CommonEvents.Page.DOMContentLoaded);
|
||||
this._page.emit(Events.Page.DOMContentLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +218,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame[frameDataSymbol] = data;
|
||||
this._frames.set(frameId, frame);
|
||||
this.emit(FrameManagerEvents.FrameAttached, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameAttached, frame);
|
||||
this._page.emit(Events.Page.FrameAttached, frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
@ -273,7 +270,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
}
|
||||
|
||||
this.emit(FrameManagerEvents.FrameNavigated, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameNavigated, frame);
|
||||
this._page.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onFrameNavigatedWithinDocument(frameId: string, url: string) {
|
||||
|
@ -283,7 +280,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._navigated(url, frame.name());
|
||||
this.emit(FrameManagerEvents.FrameNavigatedWithinDocument, frame);
|
||||
this.emit(FrameManagerEvents.FrameNavigated, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameNavigated, frame);
|
||||
this._page.emit(Events.Page.FrameNavigated, frame);
|
||||
}
|
||||
|
||||
_onFrameDetached(frameId: string) {
|
||||
|
@ -324,7 +321,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate,
|
|||
frame._detach();
|
||||
this._frames.delete(this._frameData(frame).id);
|
||||
this.emit(FrameManagerEvents.FrameDetached, frame);
|
||||
this._page.emit(CommonEvents.Page.FrameDetached, frame);
|
||||
this._page.emit(Events.Page.FrameDetached, frame);
|
||||
}
|
||||
|
||||
async navigateFrame(frame: frames.Frame, url: string, options: frames.GotoOptions = {}): Promise<network.Response | null> {
|
||||
|
@ -589,7 +586,7 @@ class NextNavigationWatchdog {
|
|||
|
||||
_registerDisconnectedListener() {
|
||||
if (this._disconnectedListener)
|
||||
helper.removeEventListeners([this._disconnectedListener]);
|
||||
helper.removeEventListeners([this._disconnectedListener]);
|
||||
const session = this._frameManager._session;
|
||||
this._disconnectedListener = helper.addEventListener(this._frameManager._session, TargetSessionEvents.Disconnected, () => {
|
||||
// Session may change on swap out, check that it's current.
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
* Modifications copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export class Multimap<T, V> {
|
||||
private _map: Map<T, Set<V>>;
|
||||
|
||||
constructor() {
|
||||
this._map = new Map();
|
||||
}
|
||||
|
||||
set(key: T, value: V) {
|
||||
let set = this._map.get(key);
|
||||
if (!set) {
|
||||
set = new Set();
|
||||
this._map.set(key, set);
|
||||
}
|
||||
set.add(value);
|
||||
}
|
||||
|
||||
get(key: T): Set<V> {
|
||||
let result = this._map.get(key);
|
||||
if (!result)
|
||||
result = new Set();
|
||||
return result;
|
||||
}
|
||||
|
||||
has(key: T): boolean {
|
||||
return this._map.has(key);
|
||||
}
|
||||
|
||||
hasValue(key: T, value: V): boolean {
|
||||
const set = this._map.get(key);
|
||||
if (!set)
|
||||
return false;
|
||||
return set.has(value);
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this._map.size;
|
||||
}
|
||||
|
||||
delete(key: T, value: V): boolean {
|
||||
const values = this.get(key);
|
||||
const result = values.delete(value);
|
||||
if (!values.size)
|
||||
this._map.delete(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
deleteAll(key: T) {
|
||||
this._map.delete(key);
|
||||
}
|
||||
|
||||
firstValue(key: T): V {
|
||||
const set = this._map.get(key);
|
||||
if (!set)
|
||||
return null;
|
||||
return set.values().next().value;
|
||||
}
|
||||
|
||||
firstKey(): T {
|
||||
return this._map.keys().next().value;
|
||||
}
|
||||
|
||||
valuesArray(): V[] {
|
||||
const result = [];
|
||||
for (const key of this._map.keys())
|
||||
result.push(...Array.from(this._map.get(key).values()));
|
||||
return result;
|
||||
}
|
||||
|
||||
keysArray(): T[] {
|
||||
return Array.from(this._map.keys());
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._map.clear();
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConnectionTransport } from '../ConnectionTransport';
|
||||
import { ConnectionTransport } from '../types';
|
||||
import { debugError, helper, RegisteredListener } from '../helper';
|
||||
|
||||
export class PipeTransport implements ConnectionTransport {
|
||||
|
|
|
@ -16,22 +16,6 @@
|
|||
*/
|
||||
|
||||
export const Events = {
|
||||
Page: {
|
||||
Close: 'close',
|
||||
Console: 'console',
|
||||
Dialog: 'dialog',
|
||||
FileChooser: 'filechooser',
|
||||
DOMContentLoaded: 'domcontentloaded',
|
||||
Request: 'request',
|
||||
Response: 'response',
|
||||
RequestFailed: 'requestfailed',
|
||||
RequestFinished: 'requestfinished',
|
||||
FrameAttached: 'frameattached',
|
||||
FrameDetached: 'framedetached',
|
||||
FrameNavigated: 'framenavigated',
|
||||
Load: 'load',
|
||||
},
|
||||
|
||||
Browser: {
|
||||
Disconnected: 'disconnected'
|
||||
},
|
||||
|
|
|
@ -117,7 +117,7 @@ function checkSources(sources) {
|
|||
function serializeSymbol(symbol, circular = []) {
|
||||
const type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration);
|
||||
const name = symbol.getName();
|
||||
if (symbol.valueDeclaration.dotDotDotToken) {
|
||||
if (symbol.valueDeclaration && symbol.valueDeclaration.dotDotDotToken) {
|
||||
const innerType = serializeType(type.typeArguments ? type.typeArguments[0] : type, circular);
|
||||
innerType.name = '...' + innerType.name;
|
||||
return Documentation.Member.createProperty('...' + name, innerType);
|
||||
|
|
|
@ -113,6 +113,8 @@ function typeOfProperty(property, domain) {
|
|||
return typeOfProperty(property.items, domain) + '[]';
|
||||
case 'integer':
|
||||
return 'number';
|
||||
case 'object':
|
||||
return '{ [key: string]: string }';
|
||||
}
|
||||
return property.type;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче