mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-28 21:33:24 +03:00
5d59670ac3
no issue - Opted in to use explicit `hisotry.replaceState` and setting iframe's `src` using assignment instead of tracking it through computed property. This allows for tighter control over when iframe's history is updated which was causing problems when `src` was bound to computed property - Added billing page metadata. This way browser history records appear with nicer signature - Removed "update button" iframe and rewrote "global iframe" to not use modals. This allows to have single iframe on a page, which simplifies `postMessage` communication and preserve history inside iframe to be able to navigate it after closure - Added route change handler responding to BMA app route changes. Allows to sync browser URL visible to the user with active route in BMA iframe. The sync is based on `hisory.replaceState` method that makes sure singular history records are kept in the browser history - Added nested wildcard billing route. This is meant to catch all the nested routes inside of BMA iframe
92 lines
2.9 KiB
JavaScript
92 lines
2.9 KiB
JavaScript
import Service from '@ember/service';
|
|
import {inject as service} from '@ember/service';
|
|
|
|
export default Service.extend({
|
|
router: service(),
|
|
config: service(),
|
|
ghostPaths: service(),
|
|
|
|
billingRouteRoot: '#/billing',
|
|
billingWindowOpen: false,
|
|
subscription: null,
|
|
previousRoute: null,
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
|
|
if (this.config.get('billingUrl')) {
|
|
window.addEventListener('message', (event) => {
|
|
if (event && event.data && event.data.route) {
|
|
this.handleRouteChangeInIframe(event.data.route);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
handleRouteChangeInIframe(destinationRoute) {
|
|
if (this.get('billingWindowOpen')) {
|
|
let billingRoute = this.get('billingRouteRoot');
|
|
|
|
if (destinationRoute !== '/') {
|
|
billingRoute += destinationRoute;
|
|
}
|
|
|
|
if (window.location.hash !== billingRoute) {
|
|
window.history.replaceState(window.history.state, '', billingRoute);
|
|
}
|
|
}
|
|
},
|
|
|
|
getIframeURL() {
|
|
let url = this.config.get('billingUrl');
|
|
|
|
if (window.location.hash && window.location.hash.includes(this.get('billingRouteRoot'))) {
|
|
let destinationRoute = window.location.hash.replace(this.get('billingRouteRoot'), '');
|
|
|
|
if (destinationRoute) {
|
|
url += destinationRoute;
|
|
}
|
|
}
|
|
|
|
return url;
|
|
},
|
|
|
|
// Controls billing window modal visibility and sync of the URL visible in browser
|
|
// and the URL opened on the iframe. It is responsible to non user triggered iframe opening,
|
|
// for example: by entering "/billing" route in the URL or using history navigation (back and forward)
|
|
setBillingWindowOpen(value) {
|
|
let billingIframe = this.getBillingIframe();
|
|
|
|
if (billingIframe && value) {
|
|
billingIframe.contentWindow.location.replace(this.getIframeURL());
|
|
}
|
|
|
|
this.set('billingWindowOpen', value);
|
|
},
|
|
|
|
// Controls navigation to billing window modal which is triggered from the application UI.
|
|
// For example: pressing "View Billing" link in navigation menu. It's main side effect is
|
|
// remembering the route from which the action has been triggered - "previousRoute" so it
|
|
// could be reused when closing billing window
|
|
openBillingWindow(currentRoute, childRoute) {
|
|
this.set('previousRoute', currentRoute);
|
|
|
|
// Ensures correct "getIframeURL" calculation when syncing iframe location
|
|
// in setBillingWindowOpen
|
|
window.location.hash = childRoute || '/billing';
|
|
|
|
this.router.transitionTo(childRoute || '/billing');
|
|
},
|
|
|
|
closeBillingWindow() {
|
|
this.set('billingWindowOpen', false);
|
|
|
|
let transitionRoute = this.get('previousRoute') || '/';
|
|
this.router.transitionTo(transitionRoute);
|
|
},
|
|
|
|
getBillingIframe() {
|
|
return document.getElementById('billing-frame');
|
|
}
|
|
});
|