Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fiber] Use a safer strategy to track the last precedence #28110

Merged
merged 1 commit into from
Jan 30, 2024
Merged
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
24 changes: 17 additions & 7 deletions packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -3481,10 +3481,20 @@ function onUnsuspend(this: SuspendedState) {
}
}

// We use a value that is type distinct from precedence to track which one is last.
// This ensures there is no collision with user defined precedences. Normally we would
// just track this in module scope but since the precedences are tracked per HoistableRoot
// we need to associate it to something other than a global scope hence why we try to
// colocate it with the map of precedences in the first place
const LAST_PRECEDENCE = null;

// This is typecast to non-null because it will always be set before read.
// it is important that this not be used except when the stack guarantees it exists.
// Currentlyt his is only during insertSuspendedStylesheet.
let precedencesByRoot: Map<HoistableRoot, Map<string, Instance>> = (null: any);
let precedencesByRoot: Map<
HoistableRoot,
Map<string | typeof LAST_PRECEDENCE, Instance>,
> = (null: any);

function insertSuspendedStylesheets(
state: SuspendedState,
Expand Down Expand Up @@ -3539,27 +3549,27 @@ function insertStylesheetIntoRoot(
// and will be hoisted by the Fizz runtime imminently.
node.getAttribute('media') !== 'not all'
) {
precedences.set('p' + node.dataset.precedence, node);
precedences.set(node.dataset.precedence, node);
last = node;
}
}
if (last) {
precedences.set('last', last);
precedences.set(LAST_PRECEDENCE, last);
}
} else {
last = precedences.get('last');
last = precedences.get(LAST_PRECEDENCE);
}

// We only call this after we have constructed an instance so we assume it here
const instance: HTMLLinkElement = (resource.instance: any);
// We will always have a precedence for stylesheet instances
const precedence: string = (instance.getAttribute('data-precedence'): any);

const prior = precedences.get('p' + precedence) || last;
const prior = precedences.get(precedence) || last;
if (prior === last) {
precedences.set('last', instance);
precedences.set(LAST_PRECEDENCE, instance);
}
precedences.set('p' + precedence, instance);
precedences.set(precedence, instance);

this.count++;
const onComplete = onUnsuspend.bind(this);
Expand Down