aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant
diff options
context:
space:
mode:
Diffstat (limited to 'packages/instant')
-rw-r--r--packages/instant/public/index.html6
-rw-r--r--packages/instant/src/index.umd.ts116
2 files changed, 87 insertions, 35 deletions
diff --git a/packages/instant/public/index.html b/packages/instant/public/index.html
index 253cbb194..557cfa3dc 100644
--- a/packages/instant/public/index.html
+++ b/packages/instant/public/index.html
@@ -27,6 +27,10 @@
<body>
<div id="zeroExInstantContainer"></div>
<script>
+ // Simulate history
+ window.history.pushState({ page: 1 }, '0x Instant');
+ window.history.pushState({ page: 2 }, '0x Instant');
+ window.history.pushState({ page: 3 }, '0x Instant');
const removeUndefined = (obj) => {
for (let k in obj) if (obj[k] === undefined) delete obj[k];
return obj;
@@ -128,8 +132,10 @@
availableAssetDatas: availableAssetDatasString ? JSON.parse(availableAssetDatasString) : undefined,
defaultSelectedAssetData: queryParams.getQueryParamValue('defaultSelectedAssetData'),
affiliateInfo: affiliateInfoOverride,
+ shouldDisablePushToHistory: !!queryParams.getQueryParamValue('shouldDisablePushToHistory'),
}
const renderOptions = Object.assign({}, renderOptionsDefaults, removeUndefined(renderOptionsOverrides));
+ window.onpopstate = () => console.log('Integrators onpopstate called');
zeroExInstant.render(renderOptions);
</script>
</body>
diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts
index 0274db30c..64f888e00 100644
--- a/packages/instant/src/index.umd.ts
+++ b/packages/instant/src/index.umd.ts
@@ -5,52 +5,98 @@ import * as ReactDOM from 'react-dom';
import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR, INJECTED_DIV_CLASS, INJECTED_DIV_ID } from './constants';
import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index';
import { assert } from './util/assert';
+import { util } from './util/util';
-export const render = (props: ZeroExInstantOverlayProps, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => {
- assert.isValidOrderSource('orderSource', props.orderSource);
- if (!_.isUndefined(props.defaultSelectedAssetData)) {
- assert.isHexString('defaultSelectedAssetData', props.defaultSelectedAssetData);
+export interface ZeroExInstantConfig extends ZeroExInstantOverlayProps {
+ shouldDisablePushToHistory?: boolean;
+}
+
+export const render = (config: ZeroExInstantConfig, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => {
+ assert.isValidOrderSource('orderSource', config.orderSource);
+ if (!_.isUndefined(config.defaultSelectedAssetData)) {
+ assert.isHexString('defaultSelectedAssetData', config.defaultSelectedAssetData);
+ }
+ if (!_.isUndefined(config.additionalAssetMetaDataMap)) {
+ assert.isValidAssetMetaDataMap('additionalAssetMetaDataMap', config.additionalAssetMetaDataMap);
}
- if (!_.isUndefined(props.additionalAssetMetaDataMap)) {
- assert.isValidAssetMetaDataMap('props.additionalAssetMetaDataMap', props.additionalAssetMetaDataMap);
+ if (!_.isUndefined(config.defaultAssetBuyAmount)) {
+ assert.isNumber('defaultAssetBuyAmount', config.defaultAssetBuyAmount);
}
- if (!_.isUndefined(props.defaultAssetBuyAmount)) {
- assert.isNumber('props.defaultAssetBuyAmount', props.defaultAssetBuyAmount);
+ if (!_.isUndefined(config.networkId)) {
+ assert.isNumber('networkId', config.networkId);
}
- if (!_.isUndefined(props.networkId)) {
- assert.isNumber('props.networkId', props.networkId);
+ if (!_.isUndefined(config.availableAssetDatas)) {
+ assert.areValidAssetDatas('availableAssetDatas', config.availableAssetDatas);
}
- if (!_.isUndefined(props.availableAssetDatas)) {
- assert.areValidAssetDatas('availableAssetDatas', props.availableAssetDatas);
+ if (!_.isUndefined(config.onClose)) {
+ assert.isFunction('onClose', config.onClose);
}
- if (!_.isUndefined(props.onClose)) {
- assert.isFunction('props.onClose', props.onClose);
+ if (!_.isUndefined(config.zIndex)) {
+ assert.isNumber('zIndex', config.zIndex);
}
- if (!_.isUndefined(props.zIndex)) {
- assert.isNumber('props.zIndex', props.zIndex);
+ if (!_.isUndefined(config.affiliateInfo)) {
+ assert.isValidAffiliateInfo('affiliateInfo', config.affiliateInfo);
}
- if (!_.isUndefined(props.affiliateInfo)) {
- assert.isValidAffiliateInfo('props.affiliateInfo', props.affiliateInfo);
+ if (!_.isUndefined(config.provider)) {
+ assert.isWeb3Provider('provider', config.provider);
}
- if (!_.isUndefined(props.provider)) {
- assert.isWeb3Provider('props.provider', props.provider);
+ if (!_.isUndefined(config.shouldDisablePushToHistory)) {
+ assert.isBoolean('shouldDisablePushToHistory', config.shouldDisablePushToHistory);
}
assert.isString('selector', selector);
- const appendToIfExists = document.querySelector(selector);
- assert.assert(!_.isNull(appendToIfExists), `Could not find div with selector: ${selector}`);
- const appendTo = appendToIfExists as Element;
- const injectedDiv = document.createElement('div');
- injectedDiv.setAttribute('id', INJECTED_DIV_ID);
- injectedDiv.setAttribute('class', INJECTED_DIV_CLASS);
- appendTo.appendChild(injectedDiv);
- const instantOverlayProps = {
- ...props,
- onClose: () => {
- appendTo.removeChild(injectedDiv);
- if (!_.isUndefined(props.onClose)) {
- props.onClose();
+ // Render instant and return a callback that allows you to remove it from the DOM.
+ const renderInstant = () => {
+ const appendToIfExists = document.querySelector(selector);
+ assert.assert(!_.isNull(appendToIfExists), `Could not find div with selector: ${selector}`);
+ const appendTo = appendToIfExists as Element;
+ const injectedDiv = document.createElement('div');
+ injectedDiv.setAttribute('id', INJECTED_DIV_ID);
+ injectedDiv.setAttribute('class', INJECTED_DIV_CLASS);
+ appendTo.appendChild(injectedDiv);
+ const closeInstant = () => {
+ if (!_.isUndefined(config.onClose)) {
+ config.onClose();
}
- },
+ appendTo.removeChild(injectedDiv);
+ };
+ const instantOverlayProps = {
+ ...config,
+ // If we are using the history API, just go back to close
+ onClose: () => (config.shouldDisablePushToHistory ? closeInstant() : window.history.back()),
+ };
+ ReactDOM.render(React.createElement(ZeroExInstantOverlay, instantOverlayProps), injectedDiv);
+ return closeInstant;
};
- ReactDOM.render(React.createElement(ZeroExInstantOverlay, instantOverlayProps), injectedDiv);
+ if (config.shouldDisablePushToHistory) {
+ if (!isInstantRendered()) {
+ renderInstant();
+ }
+ } else {
+ // Before we render, push to history saying that instant is showing for this part of the history.
+ window.history.pushState({ zeroExInstantShowing: true }, '0x Instant');
+ let removeInstant = renderInstant();
+
+ let prevOnPopState = util.boundNoop;
+ if (window.onpopstate) {
+ prevOnPopState = window.onpopstate.bind(window);
+ }
+ window.onpopstate = (e: PopStateEvent) => {
+ // Don't override integrators handler.
+ prevOnPopState(e);
+ // e.state represents the new state
+ if (e.state && e.state.zeroExInstantShowing) {
+ // We have returned to a history state that expects instant to be rendered.
+ if (!isInstantRendered()) {
+ removeInstant = renderInstant();
+ }
+ } else {
+ // History has changed to a different state.
+ if (isInstantRendered()) {
+ removeInstant();
+ }
+ }
+ };
+ }
};
+
+const isInstantRendered = (): boolean => !!document.getElementById(INJECTED_DIV_ID);