fix(content): prevent forceUpdate in SSR (#27440)

Issue number: Resolves #27411,
https://github.com/ionic-team/stencil/issues/2429,
https://github.com/ionic-team/stencil/issues/4076

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

Rendering `<ion-content fullscreen="true">` in an Angular Universal
project will result in a javascript heap exception and the browser tab
timing out.

`forceUpdate` is not a compatible API with pre-rendering and results in
calling itself indefinitely.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Updates the fullscreen implementation of `ion-content` to only call
`forceUpdate` and related functionality when running in a browser
environment.
- `<ion-content fullscreen="true">` is compatible with Angular Universal

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Dev-build: `7.0.6-dev.11683653232.1ddc5840` 
This commit is contained in:
Sean Perkins
2023-05-09 17:29:04 -04:00
committed by GitHub
parent eba4c7f6e6
commit e9309880d1

View File

@ -1,5 +1,5 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core'; import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Host, Listen, Method, Prop, forceUpdate, h, readTask } from '@stencil/core'; import { Build, Component, Element, Event, Host, Listen, Method, Prop, forceUpdate, h, readTask } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global'; import { getIonMode } from '../../global/ionic-global';
import type { Color } from '../../interface'; import type { Color } from '../../interface';
@ -172,6 +172,15 @@ export class Content implements ComponentInterface {
} }
private resize() { private resize() {
/**
* Only force update if the component is rendered in a browser context.
* Using `forceUpdate` in a server context with pre-rendering can lead to an infinite loop.
* The `hydrateDocument` function in `@stencil/core` will render the `ion-content`, but
* `forceUpdate` will trigger another render, locking up the server.
*
* TODO: Remove if STENCIL-834 determines Stencil will account for this.
*/
if (Build.isBrowser) {
if (this.fullscreen) { if (this.fullscreen) {
readTask(() => this.readDimensions()); readTask(() => this.readDimensions());
} else if (this.cTop !== 0 || this.cBottom !== 0) { } else if (this.cTop !== 0 || this.cBottom !== 0) {
@ -179,6 +188,7 @@ export class Content implements ComponentInterface {
forceUpdate(this); forceUpdate(this);
} }
} }
}
private readDimensions() { private readDimensions() {
const page = getPageElement(this.el); const page = getPageElement(this.el);