okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
7de30f7
main
1"""Explicit session recovery; only acknowledged declarative settings are retained. 2 3This is NOT a command log. Navigation, input, JavaScript, permissions, scripts, 4request interception and event subscriptions must never be replayed here. 5""" 6 7from __future__import annotations 8 9import copy 10import json 11from typing import TYPE_CHECKING 12 13from .errors import ConnectionLost 14from .transport import CDPSession ,JSON 15 16if TYPE_CHECKING : 17from .page import Page 18 19# A closed list, not "anything beginning with Emulation.set". Each entry has 20# replacement semantics. Clear commands share a key with their matching setter. 21SETTINGS = { 22"Emulation.setDeviceMetricsOverride" :"metrics" , 23"Emulation.clearDeviceMetricsOverride" :"metrics" , 24"Emulation.setTouchEmulationEnabled" :"touch" , 25"Emulation.setEmulatedMedia" :"media" , 26"Emulation.setTimezoneOverride" :"timezone" , 27"Emulation.setLocaleOverride" :"locale" , 28"Emulation.setUserAgentOverride" :"user_agent" , 29"Network.setUserAgentOverride" :"user_agent" , 30"Emulation.setGeolocationOverride" :"geolocation" , 31"Emulation.clearGeolocationOverride" :"geolocation" , 32"Emulation.setCPUThrottlingRate" :"cpu" , 33"Emulation.setDefaultBackgroundColorOverride" :"background" , 34"Emulation.setEmulatedVisionDeficiency" :"vision" , 35} 36MAX_SETTINGS_BYTES = 256 * 1024 37 38 39class PageCDPSession (CDPSession ): 40"""Raw CDP plus retention of the documented root-page emulation setters. 41 42Sending still happens exactly once. Settings are saved only after success. 43A saved CDPSession is tied to its original attachment, never silently rebound. 44""" 45 46def __init__ (self ,page :Page ,session_id :str )-> None : 47super ().__init__ (page .browser ._connection ,session_id ) 48self .page = page 49 50async def send ( 51self ,method :str ,params :JSON | None = None ,* ,timeout :float | None = None 52 )-> JSON : 53if self is not self .page .cdp : 54raise ConnectionLost ( 55"This CDP session was replaced; use page.cdp after reattachment." 56 ) 57if method not in SETTINGS : 58return await super ().send (method ,params ,timeout = timeout ) 59# Serialize configuration and reattachment, so a late acknowledgement 60# cannot overwrite a newer intended setting. Copy before the first await. 61payload = copy .deepcopy (params or {}) 62async with self .page ._settings_lock : 63self .page ._check () 64if self is not self .page .cdp : 65raise ConnectionLost ("This CDP session was replaced; use page.cdp." ) 66candidate = dict (self .page ._settings ) 67key = SETTINGS [method ] 68candidate .pop (key ,None ) 69candidate [key ]= {"method" :method ,"params" :payload } 70if ( 71len (json .dumps (candidate ,allow_nan = False ).encode ()) 72> MAX_SETTINGS_BYTES 73 ): 74raise ValueError ( 75"Remembered emulation settings exceed 256 KiB; command was not sent" 76 ) 77result = await super ().send (method ,payload ,timeout = timeout ) 78self .page ._settings = candidate 79return result