@@ -84,6 +84,17 @@ export class ClipperInject extends FrameInjectBase<ClipperInjectOptions> {
8484 this . updateUiSizeAttributes ( ) ;
8585 this . overrideTransformStyles ( document . documentElement ) ;
8686
87+ // The clipper frame is now visible; hide page body from assistive technologies
88+ // so that tools like Voice Access do not number background page controls.
89+ // The frame is appended to <html> (not <body>), so marking <body aria-hidden>
90+ // and inert only hides page content while keeping the clipper iframe accessible.
91+ // aria-hidden removes body from the AT tree; inert also disables pointer events
92+ // so Voice Access cannot enumerate or activate background controls.
93+ if ( document . body ) {
94+ document . body . setAttribute ( "aria-hidden" , "true" ) ;
95+ document . body . setAttribute ( "inert" , "" ) ;
96+ }
97+
8798 this . logger = new CommunicatorLoggerPure ( this . uiCommunicator ) ;
8899
89100 this . updatePageInfo ( ) ;
@@ -316,6 +327,10 @@ export class ClipperInject extends FrameInjectBase<ClipperInjectOptions> {
316327
317328 this . uiCommunicator . registerFunction ( Constants . FunctionKeys . hideUi , ( ) => {
318329 this . frame . style . display = "none" ;
330+ if ( document . body ) {
331+ document . body . removeAttribute ( "aria-hidden" ) ;
332+ document . body . removeAttribute ( "inert" ) ;
333+ }
319334 } ) ;
320335
321336 this . uiCommunicator . registerFunction ( Constants . FunctionKeys . refreshPage , ( ) => {
@@ -375,6 +390,10 @@ export class ClipperInject extends FrameInjectBase<ClipperInjectOptions> {
375390 private toggleClipper ( ) {
376391 if ( this . frame . style . display === "none" ) {
377392 this . frame . style . display = "" ;
393+ if ( document . body ) {
394+ document . body . setAttribute ( "aria-hidden" , "true" ) ;
395+ document . body . setAttribute ( "inert" , "" ) ;
396+ }
378397 }
379398 this . uiCommunicator . callRemoteFunction ( Constants . FunctionKeys . toggleClipper ) ;
380399 }
0 commit comments