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
|
When runtime is embedded in an iframe, the fullscreen control requests
|
||||||
fullscreen on the embedding iframe first when same-origin access is available.
|
fullscreen on the embedding iframe first when same-origin access is available.
|
||||||
For cross-origin wrappers it posts `tour-builder:request-fullscreen` to
|
For cross-origin wrappers it posts `tour-builder:request-fullscreen` to
|
||||||
`window.parent` before attempting child-document fullscreen, because a
|
`window.parent` and, for nested iframe wrappers, `window.top` before attempting
|
||||||
permissions-policy rejection inside the iframe can consume the user activation
|
child-document fullscreen, because a permissions-policy rejection inside the
|
||||||
needed by the parent fallback. If the iframe itself grants fullscreen but the
|
iframe can consume the user activation needed by the parent fallback. If the
|
||||||
parent does not listen for the message, the child-document fullscreen fallback
|
iframe itself grants fullscreen but the parent does not listen for the message,
|
||||||
can still enter fullscreen. Standalone runtime pages use the browser Fullscreen
|
the child-document fullscreen fallback can still enter fullscreen. Standalone
|
||||||
API for the presentation document. Exit attempts post
|
runtime pages use the browser Fullscreen API for the presentation document.
|
||||||
`tour-builder:exit-fullscreen`.
|
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
|
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
|
top-level runtime page can request document fullscreen from a user click, while
|
||||||
a cross-origin iframe normally needs `allow="fullscreen"` / `allowfullscreen`
|
a cross-origin iframe normally needs `allow="fullscreen"` / `allowfullscreen`
|
||||||
or a parent page that handles `tour-builder:request-fullscreen` and fullscreens
|
or a parent/top page that handles `tour-builder:request-fullscreen` and
|
||||||
the iframe element.
|
fullscreens the iframe element.
|
||||||
|
|
||||||
The runtime keeps a local fullscreen-active state after an embedded parent
|
The runtime keeps a local fullscreen-active state after an embedded parent
|
||||||
fullscreen request because the child document may not expose a local
|
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.
|
values fall back to the built-in MDI icons.
|
||||||
Embedded runtime fullscreen requests the embedding iframe first when same-origin
|
Embedded runtime fullscreen requests the embedding iframe first when same-origin
|
||||||
access is available. For cross-origin wrappers it posts
|
access is available. For cross-origin wrappers it posts
|
||||||
`tour-builder:request-fullscreen` to the parent before attempting
|
`tour-builder:request-fullscreen` to the parent and, for nested iframe wrappers,
|
||||||
child-document fullscreen, so a permissions-policy rejection inside the iframe
|
the top window before attempting child-document fullscreen, so a
|
||||||
does not consume the user activation needed by the parent fallback. If the
|
permissions-policy rejection inside the iframe does not consume the user
|
||||||
iframe itself grants fullscreen but the parent does not listen for the message,
|
activation needed by the parent fallback. If the iframe itself grants fullscreen
|
||||||
the child-document fullscreen fallback can still enter fullscreen. Standalone
|
but the parent does not listen for the message, the child-document fullscreen
|
||||||
runtime pages use native document fullscreen. Exit from cross-origin wrapper
|
fallback can still enter fullscreen. Standalone runtime pages use native
|
||||||
fullscreen posts `tour-builder:exit-fullscreen`.
|
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
|
Top-level runtime pages can request document fullscreen from a user click, but
|
||||||
cross-origin iframe embeds normally require `allow="fullscreen"` /
|
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
|
After a parent iframe fullscreen request, `useRuntimeFullscreen` keeps the
|
||||||
fullscreen button in its active state even when the child document does not
|
fullscreen button in its active state even when the child document does not
|
||||||
expose `document.fullscreenElement`; native enter/exit events still clear or set
|
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`:
|
`lib/fullscreen.ts`:
|
||||||
|
|
||||||
- enter standalone: request document fullscreen
|
- enter standalone: request document fullscreen
|
||||||
- enter embedded: request same-origin embedding iframe fullscreen or post parent
|
- enter embedded: request same-origin embedding iframe fullscreen or post
|
||||||
`tour-builder:request-fullscreen`, then fall back to child-document fullscreen
|
`tour-builder:request-fullscreen` to parent/top wrappers, then fall back to
|
||||||
when iframe permissions allow it
|
child-document fullscreen when iframe permissions allow it
|
||||||
- exit: exit native fullscreen when the child document owns it; otherwise post
|
- 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
|
- state: preserve active fullscreen state for parent iframe fullscreen requests
|
||||||
that do not create a child `document.fullscreenElement`
|
that do not create a child `document.fullscreenElement`
|
||||||
- events: listen to both `fullscreenchange` and `webkitfullscreenchange`
|
- 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 () => {
|
test('requestDocumentFullscreen returns parent request when embedded child fullscreen is blocked', async () => {
|
||||||
const calls: string[] = [];
|
const calls: string[] = [];
|
||||||
const parent = {
|
const parent = {
|
||||||
|
|||||||
@ -74,13 +74,16 @@ const requestSameOriginEmbeddingFrameFullscreen =
|
|||||||
const requestParentFullscreen = (source: string): boolean => {
|
const requestParentFullscreen = (source: string): boolean => {
|
||||||
if (!isEmbeddedWindow()) return false;
|
if (!isEmbeddedWindow()) return false;
|
||||||
|
|
||||||
window.parent.postMessage(
|
const message = {
|
||||||
{
|
type: 'tour-builder:request-fullscreen',
|
||||||
type: 'tour-builder:request-fullscreen',
|
source,
|
||||||
source,
|
};
|
||||||
},
|
|
||||||
'*',
|
window.parent.postMessage(message, '*');
|
||||||
);
|
|
||||||
|
if (window.top && window.top !== window.parent) {
|
||||||
|
window.top.postMessage(message, '*');
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -127,13 +130,16 @@ export const requestDocumentFullscreen = async (
|
|||||||
export const requestParentFullscreenExit = (source = 'runtime'): boolean => {
|
export const requestParentFullscreenExit = (source = 'runtime'): boolean => {
|
||||||
if (!isEmbeddedWindow()) return false;
|
if (!isEmbeddedWindow()) return false;
|
||||||
|
|
||||||
window.parent.postMessage(
|
const message = {
|
||||||
{
|
type: 'tour-builder:exit-fullscreen',
|
||||||
type: 'tour-builder:exit-fullscreen',
|
source,
|
||||||
source,
|
};
|
||||||
},
|
|
||||||
'*',
|
window.parent.postMessage(message, '*');
|
||||||
);
|
|
||||||
|
if (window.top && window.top !== window.parent) {
|
||||||
|
window.top.postMessage(message, '*');
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user