mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 02:36:01 -10:00
fix(studio): input that carries a point is scaled with a fitted page or refused
This commit is contained in:
1 parent
50c27314e4
commit
a9b47f614f
2 files changed
+55
-5
No files matched your search
@@ -142,10 +142,11 @@ class BrowserViews {
|
||||
send: (method, params) => {
|
||||
if (method === "Emulation.setDeviceMetricsOverride") return this.emulate(entry, params);
|
||||
if (method === "Emulation.clearDeviceMetricsOverride") return this.emulate(entry, null);
|
||||
// The page reads input in the viewport it was told it has; the view
|
||||
// draws that viewport scaled, and a point meant for the page lands
|
||||
// where the page is drawn only after the same scaling.
|
||||
if (method === "Input.dispatchMouseEvent" && entry.scale !== 1) params = { ...params, x: params.x * entry.scale, y: params.y * entry.scale };
|
||||
try {
|
||||
params = scaleInput(method, params, entry.scale);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
if (!method.startsWith("Input.")) return contents.debugger.sendCommand(method, params);
|
||||
entry.synthUntil = Date.now() + 250;
|
||||
return this.wake.run(() => contents.debugger.sendCommand(method, params));
|
||||
@@ -482,6 +483,29 @@ function placement(panel, emulated) {
|
||||
return { at: { x, y, width, height }, scale };
|
||||
}
|
||||
|
||||
// Input that carries a point. The page reads it in the viewport it was told it
|
||||
// has, the view draws that viewport scaled, and a point meant for the page lands
|
||||
// where it is drawn only after the same scaling. The mouse is measured to; the
|
||||
// rest are not, and a point that silently lands elsewhere is worse than a
|
||||
// refusal, so they are refused while the page is scaled.
|
||||
const POINTED_INPUT = new Set([
|
||||
"Input.dispatchTouchEvent",
|
||||
"Input.dispatchDragEvent",
|
||||
"Input.emulateTouchFromMouseEvent",
|
||||
"Input.synthesizeTapGesture",
|
||||
"Input.synthesizeScrollGesture",
|
||||
"Input.synthesizePinchGesture",
|
||||
]);
|
||||
|
||||
function scaleInput(method, params, scale) {
|
||||
if (scale === 1) return params;
|
||||
if (method === "Input.dispatchMouseEvent") return { ...params, x: params.x * scale, y: params.y * scale };
|
||||
if (POINTED_INPUT.has(method)) {
|
||||
throw Object.assign(new Error(`${method} is not available while the page is scaled to fit the panel`), { code: "input_unscaled" });
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function sameRect(a, b) {
|
||||
return !!a && a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
|
||||
}
|
||||
@@ -490,4 +514,4 @@ function validRect(rect) {
|
||||
return rect && [rect.x, rect.y, rect.width, rect.height].every(Number.isFinite) && rect.width > 0 && rect.height > 0;
|
||||
}
|
||||
|
||||
module.exports = { BrowserViews, AGENT_VIEWPORT, LEAVE_LIMIT_MS, placement };
|
||||
module.exports = { BrowserViews, AGENT_VIEWPORT, LEAVE_LIMIT_MS, placement, scaleInput };
|
||||
@@ -2304,6 +2304,32 @@ test("a page given its own viewport is fitted whole into its panel, centred, and
|
||||
assert.deepEqual(placement({ x: 20, y: 20, width: 1400, height: 1000 }, { width: 1280, height: 900 }), { at: { x: 80, y: 70, width: 1280, height: 900 }, scale: 1 });
|
||||
});
|
||||
|
||||
test("input that carries a point is scaled with the page or refused, never sent to the wrong place", () => {
|
||||
const Module = require("node:module");
|
||||
const load = Module._load;
|
||||
Module._load = function (request, ...rest) {
|
||||
if (request === "electron") return { WebContentsView: class {}, session: { fromPartition: () => ({}) } };
|
||||
return load.call(this, request, ...rest);
|
||||
};
|
||||
let scaleInput;
|
||||
try {
|
||||
({ scaleInput } = require("../src/browserviews.js"));
|
||||
} finally {
|
||||
Module._load = load;
|
||||
}
|
||||
const mouse = { type: "mousePressed", x: 1200, y: 800, button: "left" };
|
||||
assert.equal(scaleInput("Input.dispatchMouseEvent", mouse, 1), mouse, "an unscaled page gets the point as it is");
|
||||
assert.deepEqual(scaleInput("Input.dispatchMouseEvent", mouse, 0.5), { type: "mousePressed", x: 600, y: 400, button: "left" });
|
||||
for (const method of ["Input.dispatchTouchEvent", "Input.dispatchDragEvent", "Input.emulateTouchFromMouseEvent", "Input.synthesizeTapGesture", "Input.synthesizeScrollGesture", "Input.synthesizePinchGesture"]) {
|
||||
const params = { x: 10, y: 20, touchPoints: [{ x: 10, y: 20 }] };
|
||||
assert.equal(scaleInput(method, params, 1), params, `${method} passes on an unscaled page`);
|
||||
assert.throws(() => scaleInput(method, params, 0.5), { code: "input_unscaled" }, `${method} must not reach a scaled page unscaled`);
|
||||
}
|
||||
const key = { type: "keyDown", key: "a" };
|
||||
assert.equal(scaleInput("Input.dispatchKeyEvent", key, 0.5), key, "keys carry no point");
|
||||
assert.equal(scaleInput("Input.insertText", { text: "x" }, 0.5).text, "x");
|
||||
});
|
||||
|
||||
test("rewind notice dismissal survives the desktop preference disk round trip", (t) => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "rewind-notice-prefs-"));
|
||||
const file = path.join(dir, "prefs.json");
|
||||
|
||||
Reference in new issue
Block a user