render: unify responsive geometry and inline gradients

This commit is contained in:
SGavrl committed 2026-07-26 11:51:44 +00:00
1 parent 29d0bce3f5
commit 3618549842
16 files changed
+587 -102

No files matched your search

+10 -2
View File
@@ -8907,10 +8907,18 @@ globalThis.__obscura_init = function() {
const scr = _fp('screen');
const sw = scr[0], sh = scr[1];
// The OS screen and the page viewport are different browser concepts.
// Keep the fingerprinted screen, but let the embedding browser provide the
// actual CSS viewport so responsive JavaScript, layout, and screenshots all
// observe the same dimensions.
const vw = Number.isFinite(globalThis.__obscura_viewport_w) && globalThis.__obscura_viewport_w > 0
? globalThis.__obscura_viewport_w : sw;
const vh = Number.isFinite(globalThis.__obscura_viewport_h) && globalThis.__obscura_viewport_h > 0
? globalThis.__obscura_viewport_h : sh - 80;
globalThis.screen = new Screen(sw, sh);
globalThis.visualViewport = { width:sw, height:sh-80, offsetLeft:0, offsetTop:0, scale:1, addEventListener(){}, removeEventListener(){} };
globalThis.visualViewport = { width:vw, height:vh, offsetLeft:0, offsetTop:0, scale:1, addEventListener(){}, removeEventListener(){} };
globalThis.devicePixelRatio = sw >= 2560 ? 2 : 1;
globalThis.innerWidth = sw; globalThis.innerHeight = sh - 80;
globalThis.innerWidth = vw; globalThis.innerHeight = vh;
globalThis.outerWidth = sw; globalThis.outerHeight = sh - 40;
var hwValues = globalThis.__obscura_stealth ? [4, 6, 8, 12, 16] : [2, 4, 6, 8, 12, 16];
+40
View File
@@ -278,6 +278,27 @@ impl ObscuraJsRuntime {
);
}
/// Set the CSS viewport exposed to page JavaScript. This must run before
/// `run_page_init` for navigation-time responsive code; it may also be
/// called later by CDP emulation to update the live window surfaces.
pub fn set_viewport(&mut self, width: f64, height: f64) {
if !width.is_finite() || !height.is_finite() || width <= 0.0 || height <= 0.0 {
return;
}
let _ = self.runtime.execute_script(
"<set-viewport>",
format!(
"globalThis.__obscura_viewport_w={width};\
globalThis.__obscura_viewport_h={height};\
globalThis.innerWidth={width};globalThis.innerHeight={height};\
if(globalThis.visualViewport){{\
globalThis.visualViewport.width={width};\
globalThis.visualViewport.height={height};\
}}",
),
);
}
/// Run __obscura_init() after all per-page properties (UA, platform, stealth, etc.)
/// have been set. Must be called once per page setup, after all set_* methods.
pub fn run_page_init(&mut self) {
@@ -1788,6 +1809,25 @@ mod tests {
assert_eq!(title, serde_json::json!("Test Page"));
}
#[test]
fn explicit_viewport_is_distinct_from_fingerprinted_screen() {
let dom = parse_html("<html><body></body></html>");
let mut rt = ObscuraJsRuntime::new();
rt.set_dom(dom);
rt.set_viewport(1024.0, 768.0);
rt.run_page_init();
let result = rt
.evaluate(
"return [innerWidth, innerHeight, visualViewport.width,\
visualViewport.height, screen.width > 0, screen.height > 0];",
)
.unwrap();
assert_eq!(
result,
serde_json::json!([1024, 768, 1024, 768, true, true])
);
}
#[test]
fn test_document_url() {
let mut rt = setup_runtime("<html><body></body></html>");