Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-web-core-lynxview-disconnect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/web-core": patch
---

fix: avoid error when LynxView is removed immediately after connected
7 changes: 4 additions & 3 deletions packages/web-platform/web-core/src/apis/LynxView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ export class LynxView extends HTMLElement {
);
#instance?: LynxViewInstance;

#connected = false;
#url?: string;
/**
* @public
Expand Down Expand Up @@ -414,10 +413,13 @@ export class LynxView extends HTMLElement {
* @private
*/
#render() {
if (!this.#rendering && this.#connected) {
if (!this.#rendering && this.isConnected) {
this.#rendering = true;
queueMicrotask(() => {
this.#rendering = false;
if (!this.isConnected) {
return;
}
const ssrData = this.getAttribute('ssr');
if (this.#instance) {
this.disconnectedCallback();
Expand Down Expand Up @@ -529,7 +531,6 @@ export class LynxView extends HTMLElement {
* @private
*/
connectedCallback() {
this.#connected = true;
this.#render();
}
}
Expand Down
36 changes: 36 additions & 0 deletions packages/web-platform/web-tests/tests/web-core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -713,4 +713,40 @@ test.describe('web core tests', () => {
await wait(1000);
expect(isSuccess).toBeTruthy();
});
test('should not throw error when removed immediately after connected', async ({ page }) => {
const errors: Error[] = [];
page.on('pageerror', (err) => {
errors.push(err);
});

await goto(page);

// Evaluate in browser context
await page.evaluate(async () => {
// Verify DOM behavior assumption
const div = document.createElement('div');
const shadow = div.attachShadow({ mode: 'open' });
const style = document.createElement('style');
shadow.appendChild(style);
document.body.appendChild(div);
if (!style.sheet) throw new Error('Sheet should exist when connected');

document.body.removeChild(div);
if (style.sheet) {
throw new Error('Sheet should be null when disconnected');
}

// Create a new lynx-view
const view = document.createElement('lynx-view');
// Connect it
document.body.appendChild(view);
// Immediately disconnect it
document.body.removeChild(view);

// Wait a bit to ensure microtasks run
await new Promise((resolve) => setTimeout(resolve, 100));
});

expect(errors.length).toBe(0);
});
});
Loading