1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | class EmulationManager {
|
18 | |
19 |
|
20 |
|
21 | constructor(client) {
|
22 | this._client = client;
|
23 | this._emulatingMobile = false;
|
24 | this._injectedTouchScriptId = null;
|
25 | }
|
26 |
|
27 | |
28 |
|
29 |
|
30 |
|
31 | async emulateViewport(client, viewport) {
|
32 | const mobile = viewport.isMobile || false;
|
33 | const width = viewport.width;
|
34 | const height = viewport.height;
|
35 | const deviceScaleFactor = viewport.deviceScaleFactor || 1;
|
36 | const screenOrientation = viewport.isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' };
|
37 |
|
38 | await Promise.all([
|
39 | this._client.send('Emulation.setDeviceMetricsOverride', { mobile, width, height, deviceScaleFactor, screenOrientation }),
|
40 | this._client.send('Emulation.setTouchEmulationEnabled', {
|
41 | enabled: viewport.hasTouch || false,
|
42 | configuration: viewport.isMobile ? 'mobile' : 'desktop'
|
43 | })
|
44 | ]);
|
45 |
|
46 | let reloadNeeded = false;
|
47 | if (viewport.hasTouch && !this._injectedTouchScriptId) {
|
48 | const source = `(${injectedTouchEventsFunction})()`;
|
49 | this._injectedTouchScriptId = (await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source })).identifier;
|
50 | reloadNeeded = true;
|
51 | } else if (!viewport.hasTouch && this._injectedTouchScriptId) {
|
52 | await this._client.send('Page.removeScriptToEvaluateOnNewDocument', {identifier: this._injectedTouchScriptId});
|
53 | this._injectedTouchScriptId = null;
|
54 | reloadNeeded = true;
|
55 | }
|
56 |
|
57 | if (this._emulatingMobile !== mobile)
|
58 | reloadNeeded = true;
|
59 | this._emulatingMobile = mobile;
|
60 | return reloadNeeded;
|
61 |
|
62 | function injectedTouchEventsFunction() {
|
63 | const touchEvents = ['ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel'];
|
64 |
|
65 | const recepients = [window.__proto__, document.__proto__];
|
66 | for (let i = 0; i < touchEvents.length; ++i) {
|
67 | for (let j = 0; j < recepients.length; ++j) {
|
68 | if (!(touchEvents[i] in recepients[j])) {
|
69 | Object.defineProperty(recepients[j], touchEvents[i], {
|
70 | value: null, writable: true, configurable: true, enumerable: true
|
71 | });
|
72 | }
|
73 | }
|
74 | }
|
75 | }
|
76 | }
|
77 | }
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | module.exports = EmulationManager;
|