diff --git a/schema/core.xsd b/schema/core.xsd
index 191c9a9dd..dba4f17c5 100644
--- a/schema/core.xsd
+++ b/schema/core.xsd
@@ -1235,9 +1235,11 @@
+
+
@@ -1249,6 +1251,7 @@
+
diff --git a/src/behaviors/hv-hide/index.ts b/src/behaviors/hv-hide/index.ts
index 512621f6f..180414169 100644
--- a/src/behaviors/hv-hide/index.ts
+++ b/src/behaviors/hv-hide/index.ts
@@ -35,8 +35,8 @@ export default {
);
const hideElement = () => {
- const doc: Document = getRoot();
- const targetElement: Element | null | undefined = doc.getElementById(
+ const doc: Document | null = getRoot();
+ const targetElement: Element | null | undefined = doc?.getElementById(
targetId,
);
if (!targetElement) {
@@ -65,13 +65,16 @@ export default {
hideElement();
} else {
// If there's a delay, first trigger the indicators before the hide
- const newRoot = Behaviors.setIndicatorsBeforeLoad(
- showIndicatorIds,
- hideIndicatorIds,
- getRoot(),
- );
- // Update the DOM to reflect the new state of the indicators.
- updateRoot(newRoot);
+ const doc: Document | null = getRoot();
+ if (doc) {
+ const newRoot = Behaviors.setIndicatorsBeforeLoad(
+ showIndicatorIds,
+ hideIndicatorIds,
+ doc,
+ );
+ // Update the DOM to reflect the new state of the indicators.
+ updateRoot(newRoot);
+ }
// Wait for the delay then hide the target.
later(delay).then(hideElement).catch(hideElement);
}
diff --git a/src/behaviors/hv-select-all/index.ts b/src/behaviors/hv-select-all/index.ts
index 69636121b..6e72e7482 100644
--- a/src/behaviors/hv-select-all/index.ts
+++ b/src/behaviors/hv-select-all/index.ts
@@ -37,8 +37,8 @@ export default {
);
const selectAll = () => {
- const doc: Document = getRoot();
- const targetElement: Element | null | undefined = doc.getElementById(
+ const doc: Document | null = getRoot();
+ const targetElement: Element | null | undefined = doc?.getElementById(
targetId,
);
if (!targetElement) {
@@ -66,13 +66,16 @@ export default {
selectAll();
} else {
// If there's a delay, first trigger the indicators before the select-all.
- const newRoot = Behaviors.setIndicatorsBeforeLoad(
- showIndicatorIds,
- hideIndicatorIds,
- getRoot(),
- );
- // Update the DOM to reflect the new state of the indicators.
- updateRoot(newRoot);
+ const doc: Document | null = getRoot();
+ if (doc) {
+ const newRoot = Behaviors.setIndicatorsBeforeLoad(
+ showIndicatorIds,
+ hideIndicatorIds,
+ doc,
+ );
+ // Update the DOM to reflect the new state of the indicators.
+ updateRoot(newRoot);
+ }
// Wait for the delay then select-all the target.
later(delay).then(selectAll).catch(selectAll);
}
diff --git a/src/behaviors/hv-set-value/index.ts b/src/behaviors/hv-set-value/index.ts
index 811653662..e7aebf663 100644
--- a/src/behaviors/hv-set-value/index.ts
+++ b/src/behaviors/hv-set-value/index.ts
@@ -38,8 +38,8 @@ export default {
);
const setValue = () => {
- const doc: Document = getRoot();
- const targetElement: Element | null | undefined = doc.getElementById(
+ const doc: Document | null = getRoot();
+ const targetElement: Element | null | undefined = doc?.getElementById(
targetId,
);
if (!targetElement) {
@@ -68,13 +68,16 @@ export default {
setValue();
} else {
// If there's a delay, first trigger the indicators before the show.
- const newRoot = Behaviors.setIndicatorsBeforeLoad(
- showIndicatorIds,
- hideIndicatorIds,
- getRoot(),
- );
- // Update the DOM to reflect the new state of the indicators.
- updateRoot(newRoot);
+ const doc: Document | null = getRoot();
+ if (doc) {
+ const newRoot = Behaviors.setIndicatorsBeforeLoad(
+ showIndicatorIds,
+ hideIndicatorIds,
+ doc,
+ );
+ // Update the DOM to reflect the new state of the indicators.
+ updateRoot(newRoot);
+ }
// Wait for the delay then show the target.
later(delay).then(setValue).catch(setValue);
}
diff --git a/src/behaviors/hv-show/index.ts b/src/behaviors/hv-show/index.ts
index 9caa6de8c..f2360b657 100644
--- a/src/behaviors/hv-show/index.ts
+++ b/src/behaviors/hv-show/index.ts
@@ -35,8 +35,8 @@ export default {
);
const showElement = () => {
- const doc: Document = getRoot();
- const targetElement: Element | null | undefined = doc.getElementById(
+ const doc: Document | null = getRoot();
+ const targetElement: Element | null | undefined = doc?.getElementById(
targetId,
);
if (!targetElement) {
@@ -65,13 +65,16 @@ export default {
showElement();
} else {
// If there's a delay, first trigger the indicators before the show.
- const newRoot = Behaviors.setIndicatorsBeforeLoad(
- showIndicatorIds,
- hideIndicatorIds,
- getRoot(),
- );
- // Update the DOM to reflect the new state of the indicators.
- updateRoot(newRoot);
+ const doc: Document | null = getRoot();
+ if (doc) {
+ const newRoot = Behaviors.setIndicatorsBeforeLoad(
+ showIndicatorIds,
+ hideIndicatorIds,
+ doc,
+ );
+ // Update the DOM to reflect the new state of the indicators.
+ updateRoot(newRoot);
+ }
// Wait for the delay then show the target.
later(delay).then(showElement).catch(showElement);
}
diff --git a/src/behaviors/hv-toggle/index.ts b/src/behaviors/hv-toggle/index.ts
index 664cf734b..60c34290f 100644
--- a/src/behaviors/hv-toggle/index.ts
+++ b/src/behaviors/hv-toggle/index.ts
@@ -35,8 +35,8 @@ export default {
);
const toggleElement = () => {
- const doc: Document = getRoot();
- const targetElement: Element | null | undefined = doc.getElementById(
+ const doc: Document | null = getRoot();
+ const targetElement: Element | null | undefined = doc?.getElementById(
targetId,
);
if (!targetElement) {
@@ -68,13 +68,16 @@ export default {
toggleElement();
} else {
// If there's a delay, first trigger the indicators before the toggle.
- const newRoot = Behaviors.setIndicatorsBeforeLoad(
- showIndicatorIds,
- hideIndicatorIds,
- getRoot(),
- );
- // Update the DOM to reflect the new state of the indicators.
- updateRoot(newRoot);
+ const doc: Document | null = getRoot();
+ if (doc) {
+ const newRoot = Behaviors.setIndicatorsBeforeLoad(
+ showIndicatorIds,
+ hideIndicatorIds,
+ doc,
+ );
+ // Update the DOM to reflect the new state of the indicators.
+ updateRoot(newRoot);
+ }
// Wait for the delay then toggle the target.
later(delay).then(toggleElement).catch(toggleElement);
}
diff --git a/src/behaviors/hv-unselect-all/index.ts b/src/behaviors/hv-unselect-all/index.ts
index 569f942e6..6a010d7f3 100644
--- a/src/behaviors/hv-unselect-all/index.ts
+++ b/src/behaviors/hv-unselect-all/index.ts
@@ -37,8 +37,8 @@ export default {
);
const unselectAll = () => {
- const doc: Document = getRoot();
- const targetElement: Element | null | undefined = doc.getElementById(
+ const doc: Document | null = getRoot();
+ const targetElement: Element | null | undefined = doc?.getElementById(
targetId,
);
if (!targetElement) {
@@ -66,13 +66,16 @@ export default {
unselectAll();
} else {
// If there's a delay, first trigger the indicators before the unselect-all.
- const newRoot = Behaviors.setIndicatorsBeforeLoad(
- showIndicatorIds,
- hideIndicatorIds,
- getRoot(),
- );
- // Update the DOM to reflect the new state of the indicators.
- updateRoot(newRoot);
+ const doc: Document | null = getRoot();
+ if (doc) {
+ const newRoot = Behaviors.setIndicatorsBeforeLoad(
+ showIndicatorIds,
+ hideIndicatorIds,
+ doc,
+ );
+ // Update the DOM to reflect the new state of the indicators.
+ updateRoot(newRoot);
+ }
// Wait for the delay then unselect-all the target.
later(delay).then(unselectAll).catch(unselectAll);
}
diff --git a/src/behaviors/index.ts b/src/behaviors/index.ts
index 410d51174..b3702441e 100644
--- a/src/behaviors/index.ts
+++ b/src/behaviors/index.ts
@@ -44,4 +44,6 @@ export {
setIndicatorsBeforeLoad,
performUpdate,
setIndicatorsAfterLoad,
+ isOncePreviouslyApplied,
+ setRanOnce,
} from 'hyperview/src/services/behaviors';
diff --git a/src/contexts/index.ts b/src/contexts/index.ts
index 3042fb92b..fc526203f 100644
--- a/src/contexts/index.ts
+++ b/src/contexts/index.ts
@@ -7,6 +7,7 @@
*/
import type { ComponentType } from 'react';
+import type { HvComponentOnUpdate } from 'hyperview/src/types';
import React from 'react';
import type { RefreshControlProps } from 'react-native';
@@ -24,5 +25,11 @@ export const RefreshControlComponentContext = React.createContext<
>(undefined);
export const DocContext = React.createContext<{
- getDoc: () => Document;
+ getDoc: () => Document | undefined;
+ setDoc?: (doc: Document) => void;
} | null>(null);
+
+export const OnUpdateContext = React.createContext<{
+ onUpdate: HvComponentOnUpdate;
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+}>({ onUpdate: () => {} });
diff --git a/src/contexts/navigation.ts b/src/contexts/navigation.ts
index 65e753461..3aa98b42e 100644
--- a/src/contexts/navigation.ts
+++ b/src/contexts/navigation.ts
@@ -5,7 +5,12 @@
* LICENSE file in the root directory of this source tree.
*
*/
-import type { Fetch, HvBehavior, HvComponent } from 'hyperview/src/types';
+import type {
+ Fetch,
+ HvBehavior,
+ HvComponent,
+ HvComponentOnUpdate,
+} from 'hyperview/src/types';
import React, { ComponentType, ReactNode } from 'react';
@@ -18,6 +23,7 @@ export type NavigationContextProps = {
onError?: (error: Error) => void;
onParseAfter?: (url: string) => void;
onParseBefore?: (url: string) => void;
+ onUpdate: HvComponentOnUpdate;
url?: string;
behaviors?: HvBehavior[];
components?: HvComponent[];
diff --git a/src/contexts/navigator-map.tsx b/src/contexts/navigator-map.tsx
index ef9aec0a9..0a9f50231 100644
--- a/src/contexts/navigator-map.tsx
+++ b/src/contexts/navigator-map.tsx
@@ -9,13 +9,8 @@
import React, { createContext, useState } from 'react';
export type NavigatorMapContextProps = {
- setRoute: (key: string, route: string) => void;
- getRoute: (key: string) => string | undefined;
- setElement: (key: string, element: Element) => void;
- getElement: (key: string) => Element | undefined;
setPreload: (key: number, element: Element) => void;
getPreload: (key: number) => Element | undefined;
- initialRouteName?: string;
};
/**
@@ -23,16 +18,11 @@ export type NavigatorMapContextProps = {
* Each navigator creates its own context
* - routeMap: Urls defined in elements are stored in the routeMap by their key
* - elementMap: Contains element sub-navigators defined in a element
- * - initialRouteName: The name of the first route to render
* - preloadMap: A map of preload elements by their id
*/
export const NavigatorMapContext = createContext({
- getElement: () => undefined,
getPreload: () => undefined,
- getRoute: () => '',
- setElement: () => undefined,
setPreload: () => undefined,
- setRoute: () => undefined,
});
type Props = { children: React.ReactNode };
@@ -42,26 +32,8 @@ type Props = { children: React.ReactNode };
* store runtime information about the navigator and urls.
*/
export function NavigatorMapProvider(props: Props) {
- const [routeMap] = useState