Skip to content

fix(util): use own document in toggleFullScreen() - #3552

Merged
kumilingus merged 3 commits into
clientIO:masterfrom
MartinKanera:fix/toggle-fullscreen-cross-origin
Oct 16, 2026
Merged

kumilingus merged 3 commits into
clientIO:masterfrom
MartinKanera:fix/toggle-fullscreen-cross-origin

Conversation

@MartinKanera

@MartinKanera MartinKanera commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

util.toggleFullScreen() read window.top.document, which a cross-origin iframe is not allowed to read. So an app embedded cross-origin got a SecurityError on every call, even when its embedding page allows fullscreen. It now works on the element's own page (el.ownerDocument), or on the current page when no element is given, whose body becomes the default.

Changes

  • util.toggleFullScreen() enters or leaves fullscreen based on the element's own page instead of window.top.document, and without an element it uses the current page's body instead of the top-level page's. The order in which it tries the prefixed and standard names is unchanged.
  • In a same-origin iframe while the embedding page is in fullscreen, an element of the iframe now enters fullscreen on top of it; before, the call exited the embedding page's fullscreen. On a top-level page nothing changes.
  • QUnit tests with a same-origin iframe: an element of the iframe enters fullscreen while the pages around it are in fullscreen, and the iframe's page exits its own fullscreen. Without an element, the current page's body enters fullscreen, and the current page exits its own fullscreen without touching the embedding page.
  • A @joint/core patch changeset.

Verification

  • yarn workspace @joint/core lint: pass
  • yarn workspace @joint/core test: pass (mocha 4/4, Karma joint 2164/2164, geometry 350/350, vectorizer 453/453 with coverage thresholds, qunit, ts:test, ts:test-exports); the 4 new tests fail without the fix.
  • yarn changeset status --since=upstream/master: @joint/core patch
  • Browser check, headless Chrome 140 and Firefox 158 with real clicks: a page on one local origin embeds a page from another in two iframes, and each button calls toggleFullScreen() with and without an element.
    • With allow="fullscreen": a click enters fullscreen and a second click leaves it, with no errors.
    • Without allow: no SecurityError, and nothing enters fullscreen. Chrome stays silent; Firefox rejects with an uncaught TypeError: Fullscreen request denied, as it already does for a refused request on a top-level page.

toggleFullScreen() read window.top.document, which a cross-origin
iframe may not access, so every call there threw a SecurityError. It
now works on the element's ownerDocument, or the current document
without an element, whose body becomes the default.

On a top-level page nothing changes. In a same-origin iframe the
default element is now the iframe's body instead of the top-level
page's, and whether to enter or leave fullscreen follows the iframe's
own fullscreen element.
toggleFullScreen() without an element must leave fullscreen through
the current page when that page reports an element in fullscreen, as
the second call of a toggle does. No test covered that branch; under
Karma it fails on code that reads window.top.document.

The helper that lists the fullscreen names is renamed, and its comment
says which list it mirrors.
An embedded page in fullscreen puts its iframe in fullscreen on the
embedding page too, so the exit test without an element now stubs the
embedding page in fullscreen. Code that reads window.top.document then
exits there, which the test catches; the old stub only caught a request
no browser makes.
@MartinKanera
MartinKanera force-pushed the fix/toggle-fullscreen-cross-origin branch from b80cac4 to 1d8b768 Compare October 15, 2026 22:01
@MartinKanera
MartinKanera marked this pull request as ready for review October 15, 2026 22:01
@kumilingus
kumilingus requested a balanced review from Copilot October 16, 2026 21:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fix preserves fallback behavior, includes regression coverage, and has no identified blocking issues.

No open issues 🎉

What changed in this PR

Fixes util.toggleFullScreen() for cross-origin iframe applications by using the element’s own document rather than the top-level document.

Changes:

  • Uses the current document’s body when no element is supplied.
  • Adds four regression tests for document-specific fullscreen behavior.
  • Includes a patch changeset for @joint/core.
File Description
packages/​joint-core/​test/​jointjs/​core/​util.js Tests fullscreen entry and exit across document contexts.
packages/​joint-core/​src/​util/​util.mjs Uses the appropriate document and updates API documentation.
.changeset/​toggle-fullscreen-own-document.md Records the fullscreen fix for release.

Review effort: Balanced

@kumilingus
kumilingus merged commit 6c64bd5 into clientIO:master Oct 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants