Skip to content

Commit

Permalink
Implement additional traversal methods on ReactNativeDocument (facebo…
Browse files Browse the repository at this point in the history
…ok#49013)

Summary:
Pull Request resolved: facebook#49013

Changelog: [internal]

Adds `Document`-specific traversal methods to `ReactNativeDocument`:
* `childElementCount`
* `children`
* `firstElementChild`
* `lastElementChild`

Differential Revision: D67693032
  • Loading branch information
rubennorte authored and facebook-github-bot committed Jan 29, 2025
1 parent 64ee1d3 commit c465b6d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11322,7 +11322,11 @@ exports[`public API should not change unintentionally src/private/webapis/dom/no
rootTag: RootTag,
instanceHandle: ReactNativeDocumentInstanceHandle
): void;
get childElementCount(): number;
get children(): HTMLCollection<ReadOnlyElement>;
get documentElement(): ReactNativeElement;
get firstElementChild(): ReadOnlyElement | null;
get lastElementChild(): ReadOnlyElement | null;
get nodeName(): string;
get nodeType(): number;
get nodeValue(): null;
Expand Down
5 changes: 5 additions & 0 deletions packages/react-native/src/private/setup/setUpDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export default function setUpDOM() {
() => require('../webapis/dom/geometry/DOMRectReadOnly').default,
);

polyfillGlobal(
'HTMLCollection',
() => require('../webapis/dom/oldstylecollections/HTMLCollection').default,
);

polyfillGlobal(
'NodeList',
() => require('../webapis/dom/oldstylecollections/NodeList').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@

import type {RootTag} from '../../../../../Libraries/ReactNative/RootTag';
import type {ViewConfig} from '../../../../../Libraries/Renderer/shims/ReactNativeTypes';
import type HTMLCollection from '../oldstylecollections/HTMLCollection';
import type {ReactNativeDocumentInstanceHandle} from './internals/ReactNativeDocumentInstanceHandle';
import type ReadOnlyElement from './ReadOnlyElement';

import {createHTMLCollection} from '../oldstylecollections/HTMLCollection';
import {
createReactNativeDocumentElementInstanceHandle,
setNativeElementReferenceForReactNativeDocumentElementInstanceHandle,
Expand All @@ -35,10 +38,27 @@ export default class ReactNativeDocument extends ReadOnlyNode {
this._documentElement = createDocumentElement(rootTag, this);
}

get childElementCount(): number {
// just `documentElement`.
return 1;
}

get children(): HTMLCollection<ReadOnlyElement> {
return createHTMLCollection([this.documentElement]);
}

get documentElement(): ReactNativeElement {
return this._documentElement;
}

get firstElementChild(): ReadOnlyElement | null {
return this.documentElement;
}

get lastElementChild(): ReadOnlyElement | null {
return this.documentElement;
}

get nodeName(): string {
return '#document';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,30 @@ describe('ReactNativeDocument', () => {
expect(element.parentNode).toBe(document.documentElement);
});

it('allows traversal through document-specific methods', () => {
let lastNode;

const root = Fantom.createRoot();
Fantom.runTask(() => {
root.render(
<View
ref={node => {
lastNode = node;
}}
/>,
);
});

const element = ensureInstance(lastNode, ReactNativeElement);
const document = ensureInstance(element.ownerDocument, ReactNativeDocument);

expect(document.childElementCount).toBe(1);
expect(document.firstElementChild).toBe(document.documentElement);
expect(document.lastElementChild).toBe(document.documentElement);
expect(document.children).toBeInstanceOf(HTMLCollection);
expect([...document.children]).toEqual([document.documentElement]);
});

it('implements the abstract methods from ReadOnlyNode', () => {
let lastNode;

Expand Down

0 comments on commit c465b6d

Please sign in to comment.