@shopify/app-bridge-host
Version:
App Bridge Host contains components and middleware to be consumed by the app's host, as well as the host itself. The middleware and `Frame` component are responsible for facilitating communication between the client and host, and used to act on actions se
142 lines (135 loc) • 6.51 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var compose = require('@shopify/react-compose');
var Actions = require('@shopify/app-bridge-core/actions');
var safeRedirect = require('@shopify/app-bridge-core/validate/safe-redirect');
var components_utilities_appUrl = require('../utilities/appUrl.js');
var withFeature = require('../../withFeature.js');
var store_reducers_embeddedApp_navigation_index = require('../../store/reducers/embeddedApp/navigation/index.js');
var helpers = require('../../store/middlewares/mobile/helpers.js');
var useHostContext = require('../../hooks/useHostContext.js');
var useRouterContext = require('../../hooks/useRouterContext.js');
var components_Navigation_utilities_getResourceUrl = require('./utilities/getResourceUrl.js');
var components_Navigation_utilities_resolver = require('./utilities/resolver.js');
var components_Navigation_utilities_stripTrailingSlash = require('./utilities/stripTrailingSlash.js');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var compose__default = /*#__PURE__*/_interopDefault(compose);
/**
* Handles all actions for the Navigation feature
* @public
* @requires RouterContext
* */
function Navigation(props) {
var notifyRouteChange = useHostContext.useHostContext().notifyRouteChange;
var routerContext = useRouterContext.useRouterContext();
var updateAction = props.store.updateAction;
React.useEffect(function () {
var resolveAppUrl = props.resolveAppUrl, actions = props.actions, updateAction = props.store.updateAction;
var appRoot = routerContext.appRoot, hostname = routerContext.hostname, history = routerContext.history, location = routerContext.location, href = routerContext.href, open = routerContext.open;
var currentUrl = "".concat(location.pathname).concat(location.search);
if (!updateAction) {
return;
}
var newUrl;
var newContext;
var type = updateAction.type, target = updateAction.target, payload = updateAction.payload;
switch (target) {
case Actions.Redirect.Action.REMOTE:
if (isRemotePayload(payload)) {
newContext = payload.newContext;
newUrl = payload.url;
if (!newContext) {
if (newUrl === href) {
actions.completeRouteUpdate();
return;
}
var urlParts = new URL(newUrl);
if (urlParts.hostname === hostname && !helpers.isMobile()) {
history.push("".concat(urlParts.pathname).concat(urlParts.search));
}
else if (safeRedirect.isSafe(newUrl)) {
open(newUrl);
}
actions.completeRouteUpdate();
return;
}
}
break;
case Actions.Redirect.Action.APP:
if (isAppPayload(payload)) {
var appUrlResolver = resolveAppUrl || components_Navigation_utilities_resolver.resolver.app;
newUrl = appUrlResolver(appRoot, components_utilities_appUrl.normalizeRelativePath(payload.path));
newUrl = components_utilities_appUrl.removeRestrictedParams(newUrl);
newUrl = components_Navigation_utilities_stripTrailingSlash.stripTrailingSlash(newUrl);
}
break;
case Actions.Redirect.Action.ADMIN_PATH:
if (isAdminPathPayload(payload)) {
newUrl = "".concat(components_Navigation_utilities_resolver.resolver.home()).concat(payload.path);
newContext = payload.newContext;
}
break;
case Actions.Redirect.Action.ADMIN_SECTION:
if (isAdminSectionPayload(payload)) {
newUrl = components_Navigation_utilities_getResourceUrl.default(components_Navigation_utilities_resolver.resolver, payload.section);
newContext = payload.newContext;
}
break;
}
if (newContext) {
var absNewUrl = new URL(newUrl !== null && newUrl !== void 0 ? newUrl : '', href).href;
open(absNewUrl, '_blank');
actions.completeRouteUpdate();
return;
}
if (!newUrl || currentUrl === newUrl) {
actions.completeRouteUpdate();
return;
}
switch (type) {
case Actions.History.Action.PUSH: {
notifyRouteChange({ newUrl: newUrl, shouldNotifyClient: false });
history.push(newUrl);
break;
}
case Actions.History.Action.REPLACE: {
notifyRouteChange({ newUrl: newUrl, shouldNotifyClient: false });
history.replace(newUrl);
break;
}
default: {
// This fixes ABv3 and ABN Navigation Menu issue. See https://github.com/Shopify/app-bridge-next-internal/issues/52
var isReplaceAction = target === Actions.Redirect.Action.APP && payload.replace;
notifyRouteChange({ newUrl: newUrl, shouldNotifyClient: true });
if (isReplaceAction) {
history.replace(newUrl);
}
else {
history.push(newUrl);
}
}
}
actions.completeRouteUpdate();
}, [updateAction]);
return null;
}
function isAdminPathPayload(payload) {
return payload && Object.prototype.hasOwnProperty.call(payload, 'path');
}
function isAppPayload(payload) {
return payload && Object.prototype.hasOwnProperty.call(payload, 'path');
}
function isRemotePayload(payload) {
return payload && Object.prototype.hasOwnProperty.call(payload, 'url');
}
function isAdminSectionPayload(payload) {
return payload && Object.prototype.hasOwnProperty.call(payload, 'section');
}
/**
* The Navigation feature with its reducer, actions and a navigation actions handler
* @public
* */
var Navigation$1 = compose__default.default(withFeature.default(store_reducers_embeddedApp_navigation_index.feature))(Navigation);
exports.Navigation = Navigation;
exports.default = Navigation$1;