Skip to content

Commit

Permalink
typecheck: src/preact/components (#37463)
Browse files Browse the repository at this point in the history
  • Loading branch information
samouri committed Feb 4, 2022
1 parent 6b12807 commit 2004c91
Show file tree
Hide file tree
Showing 25 changed files with 201 additions and 126 deletions.
16 changes: 16 additions & 0 deletions src/3p-frame.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Returns a randomized sentinel value for 3p iframes.
* The format is "%d-%d" with the first value being the depth of current
* window in the window hierarchy and the second a random integer.
*/
export const generateSentinel: (win: Window) => string;

/** Returns the base URL for 3p bootstrap iframes. */
export const getDefaultBootstrapBaseUrl: (
parentWin: Window,
ampdoc?: any,
strictForUnitTest?: boolean
) => string;

/** Get the bootstrap script URL for iframe. */
export const getBootstrapUrl: (type: string) => string;
8 changes: 7 additions & 1 deletion src/core/amp-globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ declare global {
__AMP_MODE: AmpModeObject;

// AMP Runtime settings, configuration, and environment/build constants.
AMP_CONFIG?: AmpConfig & {[key: string]: (boolean|string)};
AMP_CONFIG?: AmpConfig & {[key: string]: boolean | string};
}

interface Document {
AMP?: {
canonicalUrl?: string;
};
}

interface AmpConfig {
Expand Down
18 changes: 9 additions & 9 deletions src/core/constants/loading-instructions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@
* Only `UNLOAD` is not defined by the "Lazy loading" spec at this time. It's
* added here because it supersedes all other loading instructions in AMP.
*
* @enum {string}
* @enum {"auto" | "lazy" | "eager" | "unload"}
*/
export const Loading_Enum = {
/**
* If parent is available, fallback to its loading strategy (e.g. based on
* whether the document is visible or not).
* If parent is not available, proceed with loading at your own discretion.
*/
AUTO: 'auto',
AUTO: /** @type {"auto"} */ ('auto'),

/**
* Do not load independently. Wait for the caller to start loading manually.
*/
LAZY: 'lazy',
LAZY: /** @type {"lazy"} */ ('lazy'),

/**
* Proceed with loading at the earliest convenience.
*/
EAGER: 'eager',
EAGER: /** @type {"eager"} */ ('eager'),

/**
* Force unload if possible.
*/
UNLOAD: 'unload',
UNLOAD: /** @type {"unload"} */ ('unload'),
};

/**
Expand Down Expand Up @@ -57,13 +57,13 @@ const MAP = {
* Returns the loading instruction with a higher priority. The priority
* order is auto -> lazy -> eager -> unload.
*
* @param {Loading_Enum|string} v1
* @param {Loading_Enum|string} v2
* @param {Loading_Enum|string|undefined} v1
* @param {Loading_Enum|string|undefined} v2
* @return {Loading_Enum}
*/
export function reducer(v1, v2) {
const ordinal1 = MAP[v1] || 0;
const ordinal2 = MAP[v2] || 0;
const ordinal1 = MAP[v1 ?? Loading_Enum.AUTO] || 0;
const ordinal2 = MAP[v2 ?? Loading_Enum.AUTO] || 0;
const ordinal = Math.max(ordinal1, ordinal2);
return ORDER[ordinal];
}
10 changes: 10 additions & 0 deletions src/core/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,13 @@ export function isElement(value) {
export function isFiniteNumber(value) {
return typeof value === 'number' && isFinite(value);
}

/**
* Returns true if obj is a PromiseLike.
*
* @param {*} obj
* @return {obj is Promise<*>}
*/
export function isPromise(obj) {
return typeof obj?.then === 'function';
}
9 changes: 4 additions & 5 deletions src/preact/compat.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,11 @@ function newDiff(vnode) {
* Reimplements forwardRef without dragging in everything from preact/compat.
* See https://github.com/preactjs/preact/issues/3295
*
* @param {*} Component
* @return {ReturnType<import('preact/compat').forwardRef>}
* @type {import('preact/compat').forwardRef}
*/
export function forwardRef(Component) {
export const forwardRef = function (Component) {
/**
* @param {JsonObject} props
* @param {*} props
* @return {*}
*/
function Forward(props) {
Expand Down Expand Up @@ -70,7 +69,7 @@ export function forwardRef(Component) {
}

return /** @type {*} */ (Forward);
}
};

/**
* @type {typeof import('preact').toChildArray} children
Expand Down
11 changes: 6 additions & 5 deletions src/preact/component/3p-frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getBootstrapUrl,
getDefaultBootstrapBaseUrl,
} from '../../3p-frame';
import {parseUrlDeprecated} from '../../url';

/** @type {Object<string,function():void>} 3p frames for that type. */
export const countGenerators = {};
Expand All @@ -38,9 +39,9 @@ const DEFAULT_SANDBOX =
/**
* Creates the iframe for the embed. Applies correct size and passes the embed
* attributes to the frame via JSON inside the fragment.
* @param {IframeEmbedDef.Props} props
* @param {{current: (IframeEmbedDef.Api|null)}} ref
* @return {PreactDef.Renderable}
* @param {import('./types').IframeEmbedProps} props
* @param {import('preact').RefObject<import('./types').IframeEmbedApi>} ref
* @return {import('preact').VNode}
*/
function ProxyIframeEmbedWithRef(
{
Expand Down Expand Up @@ -104,7 +105,7 @@ function ProxyIframeEmbedWithRef(
};
setNameAndSrc({
name: JSON.stringify({
'host': new URL(src, win.location.toString()).hostname,
'host': parseUrlDeprecated(src).hostname,
'bootstrap': getBootstrapUrl(type),
'type': type,
// "name" must be unique across iframes, so we add a count.
Expand Down Expand Up @@ -142,6 +143,7 @@ function ProxyIframeEmbedWithRef(

return (
<IframeEmbed
{...rest}
allow={allow}
contentRef={contentRef}
messageHandler={messageHandler}
Expand All @@ -151,7 +153,6 @@ function ProxyIframeEmbedWithRef(
sandbox={excludeSandbox ? undefined : sandbox}
src={src}
title={title}
{...rest}
/>
);
}
Expand Down
64 changes: 0 additions & 64 deletions src/preact/component/component.type.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ const SIZE_CONTENT_STYLE = {
* - layout: nothing outside the element may affect its internal layout and
* vice versa.
* - paint: the element's content doesn't display outside the element's bounds.
* @param {ContainWrapperComponentProps} props
* @param {{current: ?Element}} ref
* @return {PreactDef.Renderable}
* @param {import('./types').ContainerWrapperComponentProps} props
* @param {import('preact').RefObject<Element>} ref
* @return {import('preact').VNode}
*/
function ContainWrapperWithRef(
{
Expand Down
19 changes: 13 additions & 6 deletions src/preact/component/iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ const ABOUT_BLANK = 'about:blank';
* @param {string} src
* @return {boolean}
* */
const canResetSrc = (src) => src && src != ABOUT_BLANK && !src.includes('#');
const canResetSrc = (src) =>
!!(src && src != ABOUT_BLANK && !src.includes('#'));

/**
* @param {IframeEmbedDef.Props} props
* @param {{current: ?IframeEmbedDef.Api}} ref
* @return {PreactDef.Renderable}
* @param {import('./types').IframeEmbedProps} props
* @param {import('preact').RefObject<import('./types').IframeEmbedApi>} ref
* @return {import('preact').VNode}
*/
export function IframeEmbedWithRef(
{
Expand Down Expand Up @@ -57,6 +58,7 @@ export function IframeEmbedWithRef(
// of `onReadyState` re-triggering the side effects.
const onReadyStateRef = useValueRef(onReadyState);
const setLoaded = useCallback(
/** @param {boolean} value */
(value) => {
if (value !== loadedRef.current) {
loadedRef.current = value;
Expand Down Expand Up @@ -121,6 +123,7 @@ export function IframeEmbedWithRef(
return;
}

/** @param {MessageEvent} event */
const handler = (event) => {
const iframe = iframeRef.current;
if (
Expand All @@ -144,10 +147,14 @@ export function IframeEmbedWithRef(
<iframe
allow={allow}
allowFullScreen={allowFullScreen}
frameborder="0"
loading={loading}
// TODO: is it frameborder or frameBorder?
frameBorder="0"
// TODO: ensure loading is not "auto" or "unload".
loading={/** @type {*} */ (loading)}
name={name}
onLoad={() => setLoaded(true)}
// TODO: what should be here?
// @ts-ignore
part="iframe"
ref={iframeRef}
sandbox={sandbox}
Expand Down
5 changes: 3 additions & 2 deletions src/preact/component/intersection-observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import {useCallback, useRef} from '#preact';
/**
* Uses a shared IntersectionObserver per window instance to observe the given `ref`.
*
* @param {function(IntersectionObserverEntry)} callback
* @return {function(Element)}
* @param {function(IntersectionObserverEntry):void} callback
* @return {function(Element):void}
*/
export function useIntersectionObserver(callback) {
const unobserveRef = useRef(null);
const refCb = useCallback(
/** @param {Element} node */
(node) => {
const cleanup = unobserveRef.current;
if (cleanup) {
Expand Down
17 changes: 10 additions & 7 deletions src/preact/component/renderer.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import {isPromise} from '#core/types';

import {useLayoutEffect, useState} from '#preact';

/** @typedef {import('./types').RendererFunction} RendererFunction */
/** @typedef {import('preact').VNode<*>} VNode */

/**
* Runs the renderer. It's critical that the `data` argument is stable - it
* only changes when the actual data changes. The renderer itself is resolved
* in a layout effect and allows the result to be a promise.
*
* @param {?RendererFunctionType|undefined} renderer
* @param {RendererFunction} renderer
* @param {JsonObject} data
* @return {?RendererFunctionResponseType}
* @return {VNode|null}
*/
export function useRenderer(renderer, data) {
const [value, setValue] = useState(
/** @type {?RendererFunctionResponseType} */ (null)
);
const [value, setValue] = useState(/** @type {VNode|null} */ (null));

useLayoutEffect(() => {
const rendered = (renderer && renderer(data)) || null;
if (rendered && typeof rendered['then'] == 'function') {
if (isPromise(rendered)) {
let canceled = false;
rendered.then((result) => {
if (!canceled) {
Expand All @@ -27,7 +30,7 @@ export function useRenderer(renderer, data) {
canceled = true;
};
} else {
setValue(/** @type {?RendererFunctionResponseType} */ (rendered));
setValue(/** @type {VNode} */ (rendered));
}
}, [renderer, data]);

Expand Down

0 comments on commit 2004c91

Please sign in to comment.