added window.top calling for fullscreen mode
This commit is contained in:
parent
0a73efef22
commit
593f1c99c0
@ -80,19 +80,20 @@ sound button, and fullscreen for the fullscreen button.
|
||||
When runtime is embedded in an iframe, the fullscreen control requests
|
||||
fullscreen on the embedding iframe first when same-origin access is available.
|
||||
For cross-origin wrappers it posts `tour-builder:request-fullscreen` to
|
||||
`window.parent` before attempting child-document fullscreen, because a
|
||||
permissions-policy rejection inside the iframe can consume the user activation
|
||||
needed by the parent fallback. If the iframe itself grants fullscreen but the
|
||||
parent does not listen for the message, the child-document fullscreen fallback
|
||||
can still enter fullscreen. Standalone runtime pages use the browser Fullscreen
|
||||
API for the presentation document. Exit attempts post
|
||||
`tour-builder:exit-fullscreen`.
|
||||
`window.parent` and, for nested iframe wrappers, `window.top` before attempting
|
||||
child-document fullscreen, because a permissions-policy rejection inside the
|
||||
iframe can consume the user activation needed by the parent fallback. If the
|
||||
iframe itself grants fullscreen but the parent does not listen for the message,
|
||||
the child-document fullscreen fallback can still enter fullscreen. Standalone
|
||||
runtime pages use the browser Fullscreen API for the presentation document.
|
||||
Exit attempts post `tour-builder:exit-fullscreen` to the same parent/top
|
||||
targets.
|
||||
|
||||
Browser fullscreen is not equivalent for top-level pages and iframes. A
|
||||
top-level runtime page can request document fullscreen from a user click, while
|
||||
a cross-origin iframe normally needs `allow="fullscreen"` / `allowfullscreen`
|
||||
or a parent page that handles `tour-builder:request-fullscreen` and fullscreens
|
||||
the iframe element.
|
||||
or a parent/top page that handles `tour-builder:request-fullscreen` and
|
||||
fullscreens the iframe element.
|
||||
|
||||
The runtime keeps a local fullscreen-active state after an embedded parent
|
||||
fullscreen request because the child document may not expose a local
|
||||
|
||||
@ -167,16 +167,17 @@ Custom icons use each control's `defaultIconUrl` and `activeIconUrl`; empty
|
||||
values fall back to the built-in MDI icons.
|
||||
Embedded runtime fullscreen requests the embedding iframe first when same-origin
|
||||
access is available. For cross-origin wrappers it posts
|
||||
`tour-builder:request-fullscreen` to the parent before attempting
|
||||
child-document fullscreen, so a permissions-policy rejection inside the iframe
|
||||
does not consume the user activation needed by the parent fallback. If the
|
||||
iframe itself grants fullscreen but the parent does not listen for the message,
|
||||
the child-document fullscreen fallback can still enter fullscreen. Standalone
|
||||
runtime pages use native document fullscreen. Exit from cross-origin wrapper
|
||||
fullscreen posts `tour-builder:exit-fullscreen`.
|
||||
`tour-builder:request-fullscreen` to the parent and, for nested iframe wrappers,
|
||||
the top window before attempting child-document fullscreen, so a
|
||||
permissions-policy rejection inside the iframe does not consume the user
|
||||
activation needed by the parent fallback. If the iframe itself grants fullscreen
|
||||
but the parent does not listen for the message, the child-document fullscreen
|
||||
fallback can still enter fullscreen. Standalone runtime pages use native
|
||||
document fullscreen. Exit from cross-origin wrapper fullscreen posts
|
||||
`tour-builder:exit-fullscreen` to the same parent/top targets.
|
||||
Top-level runtime pages can request document fullscreen from a user click, but
|
||||
cross-origin iframe embeds normally require `allow="fullscreen"` /
|
||||
`allowfullscreen` or a parent listener that fullscreens the iframe element.
|
||||
`allowfullscreen` or a parent/top listener that fullscreens the iframe element.
|
||||
After a parent iframe fullscreen request, `useRuntimeFullscreen` keeps the
|
||||
fullscreen button in its active state even when the child document does not
|
||||
expose `document.fullscreenElement`; native enter/exit events still clear or set
|
||||
@ -1231,11 +1232,11 @@ actual browser operations to `runtimeFullscreen.actions.ts` and
|
||||
`lib/fullscreen.ts`:
|
||||
|
||||
- enter standalone: request document fullscreen
|
||||
- enter embedded: request same-origin embedding iframe fullscreen or post parent
|
||||
`tour-builder:request-fullscreen`, then fall back to child-document fullscreen
|
||||
when iframe permissions allow it
|
||||
- enter embedded: request same-origin embedding iframe fullscreen or post
|
||||
`tour-builder:request-fullscreen` to parent/top wrappers, then fall back to
|
||||
child-document fullscreen when iframe permissions allow it
|
||||
- exit: exit native fullscreen when the child document owns it; otherwise post
|
||||
`tour-builder:exit-fullscreen` to the parent wrapper
|
||||
`tour-builder:exit-fullscreen` to parent/top wrappers
|
||||
- state: preserve active fullscreen state for parent iframe fullscreen requests
|
||||
that do not create a child `document.fullscreenElement`
|
||||
- events: listen to both `fullscreenchange` and `webkitfullscreenchange`
|
||||
|
||||
@ -73,6 +73,44 @@ test('requestDocumentFullscreen asks the parent before child fullscreen when emb
|
||||
]);
|
||||
});
|
||||
|
||||
test('requestDocumentFullscreen also asks the top window when embedded in nested frames', async () => {
|
||||
const calls: string[] = [];
|
||||
const parent = {
|
||||
postMessage: (message: unknown, targetOrigin: string) => {
|
||||
calls.push(`parent:${targetOrigin}:${JSON.stringify(message)}`);
|
||||
},
|
||||
};
|
||||
const top = {
|
||||
postMessage: (message: unknown, targetOrigin: string) => {
|
||||
calls.push(`top:${targetOrigin}:${JSON.stringify(message)}`);
|
||||
},
|
||||
};
|
||||
|
||||
setBrowserGlobals({
|
||||
windowValue: {
|
||||
parent,
|
||||
top,
|
||||
frameElement: null,
|
||||
},
|
||||
documentValue: {
|
||||
documentElement: {
|
||||
requestFullscreen: async () => {
|
||||
calls.push('document-fullscreen');
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const entered = await requestDocumentFullscreen('runtime-global-control');
|
||||
|
||||
assert.equal(entered, true);
|
||||
assert.deepEqual(calls, [
|
||||
'parent:*:{"type":"tour-builder:request-fullscreen","source":"runtime-global-control"}',
|
||||
'top:*:{"type":"tour-builder:request-fullscreen","source":"runtime-global-control"}',
|
||||
'document-fullscreen',
|
||||
]);
|
||||
});
|
||||
|
||||
test('requestDocumentFullscreen returns parent request when embedded child fullscreen is blocked', async () => {
|
||||
const calls: string[] = [];
|
||||
const parent = {
|
||||
|
||||
@ -74,13 +74,16 @@ const requestSameOriginEmbeddingFrameFullscreen =
|
||||
const requestParentFullscreen = (source: string): boolean => {
|
||||
if (!isEmbeddedWindow()) return false;
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: 'tour-builder:request-fullscreen',
|
||||
source,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
const message = {
|
||||
type: 'tour-builder:request-fullscreen',
|
||||
source,
|
||||
};
|
||||
|
||||
window.parent.postMessage(message, '*');
|
||||
|
||||
if (window.top && window.top !== window.parent) {
|
||||
window.top.postMessage(message, '*');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
@ -127,13 +130,16 @@ export const requestDocumentFullscreen = async (
|
||||
export const requestParentFullscreenExit = (source = 'runtime'): boolean => {
|
||||
if (!isEmbeddedWindow()) return false;
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: 'tour-builder:exit-fullscreen',
|
||||
source,
|
||||
},
|
||||
'*',
|
||||
);
|
||||
const message = {
|
||||
type: 'tour-builder:exit-fullscreen',
|
||||
source,
|
||||
};
|
||||
|
||||
window.parent.postMessage(message, '*');
|
||||
|
||||
if (window.top && window.top !== window.parent) {
|
||||
window.top.postMessage(message, '*');
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user