Make constructors of internal DOM, MutationObserver, and IntersectionObserver classes throw#57046
Closed
rubennorte wants to merge 1 commit into
Closed
Make constructors of internal DOM, MutationObserver, and IntersectionObserver classes throw#57046rubennorte wants to merge 1 commit into
rubennorte wants to merge 1 commit into
Conversation
|
@rubennorte has exported this pull request. If you are a Meta employee, you can view the originating Diff in D107227212. |
rubennorte
added a commit
to rubennorte/react-native
that referenced
this pull request
Jun 2, 2026
…Observer classes throw (facebook#57046) Summary: Pull Request resolved: facebook#57046 Several Web API classes exposed globally by React Native are not meant to be constructed from userland — either because they correspond to web spec interfaces whose constructors are illegal (e.g. `Node`, `Element`, `HTMLCollection`, `NodeList`, `DOMRectList`, `IntersectionObserverEntry`, `MutationRecord`), or because their React Native implementations take internal arguments that callers cannot meaningfully supply (e.g. `Document`, `Text`, `CharacterData`, `HTMLElement`). Apply the same `_public` pattern already in use under `setUpPerformanceModern` to these classes: export a constructor stub that throws `TypeError: Failed to construct '<Name>': Illegal constructor`, with its `prototype` aliased to the real class so that `instanceof` checks against the global still work. Internal code continues to use the real class via the default export. The following classes get a `_public` export and are now polyfilled through it in their corresponding setup file: - `setUpDOM`: `DOMRectList`, `HTMLCollection`, `NodeList`, `Node` (`ReadOnlyNode`), `Document` (`ReactNativeDocument`), `CharacterData` (`ReadOnlyCharacterData`), `Text` (`ReadOnlyText`), `Element` (`ReadOnlyElement`), `HTMLElement` (`ReactNativeElement`). - `setUpMutationObserver`: `MutationRecord`. - `setUpIntersectionObserver`: `IntersectionObserverEntry` (also newly added to the setup file — it was not being exposed globally before). For `Node`, the public stub also copies the static node-type and document-position constants (`ELEMENT_NODE`, `TEXT_NODE`, `DOCUMENT_POSITION_*`, etc.) so that consumers can keep reading them from the global (`Node.ELEMENT_NODE`, …). Classes whose web-spec constructors are legitimately public (`DOMRect`, `DOMRectReadOnly`, `Event`, `EventTarget`, `CustomEvent`, `MutationObserver`, `IntersectionObserver`) are unchanged. For the three collection classes whose public Flow types live in a `.js.flow` declaration file (`DOMRectList`, `HTMLCollection`, `NodeList`), the new `_public` export is also declared in the `.js.flow` companion so Flow can see it. Changelog: [General][Fixed] - Throw "Illegal constructor" when constructing `Node`, `Document`, `Element`, `HTMLElement`, `CharacterData`, `Text`, `HTMLCollection`, `NodeList`, `DOMRectList`, `MutationRecord`, and `IntersectionObserverEntry` from JavaScript. Reviewed By: huntie Differential Revision: D107227212
84775c8 to
33b8d6a
Compare
…Observer classes throw Summary: Several Web API classes exposed globally by React Native are not meant to be constructed from userland. They fall into two groups: - Classes whose web spec constructors are illegal regardless of platform: `Node`, `Element`, `CharacterData`, `HTMLCollection`, `NodeList`, `DOMRectList`, `IntersectionObserverEntry`, `MutationRecord`. The web platform itself throws an "Illegal constructor" `TypeError` for these. - Classes whose web spec constructors are public, but whose React Native implementations cannot be constructed from userland because nodes cannot be imperatively created in React Native — only React can create them during rendering. These are `Document`, `Text`, and `HTMLElement`. Apply the same `_public` pattern already in use under `setUpPerformanceModern` to these classes: export a constructor stub that throws a `TypeError`, with its `prototype` aliased to the real class so that `instanceof` checks against the global still work. Internal code continues to use the real class via the default export. For the first group the thrown message follows the web convention, e.g.: TypeError: Failed to construct 'Node': Illegal constructor For the second group the message clarifies the React-Native-specific reason, e.g.: TypeError: Failed to construct 'Document': Nodes cannot be imperatively created in React Native The following classes get a `_public` export and are now polyfilled through it in their corresponding setup file: - `setUpDOM`: `DOMRectList`, `HTMLCollection`, `NodeList`, `Node` (`ReadOnlyNode`), `Document` (`ReactNativeDocument`), `CharacterData` (`ReadOnlyCharacterData`), `Text` (`ReadOnlyText`), `Element` (`ReadOnlyElement`), `HTMLElement` (`ReactNativeElement`). - `setUpMutationObserver`: `MutationRecord`. - `setUpIntersectionObserver`: `IntersectionObserverEntry` (also newly added to the setup file — it was not being exposed globally before). For `Node`, the public stub also copies the static node-type and document-position constants (`ELEMENT_NODE`, `TEXT_NODE`, `DOCUMENT_POSITION_*`, etc.) so that consumers can keep reading them from the global (`Node.ELEMENT_NODE`, …). Classes whose web-spec constructors are legitimately public (`DOMRect`, `DOMRectReadOnly`, `Event`, `EventTarget`, `CustomEvent`, `MutationObserver`, `IntersectionObserver`) are unchanged. For the three collection classes whose public Flow types live in a `.js.flow` declaration file (`DOMRectList`, `HTMLCollection`, `NodeList`), the new `_public` export is also declared in the `.js.flow` companion so Flow can see it. Changelog: [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `Node` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `Element` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `CharacterData` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `HTMLCollection` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `NodeList` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `DOMRectList` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `IntersectionObserverEntry` from JavaScript [General][Changed] - Throw "Illegal constructor" `TypeError` when constructing `MutationRecord` from JavaScript [General][Changed] - Throw "Nodes cannot be imperatively created in React Native" `TypeError` when constructing `Document` from JavaScript [General][Changed] - Throw "Nodes cannot be imperatively created in React Native" `TypeError` when constructing `Text` from JavaScript [General][Changed] - Throw "Nodes cannot be imperatively created in React Native" `TypeError` when constructing `HTMLElement` from JavaScript [General][Added] - Expose `IntersectionObserverEntry` as a global Reviewed By: huntie Differential Revision: D107227212
33b8d6a to
fbc9087
Compare
|
This pull request has been merged in 4deb32a. |
Collaborator
|
This pull request was successfully merged by @rubennorte in 4deb32a When will my fix make it into a release? | How to file a pick request? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Several Web API classes exposed globally by React Native are not meant to be constructed from userland. They fall into two groups:
Node,Element,CharacterData,HTMLCollection,NodeList,DOMRectList,IntersectionObserverEntry,MutationRecord. The web platform itself throws an "Illegal constructor"TypeErrorfor these.Document,Text, andHTMLElement.Apply the same
_publicpattern already in use undersetUpPerformanceModernto these classes: export a constructor stub that throws aTypeError, with itsprototypealiased to the real class so thatinstanceofchecks against the global still work. Internal code continues to use the real class via the default export.For the first group the thrown message follows the web convention, e.g.:
TypeError: Failed to construct 'Node': Illegal constructor
For the second group the message clarifies the React-Native-specific reason, e.g.:
TypeError: Failed to construct 'Document': Nodes cannot be imperatively created in React Native
The following classes get a
_publicexport and are now polyfilled through it in their corresponding setup file:setUpDOM:DOMRectList,HTMLCollection,NodeList,Node(ReadOnlyNode),Document(ReactNativeDocument),CharacterData(ReadOnlyCharacterData),Text(ReadOnlyText),Element(ReadOnlyElement),HTMLElement(ReactNativeElement).setUpMutationObserver:MutationRecord.setUpIntersectionObserver:IntersectionObserverEntry(also newly added to the setup file — it was not being exposed globally before).For
Node, the public stub also copies the static node-type and document-position constants (ELEMENT_NODE,TEXT_NODE,DOCUMENT_POSITION_*, etc.) so that consumers can keep reading them from the global (Node.ELEMENT_NODE, …).Classes whose web-spec constructors are legitimately public (
DOMRect,DOMRectReadOnly,Event,EventTarget,CustomEvent,MutationObserver,IntersectionObserver) are unchanged.For the three collection classes whose public Flow types live in a
.js.flowdeclaration file (DOMRectList,HTMLCollection,NodeList), the new_publicexport is also declared in the.js.flowcompanion so Flow can see it.Changelog:
[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingNodefrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingElementfrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingCharacterDatafrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingHTMLCollectionfrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingNodeListfrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingDOMRectListfrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingIntersectionObserverEntryfrom JavaScript[General][Changed] - Throw "Illegal constructor"
TypeErrorwhen constructingMutationRecordfrom JavaScript[General][Changed] - Throw "Nodes cannot be imperatively created in React Native"
TypeErrorwhen constructingDocumentfrom JavaScript[General][Changed] - Throw "Nodes cannot be imperatively created in React Native"
TypeErrorwhen constructingTextfrom JavaScript[General][Changed] - Throw "Nodes cannot be imperatively created in React Native"
TypeErrorwhen constructingHTMLElementfrom JavaScript[General][Added] - Expose
IntersectionObserverEntryas a globalReviewed By: huntie
Differential Revision: D107227212