@oh-my-pi/pi-coding-agent 16.1.8 → 16.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/cli.js +4621 -3814
- package/dist/types/cli/flag-tables.d.ts +17 -0
- package/dist/types/cli-commands.d.ts +4 -2
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/types.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +13 -0
- package/dist/types/tools/browser/launch.d.ts +5 -0
- package/package.json +12 -12
- package/src/cli/args.ts +0 -1
- package/src/cli/flag-tables.ts +42 -0
- package/src/cli/profile-bootstrap.ts +1 -11
- package/src/cli-commands.ts +48 -3
- package/src/config/model-registry.ts +6 -7
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/lsp/client.ts +39 -25
- package/src/modes/controllers/command-controller.ts +18 -3
- package/src/modes/controllers/mcp-command-controller.ts +40 -12
- package/src/modes/interactive-mode.ts +1 -1
- package/src/modes/types.ts +1 -1
- package/src/session/agent-session.ts +36 -1
- package/src/slash-commands/builtin-registry.ts +24 -66
- package/src/tools/browser/launch.ts +107 -31
- package/src/tools/puppeteer/00_stealth_tampering.txt +16 -35
- package/src/tools/puppeteer/01_stealth_activity.txt +79 -19
- package/src/tools/puppeteer/02_stealth_hairline.txt +57 -11
- package/src/tools/puppeteer/03_stealth_botd.txt +10 -14
- package/src/tools/puppeteer/04_stealth_iframe.txt +156 -63
- package/src/tools/puppeteer/05_stealth_webgl.txt +222 -64
- package/src/tools/puppeteer/06_stealth_screen.txt +255 -67
- package/src/tools/puppeteer/07_stealth_fonts.txt +17 -15
- package/src/tools/puppeteer/08_stealth_audio.txt +32 -20
- package/src/tools/puppeteer/09_stealth_locale.txt +45 -40
- package/src/tools/puppeteer/10_stealth_plugins.txt +12 -8
- package/src/tools/puppeteer/11_stealth_hardware.txt +57 -6
- package/src/tools/puppeteer/12_stealth_codecs.txt +20 -18
- package/src/tools/puppeteer/13_stealth_worker.txt +206 -45
|
@@ -1,75 +1,233 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
const webglPlatformSource =
|
|
2
|
+
String(navigator.userAgentData?.platform || navigator.platform || "") +
|
|
3
|
+
" " +
|
|
4
|
+
String(navigator.userAgent || "");
|
|
5
|
+
const webglPlatformText = webglPlatformSource.toLowerCase();
|
|
6
|
+
const webglPlatformKind = webglPlatformText.includes("android")
|
|
7
|
+
? "android"
|
|
8
|
+
: webglPlatformText.includes("iphone") ||
|
|
9
|
+
webglPlatformText.includes("ipad") ||
|
|
10
|
+
webglPlatformText.includes("ipod")
|
|
11
|
+
? "ios"
|
|
12
|
+
: webglPlatformText.includes("mac")
|
|
13
|
+
? "mac"
|
|
14
|
+
: webglPlatformText.includes("win")
|
|
15
|
+
? "windows"
|
|
16
|
+
: webglPlatformText.includes("cros")
|
|
17
|
+
? "cros"
|
|
18
|
+
: "linux";
|
|
19
|
+
|
|
20
|
+
const webglFallbackProfiles = {
|
|
21
|
+
android: {
|
|
22
|
+
vendor: "Qualcomm",
|
|
23
|
+
renderer: "Adreno (TM) 640",
|
|
24
|
+
},
|
|
25
|
+
ios: {
|
|
26
|
+
vendor: "Apple Inc.",
|
|
27
|
+
renderer: "Apple GPU",
|
|
28
|
+
},
|
|
29
|
+
mac: {
|
|
30
|
+
vendor: "Google Inc. (Intel Inc.)",
|
|
31
|
+
renderer: "ANGLE (Intel Inc., Intel(R) Iris(TM) Plus Graphics 640 OpenGL Engine, OpenGL 4.1)",
|
|
32
|
+
},
|
|
33
|
+
windows: {
|
|
34
|
+
vendor: "Google Inc. (Intel)",
|
|
35
|
+
renderer: "ANGLE (Intel, Intel(R) UHD Graphics 620 Direct3D11 vs_5_0 ps_5_0, D3D11)",
|
|
36
|
+
},
|
|
37
|
+
cros: {
|
|
38
|
+
vendor: "Google Inc. (Intel)",
|
|
39
|
+
renderer: "ANGLE (Intel, Mesa Intel(R) UHD Graphics 620 (KBL GT2), OpenGL 4.6)",
|
|
40
|
+
},
|
|
41
|
+
linux: {
|
|
42
|
+
vendor: "Google Inc. (Intel)",
|
|
43
|
+
renderer: "ANGLE (Intel, Mesa Intel(R) UHD Graphics 620 (KBL GT2), OpenGL 4.6)",
|
|
44
|
+
},
|
|
27
45
|
};
|
|
46
|
+
const webglFallbackProfile = webglFallbackProfiles[webglPlatformKind] || webglFallbackProfiles.linux;
|
|
47
|
+
const webglContextProfiles = new WeakMap();
|
|
48
|
+
const webglIsObjectKey = (value) =>
|
|
49
|
+
(typeof value === "object" && value !== null) || typeof value === "function";
|
|
28
50
|
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
51
|
+
const webglLooksSoftware = (value) => {
|
|
52
|
+
const text = String(value || "").toLowerCase();
|
|
53
|
+
return (
|
|
54
|
+
text.includes("swiftshader") ||
|
|
55
|
+
text.includes("llvmpipe") ||
|
|
56
|
+
text.includes("lavapipe") ||
|
|
57
|
+
text.includes("software") ||
|
|
58
|
+
text.includes("mesa offscreen") ||
|
|
59
|
+
text.includes("google inc. (google)")
|
|
60
|
+
);
|
|
38
61
|
};
|
|
39
62
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
const webglMatchesPlatform = (renderer) => {
|
|
64
|
+
const text = String(renderer || "").toLowerCase();
|
|
65
|
+
if (webglPlatformKind === "windows") {
|
|
66
|
+
return !text.includes("apple") && !text.includes("mesa") && !text.includes("opengl engine");
|
|
67
|
+
}
|
|
68
|
+
if (webglPlatformKind === "mac") {
|
|
69
|
+
return !text.includes("direct3d") && !text.includes("d3d") && !text.includes("mesa");
|
|
70
|
+
}
|
|
71
|
+
if (webglPlatformKind === "android") {
|
|
72
|
+
return (
|
|
73
|
+
text.includes("adreno") ||
|
|
74
|
+
text.includes("mali") ||
|
|
75
|
+
text.includes("powervr") ||
|
|
76
|
+
text.includes("qualcomm")
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (webglPlatformKind === "ios") {
|
|
80
|
+
return text.includes("apple");
|
|
81
|
+
}
|
|
82
|
+
return !text.includes("direct3d") && !text.includes("d3d") && !text.includes("apple");
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const webglGetContextProfile = (target, thisArg) => {
|
|
86
|
+
if (!webglIsObjectKey(thisArg)) return webglFallbackProfile;
|
|
87
|
+
const cached = Reflect_apply(Page_WeakMap_get, webglContextProfiles, [thisArg]);
|
|
88
|
+
if (cached) return cached;
|
|
89
|
+
|
|
90
|
+
let nativeVendor;
|
|
91
|
+
let nativeRenderer;
|
|
92
|
+
try {
|
|
93
|
+
nativeVendor = Reflect_apply(target, thisArg, [0x9245]);
|
|
94
|
+
nativeRenderer = Reflect_apply(target, thisArg, [0x9246]);
|
|
95
|
+
} catch {}
|
|
96
|
+
|
|
97
|
+
const nativeProfile =
|
|
98
|
+
typeof nativeVendor === "string" &&
|
|
99
|
+
typeof nativeRenderer === "string" &&
|
|
100
|
+
nativeVendor &&
|
|
101
|
+
nativeRenderer &&
|
|
102
|
+
!webglLooksSoftware(nativeVendor) &&
|
|
103
|
+
!webglLooksSoftware(nativeRenderer) &&
|
|
104
|
+
webglMatchesPlatform(nativeRenderer)
|
|
105
|
+
? { vendor: nativeVendor, renderer: nativeRenderer }
|
|
106
|
+
: webglFallbackProfile;
|
|
107
|
+
|
|
108
|
+
Reflect_apply(Page_WeakMap_set, webglContextProfiles, [thisArg, nativeProfile]);
|
|
109
|
+
return nativeProfile;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const webglGetParameterHandler = {
|
|
113
|
+
apply(target, thisArg, args) {
|
|
114
|
+
const nativeValue = Reflect_apply(target, thisArg, args);
|
|
115
|
+
const param = args[0];
|
|
116
|
+
if (param === 0x1f00 && typeof nativeValue === "string") return "WebKit";
|
|
117
|
+
if (param === 0x1f01 && typeof nativeValue === "string") return "WebKit WebGL";
|
|
118
|
+
if ((param === 0x9245 || param === 0x9246) && typeof nativeValue === "string") {
|
|
119
|
+
const profile = webglGetContextProfile(target, thisArg);
|
|
120
|
+
return param === 0x9245 ? profile.vendor : profile.renderer;
|
|
121
|
+
}
|
|
122
|
+
return nativeValue;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const webglFloatPrecisionTypes = {
|
|
127
|
+
0x8df0: true,
|
|
128
|
+
0x8df1: true,
|
|
129
|
+
0x8df2: true,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const webglClonePrecisionFormat = (result, values) => {
|
|
133
|
+
const ownKeys = Reflect_ownKeys(result);
|
|
134
|
+
let hasRangeMin = false;
|
|
135
|
+
let hasRangeMax = false;
|
|
136
|
+
let hasPrecision = false;
|
|
137
|
+
for (let index = 0; index < ownKeys.length; index += 1) {
|
|
138
|
+
if (ownKeys[index] === "rangeMin") hasRangeMin = true;
|
|
139
|
+
if (ownKeys[index] === "rangeMax") hasRangeMax = true;
|
|
140
|
+
if (ownKeys[index] === "precision") hasPrecision = true;
|
|
141
|
+
}
|
|
142
|
+
if (!hasRangeMin || !hasRangeMax || !hasPrecision) return result;
|
|
143
|
+
|
|
144
|
+
const clone = Object_create(Object_getPrototypeOf(result));
|
|
145
|
+
for (let index = 0; index < ownKeys.length; index += 1) {
|
|
146
|
+
const key = ownKeys[index];
|
|
147
|
+
const descriptor = Object_getOwnPropertyDescriptor(result, key);
|
|
148
|
+
if (!descriptor) return result;
|
|
149
|
+
if (key === "rangeMin" || key === "rangeMax" || key === "precision") {
|
|
150
|
+
if (!("value" in descriptor)) return result;
|
|
151
|
+
descriptor.value = values[key];
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
Object_defineProperty(clone, key, descriptor);
|
|
155
|
+
} catch {
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return clone;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const webglGetShaderPrecisionFormatHandler = {
|
|
163
|
+
apply(target, thisArg, args) {
|
|
164
|
+
const result = Reflect_apply(target, thisArg, args);
|
|
165
|
+
const precisionType = args[1];
|
|
166
|
+
if (
|
|
167
|
+
!result ||
|
|
168
|
+
webglPlatformKind === "android" ||
|
|
169
|
+
webglPlatformKind === "ios" ||
|
|
170
|
+
!webglFloatPrecisionTypes[precisionType]
|
|
171
|
+
) {
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const rangeMin = result.rangeMin;
|
|
176
|
+
const rangeMax = result.rangeMax;
|
|
177
|
+
const precision = result.precision;
|
|
178
|
+
if (
|
|
179
|
+
typeof rangeMin !== "number" ||
|
|
180
|
+
typeof rangeMax !== "number" ||
|
|
181
|
+
typeof precision !== "number"
|
|
182
|
+
) {
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const values = {
|
|
187
|
+
rangeMin: Math_max(rangeMin, 127),
|
|
188
|
+
rangeMax: Math_max(rangeMax, 127),
|
|
189
|
+
precision: Math_max(precision, 23),
|
|
190
|
+
};
|
|
191
|
+
if (
|
|
192
|
+
values.rangeMin === rangeMin &&
|
|
193
|
+
values.rangeMax === rangeMax &&
|
|
194
|
+
values.precision === precision
|
|
195
|
+
) {
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
return webglClonePrecisionFormat(result, values);
|
|
199
|
+
},
|
|
200
|
+
};
|
|
46
201
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
return result;
|
|
63
|
-
},
|
|
64
|
-
writable: true,
|
|
65
|
-
configurable: true,
|
|
66
|
-
enumerable: true,
|
|
67
|
-
});
|
|
202
|
+
const webglInstallMethodProxy = (proto, name, handler) => {
|
|
203
|
+
if (!proto) return;
|
|
204
|
+
const descriptor = Object_getOwnPropertyDescriptor(proto, name);
|
|
205
|
+
if (!descriptor || typeof descriptor.value !== "function") return;
|
|
206
|
+
const proxy = new Window_Proxy(descriptor.value, handler);
|
|
207
|
+
patchToString(proxy, name);
|
|
208
|
+
try {
|
|
209
|
+
Object_defineProperty(proto, name, {
|
|
210
|
+
value: proxy,
|
|
211
|
+
writable: descriptor.writable,
|
|
212
|
+
configurable: descriptor.configurable,
|
|
213
|
+
enumerable: descriptor.enumerable,
|
|
214
|
+
});
|
|
215
|
+
} catch {}
|
|
68
216
|
};
|
|
69
217
|
|
|
70
218
|
if (window.WebGLRenderingContext) {
|
|
71
|
-
|
|
219
|
+
webglInstallMethodProxy(WebGLRenderingContext.prototype, "getParameter", webglGetParameterHandler);
|
|
220
|
+
webglInstallMethodProxy(
|
|
221
|
+
WebGLRenderingContext.prototype,
|
|
222
|
+
"getShaderPrecisionFormat",
|
|
223
|
+
webglGetShaderPrecisionFormatHandler,
|
|
224
|
+
);
|
|
72
225
|
}
|
|
73
226
|
if (window.WebGL2RenderingContext) {
|
|
74
|
-
|
|
227
|
+
webglInstallMethodProxy(WebGL2RenderingContext.prototype, "getParameter", webglGetParameterHandler);
|
|
228
|
+
webglInstallMethodProxy(
|
|
229
|
+
WebGL2RenderingContext.prototype,
|
|
230
|
+
"getShaderPrecisionFormat",
|
|
231
|
+
webglGetShaderPrecisionFormatHandler,
|
|
232
|
+
);
|
|
75
233
|
}
|
|
@@ -1,72 +1,260 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
;(() => {
|
|
2
|
+
if (typeof Window_Proxy !== "function" || typeof Reflect_apply !== "function") return;
|
|
3
|
+
|
|
4
|
+
const screenObject = window.screen;
|
|
5
|
+
if (!screenObject) return;
|
|
6
|
+
|
|
7
|
+
const isFiniteNumber = (value) =>
|
|
8
|
+
typeof value === "number" &&
|
|
9
|
+
value === value &&
|
|
10
|
+
value !== Infinity &&
|
|
11
|
+
value !== -Infinity;
|
|
12
|
+
|
|
13
|
+
const readValue = (object, prop, fallback) => {
|
|
14
|
+
try {
|
|
15
|
+
const value = object[prop];
|
|
16
|
+
return value === undefined ? fallback : value;
|
|
17
|
+
} catch {
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const finiteNumber = (value, fallback) =>
|
|
23
|
+
isFiniteNumber(value) ? value : fallback;
|
|
24
|
+
|
|
25
|
+
const positiveNumber = (value, fallback) =>
|
|
26
|
+
isFiniteNumber(value) && value > 0 ? value : fallback;
|
|
27
|
+
|
|
28
|
+
const integerNumber = (value, fallback) =>
|
|
29
|
+
isFiniteNumber(value) ? Math_floor(value) : fallback;
|
|
30
|
+
|
|
31
|
+
const positiveInteger = (value, fallback) =>
|
|
32
|
+
isFiniteNumber(value) && value > 0 ? Math_floor(value) : fallback;
|
|
33
|
+
|
|
34
|
+
const findDescriptorOwner = (object, prop) => {
|
|
35
|
+
let owner = object;
|
|
36
|
+
while (owner) {
|
|
37
|
+
let descriptor;
|
|
38
|
+
try {
|
|
39
|
+
descriptor = Object_getOwnPropertyDescriptor(owner, prop);
|
|
40
|
+
} catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
if (descriptor) return [owner, descriptor];
|
|
44
|
+
try {
|
|
45
|
+
owner = Object_getPrototypeOf(owner);
|
|
46
|
+
} catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const patchGetter = (object, prop, getValue) => {
|
|
54
|
+
const found = findDescriptorOwner(object, prop);
|
|
55
|
+
if (!found) return false;
|
|
56
|
+
|
|
57
|
+
const owner = found[0];
|
|
58
|
+
const descriptor = found[1];
|
|
59
|
+
if (descriptor.configurable !== true || typeof descriptor.get !== "function") {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const originalGet = descriptor.get;
|
|
64
|
+
const patchedGet = new Window_Proxy(originalGet, {
|
|
65
|
+
apply(target, thisArg, args) {
|
|
66
|
+
const nativeValue = Reflect_apply(target, thisArg, args);
|
|
67
|
+
return getValue(nativeValue, thisArg);
|
|
68
|
+
},
|
|
16
69
|
});
|
|
17
|
-
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// Override screen properties
|
|
21
|
-
for (const [prop, descriptor] of Object_entries({
|
|
22
|
-
width,
|
|
23
|
-
height,
|
|
24
|
-
availWidth,
|
|
25
|
-
availHeight,
|
|
26
|
-
availLeft: 0,
|
|
27
|
-
availTop: 0,
|
|
28
|
-
colorDepth,
|
|
29
|
-
pixelDepth,
|
|
30
|
-
})) {
|
|
31
|
-
defineScreenProp(prop, descriptor);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Ensure outer dimensions match screen for consistency
|
|
35
|
-
const chromeFrameHeight = 85;
|
|
36
|
-
Object_defineProperty(window, "outerWidth", {
|
|
37
|
-
get: () => window.innerWidth,
|
|
38
|
-
configurable: true,
|
|
39
|
-
enumerable: true,
|
|
40
|
-
});
|
|
41
|
-
Object_defineProperty(window, "outerHeight", {
|
|
42
|
-
get: () => window.innerHeight + chromeFrameHeight,
|
|
43
|
-
configurable: true,
|
|
44
|
-
enumerable: true,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
if (window.visualViewport) {
|
|
48
|
-
const defineVvpProp = (prop, value) => {
|
|
70
|
+
patchToString(patchedGet, "get " + prop);
|
|
49
71
|
try {
|
|
50
|
-
Object_defineProperty(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
72
|
+
Object_defineProperty(owner, prop, {
|
|
73
|
+
configurable: descriptor.configurable,
|
|
74
|
+
enumerable: descriptor.enumerable,
|
|
75
|
+
get: patchedGet,
|
|
76
|
+
set: descriptor.set,
|
|
54
77
|
});
|
|
55
|
-
|
|
78
|
+
return true;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
56
82
|
};
|
|
57
83
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
84
|
+
const patchStableNumber = (object, prop, value) => {
|
|
85
|
+
const current = readValue(object, prop, undefined);
|
|
86
|
+
if (current === value) return;
|
|
87
|
+
patchGetter(object, prop, () => value);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const initialInnerWidth = positiveInteger(readValue(window, "innerWidth", 0), 0);
|
|
91
|
+
const initialInnerHeight = positiveInteger(readValue(window, "innerHeight", 0), 0);
|
|
92
|
+
const initialOuterWidth = positiveInteger(
|
|
93
|
+
readValue(window, "outerWidth", Math_max(initialInnerWidth, 1)),
|
|
94
|
+
Math_max(initialInnerWidth, 1),
|
|
95
|
+
);
|
|
96
|
+
const initialOuterHeight = positiveInteger(
|
|
97
|
+
readValue(window, "outerHeight", Math_max(initialInnerHeight, 1)),
|
|
98
|
+
Math_max(initialInnerHeight, 1),
|
|
99
|
+
);
|
|
100
|
+
// Real Chrome reserves vertical space for the tab strip + URL bar, so
|
|
101
|
+
// outerHeight is always taller than innerHeight (~88px on a stock window).
|
|
102
|
+
// Headless reports outerHeight === innerHeight, which is a well-known tell, so
|
|
103
|
+
// synthesize a realistic chrome height when the window has no visible chrome.
|
|
104
|
+
const browserChromeHeight = 88;
|
|
105
|
+
const targetOuterHeight =
|
|
106
|
+
initialOuterHeight > initialInnerHeight
|
|
107
|
+
? initialOuterHeight
|
|
108
|
+
: initialInnerHeight + browserChromeHeight;
|
|
109
|
+
const requiredWidth = Math_max(initialInnerWidth, initialOuterWidth, 1);
|
|
110
|
+
const requiredHeight = Math_max(initialInnerHeight, initialOuterHeight, targetOuterHeight, 1);
|
|
111
|
+
|
|
112
|
+
const screenWidth = Math_max(
|
|
113
|
+
positiveInteger(readValue(screenObject, "width", requiredWidth), requiredWidth),
|
|
114
|
+
requiredWidth,
|
|
115
|
+
);
|
|
116
|
+
const screenHeight = Math_max(
|
|
117
|
+
positiveInteger(readValue(screenObject, "height", requiredHeight), requiredHeight),
|
|
118
|
+
requiredHeight,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
let screenAvailWidth = positiveInteger(
|
|
122
|
+
readValue(screenObject, "availWidth", screenWidth),
|
|
123
|
+
screenWidth,
|
|
124
|
+
);
|
|
125
|
+
if (screenAvailWidth < requiredWidth || screenAvailWidth > screenWidth) {
|
|
126
|
+
screenAvailWidth = screenWidth;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let screenAvailHeight = positiveInteger(
|
|
130
|
+
readValue(screenObject, "availHeight", screenHeight),
|
|
131
|
+
screenHeight,
|
|
132
|
+
);
|
|
133
|
+
if (screenAvailHeight < requiredHeight || screenAvailHeight > screenHeight) {
|
|
134
|
+
screenAvailHeight = screenHeight;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const screenAvailLeft = integerNumber(readValue(screenObject, "availLeft", 0), 0);
|
|
138
|
+
const screenAvailTop = integerNumber(readValue(screenObject, "availTop", 0), 0);
|
|
139
|
+
const screenColorDepth = positiveInteger(readValue(screenObject, "colorDepth", 24), 24);
|
|
140
|
+
const screenPixelDepth = positiveInteger(
|
|
141
|
+
readValue(screenObject, "pixelDepth", screenColorDepth),
|
|
142
|
+
screenColorDepth,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
for (const entry of [
|
|
146
|
+
["width", screenWidth],
|
|
147
|
+
["height", screenHeight],
|
|
148
|
+
["availWidth", screenAvailWidth],
|
|
149
|
+
["availHeight", screenAvailHeight],
|
|
150
|
+
["availLeft", screenAvailLeft],
|
|
151
|
+
["availTop", screenAvailTop],
|
|
152
|
+
["colorDepth", screenColorDepth],
|
|
153
|
+
["pixelDepth", screenPixelDepth],
|
|
154
|
+
]) {
|
|
155
|
+
patchStableNumber(screenObject, entry[0], entry[1]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const outerWidthNeedsPatch =
|
|
159
|
+
!isFiniteNumber(readValue(window, "outerWidth", undefined)) ||
|
|
160
|
+
readValue(window, "outerWidth", 0) <= 0 ||
|
|
161
|
+
Math_floor(readValue(window, "outerWidth", 0)) < initialInnerWidth;
|
|
162
|
+
if (outerWidthNeedsPatch) {
|
|
163
|
+
patchGetter(window, "outerWidth", (nativeValue) =>
|
|
164
|
+
Math_max(
|
|
165
|
+
positiveInteger(nativeValue, initialOuterWidth),
|
|
166
|
+
positiveInteger(readValue(window, "innerWidth", requiredWidth), requiredWidth),
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const outerHeightNeedsPatch =
|
|
172
|
+
!isFiniteNumber(readValue(window, "outerHeight", undefined)) ||
|
|
173
|
+
readValue(window, "outerHeight", 0) <= 0 ||
|
|
174
|
+
Math_floor(readValue(window, "outerHeight", 0)) <= initialInnerHeight;
|
|
175
|
+
if (outerHeightNeedsPatch) {
|
|
176
|
+
patchGetter(window, "outerHeight", (nativeValue) =>
|
|
177
|
+
Math_max(
|
|
178
|
+
positiveInteger(nativeValue, initialOuterHeight),
|
|
179
|
+
positiveInteger(readValue(window, "innerHeight", requiredHeight), requiredHeight) +
|
|
180
|
+
browserChromeHeight,
|
|
181
|
+
),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const initialDevicePixelRatio = positiveNumber(
|
|
186
|
+
readValue(window, "devicePixelRatio", 1),
|
|
187
|
+
1,
|
|
188
|
+
);
|
|
189
|
+
if (readValue(window, "devicePixelRatio", undefined) !== initialDevicePixelRatio) {
|
|
190
|
+
patchGetter(window, "devicePixelRatio", () => initialDevicePixelRatio);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const visualViewportObject = readValue(window, "visualViewport", null);
|
|
194
|
+
if (visualViewportObject) {
|
|
195
|
+
const initialScale = positiveNumber(readValue(visualViewportObject, "scale", 1), 1);
|
|
196
|
+
if (readValue(visualViewportObject, "scale", undefined) !== initialScale) {
|
|
197
|
+
patchGetter(visualViewportObject, "scale", (nativeValue) =>
|
|
198
|
+
positiveNumber(nativeValue, initialScale),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const getViewportScale = () =>
|
|
203
|
+
positiveNumber(readValue(visualViewportObject, "scale", initialScale), initialScale);
|
|
204
|
+
|
|
205
|
+
const getViewportWidthFallback = () =>
|
|
206
|
+
positiveNumber(readValue(window, "innerWidth", requiredWidth), requiredWidth) /
|
|
207
|
+
getViewportScale();
|
|
208
|
+
|
|
209
|
+
const getViewportHeightFallback = () =>
|
|
210
|
+
positiveNumber(readValue(window, "innerHeight", requiredHeight), requiredHeight) /
|
|
211
|
+
getViewportScale();
|
|
212
|
+
|
|
213
|
+
if (positiveNumber(readValue(visualViewportObject, "width", 0), 0) <= 0) {
|
|
214
|
+
patchGetter(visualViewportObject, "width", (nativeValue) =>
|
|
215
|
+
positiveNumber(nativeValue, getViewportWidthFallback()),
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (positiveNumber(readValue(visualViewportObject, "height", 0), 0) <= 0) {
|
|
220
|
+
patchGetter(visualViewportObject, "height", (nativeValue) =>
|
|
221
|
+
positiveNumber(nativeValue, getViewportHeightFallback()),
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const getViewportOffsetLeft = () =>
|
|
226
|
+
finiteNumber(readValue(visualViewportObject, "offsetLeft", 0), 0);
|
|
227
|
+
const getViewportOffsetTop = () =>
|
|
228
|
+
finiteNumber(readValue(visualViewportObject, "offsetTop", 0), 0);
|
|
229
|
+
|
|
230
|
+
if (!isFiniteNumber(readValue(visualViewportObject, "offsetLeft", undefined))) {
|
|
231
|
+
patchGetter(visualViewportObject, "offsetLeft", (nativeValue) =>
|
|
232
|
+
finiteNumber(nativeValue, 0),
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (!isFiniteNumber(readValue(visualViewportObject, "offsetTop", undefined))) {
|
|
237
|
+
patchGetter(visualViewportObject, "offsetTop", (nativeValue) =>
|
|
238
|
+
finiteNumber(nativeValue, 0),
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!isFiniteNumber(readValue(visualViewportObject, "pageLeft", undefined))) {
|
|
243
|
+
patchGetter(visualViewportObject, "pageLeft", (nativeValue) =>
|
|
244
|
+
finiteNumber(
|
|
245
|
+
nativeValue,
|
|
246
|
+
finiteNumber(readValue(window, "scrollX", 0), 0) + getViewportOffsetLeft(),
|
|
247
|
+
),
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (!isFiniteNumber(readValue(visualViewportObject, "pageTop", undefined))) {
|
|
252
|
+
patchGetter(visualViewportObject, "pageTop", (nativeValue) =>
|
|
253
|
+
finiteNumber(
|
|
254
|
+
nativeValue,
|
|
255
|
+
finiteNumber(readValue(window, "scrollY", 0), 0) + getViewportOffsetTop(),
|
|
256
|
+
),
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
})();
|