diff --git a/docs/api/instance.md b/docs/api/instance.md index 7ac1c6c9..a237a7ca 100644 --- a/docs/api/instance.md +++ b/docs/api/instance.md @@ -234,7 +234,7 @@ document.querySelector('button#trigger-error').addEventListener('click', () => { ## event -Event emitter that can be used to listen for the following events: `RENDER`, `RENDERED`, `DISPLAY`, `ERROR`, `CLOSED`, `PROPS`, `RESIZE`. +Event emitter that can be used to listen for the following events: `RENDER`, `RENDERED`, `PRERENDER`, `PRERENDERED`, `DISPLAY`, `ERROR`, `CLOSED`, `PROPS`, `RESIZE`. ```javascript const myComponent = MyComponent(); diff --git a/src/component/props.js b/src/component/props.js index 01f23194..26171378 100644 --- a/src/component/props.js +++ b/src/component/props.js @@ -32,6 +32,8 @@ export type getParentDomainPropType = () => string; export type onDisplayPropType = EventHandlerType; export type onRenderedPropType = EventHandlerType; export type onRenderPropType = EventHandlerType; +export type onPrerenderedPropType = EventHandlerType; +export type onPrerenderPropType = EventHandlerType; export type onClosePropType = EventHandlerType; export type onDestroyPropType = EventHandlerType; export type onResizePropType = EventHandlerType; @@ -56,6 +58,8 @@ export type PropsInputType

= {| onDisplay? : onDisplayPropType, onRendered? : onRenderedPropType, onRender? : onRenderPropType, + onPrerendered? : onPrerenderedPropType, + onPrerender? : onPrerenderPropType, onClose? : onClosePropType, onDestroy? : onDestroyPropType, onResize? : onResizePropType, @@ -75,6 +79,8 @@ export type PropsType

= {| onDisplay : onDisplayPropType, onRendered : onRenderedPropType, onRender : onRenderPropType, + onPrerendered : onPrerenderedPropType, + onPrerender : onPrerenderPropType, onClose : onClosePropType, onDestroy : onDestroyPropType, onResize : onResizePropType, @@ -217,6 +223,8 @@ export type BuiltInPropsDefinitionType = {| onDisplay : FunctionPropDefinitionType, onRendered : FunctionPropDefinitionType, onRender : FunctionPropDefinitionType, + onPrerendered : FunctionPropDefinitionType, + onPrerender : FunctionPropDefinitionType, onClose : FunctionPropDefinitionType, onDestroy : FunctionPropDefinitionType, onResize : FunctionPropDefinitionType, @@ -299,6 +307,22 @@ export function getBuiltInProps() : BuiltInPropsDefinitionType { decorate: decorateOnce }, + onPrerendered: { + type: PROP_TYPE.FUNCTION, + required: false, + sendToChild: false, + default: defaultNoop, + decorate: decorateOnce + }, + + onPrerender: { + type: PROP_TYPE.FUNCTION, + required: false, + sendToChild: false, + default: defaultNoop, + decorate: decorateOnce + }, + onClose: { type: PROP_TYPE.FUNCTION, required: false, diff --git a/src/constants.js b/src/constants.js index 46e66e19..4d1d8270 100644 --- a/src/constants.js +++ b/src/constants.js @@ -41,15 +41,17 @@ export const DEFAULT_DIMENSIONS = { }; export const EVENT = { - RENDER: 'zoid-render', - RENDERED: 'zoid-rendered', - DISPLAY: 'zoid-display', - ERROR: 'zoid-error', - CLOSE: 'zoid-close', - DESTROY: 'zoid-destroy', - PROPS: 'zoid-props', - RESIZE: 'zoid-resize', - FOCUS: 'zoid-focus' + RENDER: 'zoid-render', + RENDERED: 'zoid-rendered', + PRERENDER: 'zoid-prerender', + PRERENDERED: 'zoid-prerendered', + DISPLAY: 'zoid-display', + ERROR: 'zoid-error', + CLOSE: 'zoid-close', + DESTROY: 'zoid-destroy', + PROPS: 'zoid-props', + RESIZE: 'zoid-resize', + FOCUS: 'zoid-focus' }; export const METHOD = { diff --git a/src/parent/parent.js b/src/parent/parent.js index 95e21c6e..bd262fb2 100644 --- a/src/parent/parent.js +++ b/src/parent/parent.js @@ -275,8 +275,10 @@ export function parentComponent({ uid, options, overrides = getDefaultO const setupEvents = () => { event.on(EVENT.RENDER, () => props.onRender()); + event.on(EVENT.PRERENDER, () => props.onPrerender()); event.on(EVENT.DISPLAY, () => props.onDisplay()); event.on(EVENT.RENDERED, () => props.onRendered()); + event.on(EVENT.PRERENDERED, () => props.onPrerendered()); event.on(EVENT.CLOSE, () => props.onClose()); event.on(EVENT.DESTROY, () => props.onDestroy()); event.on(EVENT.RESIZE, () => props.onResize()); @@ -795,6 +797,8 @@ export function parentComponent({ uid, options, overrides = getDefaultO return; } + event.trigger(EVENT.PRERENDER); + let prerenderWindow = proxyPrerenderWin.getWindow(); if (!prerenderWindow || !isSameDomain(prerenderWindow) || !isBlankDomain(prerenderWindow)) { @@ -829,6 +833,7 @@ export function parentComponent({ uid, options, overrides = getDefaultO event.on(EVENT.RENDERED, prerenderResizeListener.cancel); } + event.trigger(EVENT.PRERENDERED); }); }; const renderContainer : RenderContainer = (proxyContainer : ProxyObject, { proxyFrame, proxyPrerenderFrame, context, rerender } : RenderContainerOptions) : ZalgoPromise> => { diff --git a/test/tests/error.js b/test/tests/error.js index 1fe4c795..7afaef1a 100644 --- a/test/tests/error.js +++ b/test/tests/error.js @@ -328,7 +328,7 @@ describe('zoid error cases', () => { }); it('should error out when a prerender template is created with the incorrect document', () => { - return wrapPromise(({ expect }) => { + return wrapPromise(({ expect, avoid }) => { window.__component__ = () => { return zoid.create({ @@ -347,7 +347,9 @@ describe('zoid error cases', () => { const component = window.__component__(); return component({ - onDestroy: expect('onDestroy') + onDestroy: expect('onDestroy'), + onPrerender: expect('onPrerender'), + onPrerendered: avoid('onPrerendered') }).render(getBody()).catch(expect('catch')); }); }); diff --git a/test/tests/happy.jsx b/test/tests/happy.jsx index 269b239f..dbd96f2e 100644 --- a/test/tests/happy.jsx +++ b/test/tests/happy.jsx @@ -377,7 +377,10 @@ describe('zoid happy cases', () => { window.prerenderScriptLoaded = expect('prerenderScriptLoaded'); const component = window.__component__(); - return component().render(getBody()); + return component({ + onPrerender: expect('onPrerender'), + onPrerendered: expect('onPrerendered') + }).render(getBody()); }); }); @@ -405,7 +408,10 @@ describe('zoid happy cases', () => { window.prerenderScriptLoaded = expect('prerenderScriptLoaded'); const component = window.__component__(); - const instance = component(); + const instance = component({ + onPrerender: expect('onPrerender'), + onPrerendered: expect('onPrerendered') + }); return runOnClick(() => { return instance.render(getBody(), zoid.CONTEXT.POPUP);