Problem with canvas resizing

Hello!
We have embedded our PlayCanvas app to iframe in page.
Because of iPhone fullscreen incompatibility, we made pseudo-fullscreen. We just resize canvas to fill the page and vice versa.
Our solution works perfectly on:

  • Desktop
  • Android
  • iOS 13 and earlier

Except iOS 14: it enables and disable pseudo-fullscreen for the first time, but when you click fullscreen button again, Safari refreshes the page.
Demo video
fullscreen-button.js:

var FullscreenButton = pc.createScript('fullscreenButton');

// Properties
FullscreenButton.attributes.add("debug", { type: 'boolean', default: false });
FullscreenButton.attributes.add("eventName", { type: 'string', default: "click" });
FullscreenButton.attributes.add("htmlIDs", { type: 'string', array: true });
FullscreenButton.prototype.fullscreen = false;
FullscreenButton.prototype.parentFrame = null;
FullscreenButton.prototype.defaultStyle = null;

// initialize code called once per entity
FullscreenButton.prototype.postInitialize = function() {
    DebugHelper.printDebugMessage(this, "postInitialize");

    this.setupEvents();
};

// Event handlers initialization
FullscreenButton.prototype.setupEvents = function() {
    DebugHelper.printDebugMessage(this, "setupEvents");

    if (this.entity.script.htmlRedirector) {
        this.entity.script.htmlRedirector.setupEventListeners(this, this.eventName, this.htmlIDs, this.onPress);
    } else {
        this.entity.element.on(eventName, this.onPress, this);
    }
    
    this.app.graphicsDevice.on("resizecanvas", this.onResizeCanvas, this);
    
    // TODO Move to another method
    this.parentFrame = window.parent.document.getElementsByTagName("iframe")[0];
    if (this.parentFrame) {
        this.defaultStyle = this.parentFrame.style.cssText;
    }
};

// Event handlers destroying
FullscreenButton.prototype.clearEvents = function() {
    DebugHelper.printDebugMessage(this, "clearEvents");

    if (this.entity.script.htmlRedirector) {
        this.entity.script.htmlRedirector.removeEventListeners(this, this.eventName, this.htmlIDs, this.onPress);
    } else {
        this.entity.element.on(eventName, this.onPress, this);
    }
    
    this.app.graphicsDevice.off("resizecanvas", this.onResizeCanvas, this);

};

// Event handlers
FullscreenButton.prototype.onPress = function() {
    DebugHelper.printDebugMessage(this, "onPress");
    
    if (!this.fullscreen) {
        if (this.parentFrame) {
            this.parentFrame.style.cssText = "position: absolute; width: 100%; height: 100%; margin: 0px; top: 0px; right: 0px; left: 0px; bottom: 0px;";
        } else if (!pc.platform.ios) {
            document.documentElement.requestFullscreen();
        }
    } else {
        if (this.parentFrame) {
            this.parentFrame.style.cssText = this.defaultStyle;
        } else if (!pc.platform.ios) {
            document.exitFullscreen();
        }
    }
    
    this.fullscreen = !this.fullscreen;
};

FullscreenButton.prototype.onResizeCanvas = function(width, height) {
    DebugHelper.printDebugMessage(this, "onResizeCanvas");
    
    document.getElementById("application-canvas").width = document.body.clientWidth;
    document.getElementById("application-canvas").height = document.body.clientHeight;
    DebugHelper.printDebugMessage(this, "onResizeCanvas: ", document.getElementById("application-canvas").width, document.getElementById("application-canvas").height, width, height);
};

// Hot reloading
FullscreenButton.prototype.swap = function(old) { 
    DebugHelper.printDebugMessage(this, "hot reloading");

    this.setupEvents();
    old.clearEvents();
};


index.html:

<!DOCTYPE html>
<html>
  <head> </head>
  <body>
    <iframe
      src="app.html"
      frameborder="0"
      style="width: 590px; height: 520px; right: 20%;"
    ></iframe>
  </body>
</html>

app.html:

<!doctype html>
<html>
<head>
    <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no' />
    <meta charset='utf-8'>
    <link rel="stylesheet" type="text/css" href="styles.css">
    <link rel="manifest" href="manifest.json">
    <style></style>
    <title>apartment_127</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="playcanvas-stable.min.js"></script>
    <script src="__settings__.js"></script>
</head>
<body>
    <iframe src="splash.html" id="splash-container" frameborder="0"></iframe>
    <script src="__modules__.js"></script>
    <script src="__start__.js"></script>
    <script src="__loading__.js"></script>
</body>
</html>

What’s the problem?

Any errors in the console?

I guess there are no errors in the console (only warning “responseType: arraybuffer being served with Content-Type: text/plain”)
Idk if there is any error in iOS 14, because I don’t have access to iOS 14 device
You can check it out here