@rebilly/instruments 3.15.6-beta.0 → 3.16.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/.eslintrc.js +7 -0
  2. package/dist/index.js +10 -10
  3. package/dist/index.min.js +10 -10
  4. package/package.json +6 -4
  5. package/service/prefetch/config.mjs +8 -0
  6. package/service/prefetch/metadata.mjs +35 -0
  7. package/service/prefetch/prefetch.mjs +9 -0
  8. package/src/data/payment-methods.json +2886 -0
  9. package/src/functions/mount/fetch-data.js +2 -8
  10. package/src/functions/mount/mount.spec.js +1 -1
  11. package/src/functions/mount/setup-options.js +31 -19
  12. package/src/functions/mount/setup-options.spec.js +66 -1
  13. package/src/functions/purchase.js +18 -8
  14. package/src/functions/purchase.spec.js +4 -1
  15. package/src/storefront/ready-to-pay.js +2 -2
  16. package/src/storefront/ready-to-pay.spec.js +6 -1
  17. package/src/storefront/summary.js +9 -0
  18. package/src/storefront/summary.spec.js +6 -6
  19. package/src/views/common/iframe/base-iframe.js +0 -1
  20. package/src/views/common/iframe/events/change-iframe-src-handler.js +6 -0
  21. package/src/views/common/iframe/events/dispatch-event-handler.js +8 -0
  22. package/src/views/common/iframe/events/resize-component-handler.js +9 -0
  23. package/src/views/common/iframe/events/show-error-handler.js +5 -0
  24. package/src/views/common/iframe/events/stop-loader-handler.js +9 -0
  25. package/src/views/common/iframe/events/update-coupons-handler.js +18 -0
  26. package/src/views/common/iframe/modal-iframe.js +8 -9
  27. package/src/views/common/iframe/view-iframe.js +8 -7
  28. package/src/views/method-selector/get-payment-methods.js +1 -1
  29. package/src/views/method-selector/index.js +1 -0
  30. package/src/views/result.js +1 -0
  31. package/src/views/summary.js +1 -0
  32. package/src/views/common/iframe/event-listeners.js +0 -50
@@ -21,6 +21,7 @@ export class DataInstance {
21
21
  });
22
22
 
23
23
  this.money = state.options?.money || null;
24
+ this.couponIds = [];
24
25
  }
25
26
 
26
27
  get amountAndCurrency() {
@@ -139,11 +140,6 @@ export async function fetchData({
139
140
  availableInstrumentsPromise = fetchInstruments({state});
140
141
  }
141
142
 
142
- const paymentMethodsMetadataPromise =
143
- state.storefront.rebilly.paymentMethods.getAll().then(
144
- ({ items }) => items.map(({fields}) => fields)
145
- );
146
-
147
143
  if (state.options?.transactionId) {
148
144
  state.data.transaction = await fetchTransaction({data: {
149
145
  id: state.options.transactionId
@@ -162,9 +158,7 @@ export async function fetchData({
162
158
  }
163
159
 
164
160
  const readyToPayPromise = state.data?.readyToPay ??
165
- accountPromise.then(() => fetchReadyToPay({
166
- riskMetadata, state, paymentMethodsMetadataPromise
167
- }));
161
+ accountPromise.then(() => fetchReadyToPay({riskMetadata, state}));
168
162
 
169
163
  const previewPurchasePromise = state.options.items ?
170
164
  fetchSummary({ state }) : null;
@@ -37,7 +37,7 @@ describe('RebillyInstruments instance', () => {
37
37
 
38
38
  // Mounts form and summary
39
39
  const summarySelector = document.querySelector('.summary-selector');
40
- expect(summarySelector.innerHTML).toContain('<iframe name="rebilly-instruments-summary" class="rebilly-instruments-iframe" loading="lazy" allow="payment" scrolling="no" src="https://forms.local.rebilly.dev:3000/summary"></iframe>');
40
+ expect(summarySelector.innerHTML).toContain('<iframe name="rebilly-instruments-summary" class="rebilly-instruments-iframe" loading="lazy" allow="payment" src="https://forms.local.rebilly.dev:3000/summary"></iframe>');
41
41
 
42
42
  // Theme config overrides initial styles
43
43
  const STYLE_VARS = document.querySelectorAll('style[type="text/css"]')[0];
@@ -40,10 +40,20 @@ export const defaults = {
40
40
  transactionType: 'purchase',
41
41
  features: {
42
42
  autoConfirmation: true,
43
- autoResult: true
43
+ autoResult: true,
44
+ showCoupons: null,
44
45
  }
45
46
  };
46
47
 
48
+ export function sanitizeOptions(options) {
49
+ // TODO: Additional sanitization
50
+
51
+ // cast options to be only json object
52
+ return JSON.parse(
53
+ JSON.stringify(options)
54
+ )
55
+ }
56
+
47
57
  export function validateOptions(options) {
48
58
  // TODO: validate more options
49
59
  const purchaseData = [
@@ -71,37 +81,39 @@ export default ({
71
81
  options = {}
72
82
  } = {}) => {
73
83
 
74
- validateOptions(options);
84
+ const sanitizedOptions = sanitizeOptions(options)
85
+
86
+ validateOptions(sanitizedOptions);
75
87
 
76
88
  const _computed = {
77
- paymentMethodsUrl: options._dev
78
- ? options._dev.paymentMethodsUrl || 'https://forms.local.rebilly.dev:3000'
89
+ paymentMethodsUrl: sanitizedOptions._dev
90
+ ? sanitizedOptions._dev.paymentMethodsUrl || 'https://forms.local.rebilly.dev:3000'
79
91
  : 'https://forms.secure-payments.app'
80
92
  };
81
93
 
82
94
  const combinedOptions = merge({...defaults}, {
83
- apiMode: options.apiMode,
84
- i18n: options.i18n,
85
- theme: options.theme,
86
- css: options.css,
87
- locale: options.locale,
88
- countryCode: options.countryCode,
89
- features: options.features,
90
- paymentInstruments: options.paymentInstruments,
91
- transactionType: options.transactionType,
95
+ apiMode: sanitizedOptions.apiMode,
96
+ i18n: sanitizedOptions.i18n,
97
+ theme: sanitizedOptions.theme,
98
+ css: sanitizedOptions.css,
99
+ locale: sanitizedOptions.locale,
100
+ countryCode: sanitizedOptions.countryCode,
101
+ features: sanitizedOptions.features,
102
+ paymentInstruments: sanitizedOptions.paymentInstruments,
103
+ transactionType: sanitizedOptions.transactionType,
92
104
  _computed
93
105
  });
94
106
 
95
- if (options.publishableKey) {
107
+ if (sanitizedOptions.publishableKey) {
96
108
  Object.entries({
97
- organizationId: options.organizationId,
98
- publishableKey: options.publishableKey,
99
- websiteId: options.websiteId,
109
+ organizationId: sanitizedOptions.organizationId,
110
+ publishableKey: sanitizedOptions.publishableKey,
111
+ websiteId: sanitizedOptions.websiteId,
100
112
  }).forEach(([key, value]) => {
101
113
  combinedOptions[key] = value;
102
114
  });
103
- } else if (options.jwt) {
104
- combinedOptions.jwt = options.jwt;
115
+ } else if (sanitizedOptions.jwt) {
116
+ combinedOptions.jwt = sanitizedOptions.jwt;
105
117
  const {
106
118
  merchant: organizationId,
107
119
  claims: {
@@ -1,5 +1,5 @@
1
1
  import { RenderMockRebillyInstruments } from 'tests/mocks/rebilly-instruments-mock';
2
- import setupOptions, {validateOptions, defaults} from './setup-options';
2
+ import setupOptions, {validateOptions, defaults, sanitizeOptions} from './setup-options';
3
3
 
4
4
  describe('Setup mount options', () => {
5
5
  it("should fill with default options", () => {
@@ -56,4 +56,69 @@ describe('Validate mount options', () => {
56
56
  }
57
57
  expect(error.message).toBe('Must provide only one purchase data type');
58
58
  });
59
+ });
60
+
61
+ describe('sanitize mount options', () => {
62
+ it('should make into object', () => {
63
+ class options {
64
+ constructor() {
65
+ this.items = [
66
+ {
67
+ planId: "test-plan-id",
68
+ quantity: 1
69
+ }
70
+ ];
71
+ }
72
+ }
73
+
74
+ expect(setupOptions({
75
+ options: new options()
76
+ })).toMatchObject(defaults);
77
+ });
78
+
79
+ it('should merge class and default object', () => {
80
+ class options {
81
+ constructor() {
82
+ this.items = [
83
+ {
84
+ planId: "test-plan-id",
85
+ quantity: 1
86
+ }
87
+ ];
88
+
89
+ this.features = {
90
+ showCoupons: ['summary'],
91
+ other: 'key'
92
+ }
93
+ }
94
+ }
95
+
96
+ expect(setupOptions({
97
+ options: new options()
98
+ })).toMatchObject(
99
+ expect.objectContaining({
100
+ features: expect.objectContaining({
101
+ ...defaults.features,
102
+ showCoupons: ['summary'],
103
+ other: 'key'
104
+ })
105
+ })
106
+ );
107
+ });
108
+
109
+ it ('should sanitize class to object', () => {
110
+ class OptionsClass {
111
+ constructor() {
112
+ this.key = "value"
113
+ }
114
+ }
115
+
116
+ const newOptions = new OptionsClass();
117
+
118
+ expect(sanitizeOptions(newOptions)).toMatchObject({
119
+ key: 'value'
120
+ });
121
+ expect(sanitizeOptions(newOptions)).toBeInstanceOf(Object);
122
+ expect(sanitizeOptions(newOptions)).not.toBeInstanceOf(OptionsClass);
123
+ })
59
124
  });
@@ -39,6 +39,10 @@ export async function makePayment({ state, payload }) {
39
39
  data.currency = state.options.money.currency;
40
40
  }
41
41
 
42
+ if (state.data.couponIds && Array.isArray(state.data.couponIds)) {
43
+ data.couponIds = state.data.couponIds
44
+ }
45
+
42
46
  let { fields } = await postPayment({
43
47
  state,
44
48
  data
@@ -57,16 +61,22 @@ export async function makePayment({ state, payload }) {
57
61
  }
58
62
 
59
63
  export async function makePurchase({ state, payload }) {
64
+ const data = {
65
+ websiteId: state.options.websiteId,
66
+ items: state.options.items,
67
+ paymentInstruction: {
68
+ token: payload._raw.id
69
+ },
70
+ ...payload
71
+ };
72
+
73
+ if (state.data.couponIds && Array.isArray(state.data.couponIds)) {
74
+ data.couponIds = state.data.couponIds
75
+ }
76
+
60
77
  const { fields } = await postPurchase({
61
78
  state,
62
- data: {
63
- websiteId: state.options.websiteId,
64
- items: state.options.items,
65
- paymentInstruction: {
66
- token: payload._raw.id
67
- },
68
- ...payload
69
- }
79
+ data
70
80
  });
71
81
  return fields;
72
82
  }
@@ -52,6 +52,7 @@ describe('RebillyInstruments purchase', () => {
52
52
  items: rebillyInstruments.state.options.items,
53
53
  billingAddress,
54
54
  deliveryAddress,
55
+ couponIds: [],
55
56
  paymentInstruction: {
56
57
  token: token.id
57
58
  }
@@ -60,7 +61,9 @@ describe('RebillyInstruments purchase', () => {
60
61
  await rebillyInstruments.purchase(purchasePayload);
61
62
 
62
63
  expect(spyStorefrontPurchase).toBeCalledTimes(1);
63
- expect(spyStorefrontPurchase).toBeCalledWith(expect.objectContaining({ data: purchasePayloadParsed }));
64
+ expect(spyStorefrontPurchase).toBeCalledWith({
65
+ data: expect.objectContaining(purchasePayloadParsed)
66
+ });
64
67
 
65
68
  expect(Events.purchaseCompleted.dispatch).toBeCalledTimes(1);
66
69
 
@@ -1,11 +1,11 @@
1
1
  import { collectData } from '@rebilly/risk-data-collector';
2
+ import paymentMethodsFile from '../data/payment-methods.json';
2
3
  import ReadyToPayModel from './models/ready-to-pay-model';
3
4
  import { Endpoint } from './index';
4
5
 
5
6
  export async function fetchReadyToPay({
6
7
  state,
7
8
  riskMetadata = null,
8
- paymentMethodsMetadataPromise = Promise.resolve([])
9
9
  }) {
10
10
  return Endpoint({state}, async () => {
11
11
  if (!riskMetadata) {
@@ -42,7 +42,7 @@ export async function fetchReadyToPay({
42
42
  }
43
43
 
44
44
  const { fields: readyToPayFields } = await state.storefront.purchase.readyToPay({ data });
45
- const paymentMethodsMetadata = await paymentMethodsMetadataPromise;
45
+ const paymentMethodsMetadata = [...paymentMethodsFile];
46
46
 
47
47
  return Object.values(readyToPayFields)
48
48
  // Remove result for "old" paypal method
@@ -5,6 +5,8 @@ import { storefrontURL } from 'tests/mocks/storefront-api-mock';
5
5
  import { fetchReadyToPay } from './ready-to-pay';
6
6
  import ReadyToPayModel from './models/ready-to-pay-model';
7
7
  import { expectConfigurationError } from 'tests/async-utilities';
8
+ import PaymentMetadataModel from './models/payment-metadata';
9
+ import paymentMethodsFile from '@/data/payment-methods.json';
8
10
 
9
11
  describe('Storefront API Ready to Pay', () => {
10
12
  it('can fetch ready to pay', async () => {
@@ -26,6 +28,8 @@ describe('Storefront API Ready to Pay', () => {
26
28
  ]
27
29
  };
28
30
 
31
+ const paymentCardMetadata = [...paymentMethodsFile].find(method => method.apiName === 'payment-card');
32
+
29
33
  when(post(`${storefrontURL}/ready-to-pay`)).thenReturn(
30
34
  ok(readyToPayPayload)
31
35
  );
@@ -52,7 +56,8 @@ describe('Storefront API Ready to Pay', () => {
52
56
  expect(response).toEqual([
53
57
  new ReadyToPayModel({
54
58
  index: 0,
55
- ...readyToPayPayload[0]
59
+ ...readyToPayPayload[0],
60
+ metadata: new PaymentMetadataModel(paymentCardMetadata),
56
61
  })
57
62
  ]);
58
63
  });
@@ -13,6 +13,11 @@ export async function fetchSummary({ data = null, state = null } = {}) {
13
13
 
14
14
  if (state.options?.items) {
15
15
  payload.data.items = state.options.items;
16
+ } else {
17
+ payload.data.items = state.data.summaryLineItems.map(item => ({
18
+ planId: item.planId,
19
+ quantity: item.quantity,
20
+ }));
16
21
  }
17
22
 
18
23
  if (state.data?.amountAndCurrency) {
@@ -29,6 +34,10 @@ export async function fetchSummary({ data = null, state = null } = {}) {
29
34
  payload.data.deliveryAddress = data.deliveryAddress;
30
35
  }
31
36
 
37
+ if(state.data?.couponIds) {
38
+ payload.data.couponIds = state.data.couponIds;
39
+ }
40
+
32
41
  const { fields: summaryFields } = await state.storefront.purchase.preview(
33
42
  payload
34
43
  );
@@ -40,10 +40,10 @@ describe('Storefront API Summary', () => {
40
40
 
41
41
  expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
42
42
  expect(instance.storefront.purchase.preview).toBeCalledWith({
43
- data: {
43
+ data: expect.objectContaining({
44
44
  items: options.items,
45
45
  websiteId: options.websiteId
46
- }
46
+ })
47
47
  });
48
48
  expect(response).toBeInstanceOf(SummaryModel);
49
49
  expect(response).toEqual(new SummaryModel(testSummary));
@@ -78,11 +78,11 @@ describe('Storefront API Summary', () => {
78
78
 
79
79
  expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
80
80
  expect(instance.storefront.purchase.preview).toBeCalledWith({
81
- data: {
81
+ data: expect.objectContaining({
82
82
  items: options.items,
83
83
  websiteId: options.websiteId,
84
84
  billingAddress
85
- }
85
+ })
86
86
  });
87
87
  });
88
88
 
@@ -115,11 +115,11 @@ describe('Storefront API Summary', () => {
115
115
 
116
116
  expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
117
117
  expect(instance.storefront.purchase.preview).toBeCalledWith({
118
- data: {
118
+ data: expect.objectContaining({
119
119
  items: options.items,
120
120
  websiteId: options.websiteId,
121
121
  deliveryAddress
122
- }
122
+ })
123
123
  });
124
124
  });
125
125
 
@@ -45,7 +45,6 @@ export default class BaseIframe {
45
45
  appendChild: (iframe) => {
46
46
  iframe.setAttribute('loading', 'lazy');
47
47
  iframe.setAttribute('allow', 'payment');
48
- iframe.setAttribute('scrolling', 'no');
49
48
  iframe.allowPaymentRequest = true;
50
49
  this.container.appendChild(iframe);
51
50
  },
@@ -0,0 +1,6 @@
1
+ export function changeIframeSrcHandler(iframe) {
2
+ iframe.component.on(`${iframe.name}-change-iframe-src`, (url = null) => {
3
+ iframe.component.frame.src = url;
4
+ iframe.component.frame.style.height = '75vh';
5
+ });
6
+ }
@@ -0,0 +1,8 @@
1
+ import camelCase from 'lodash.camelcase';
2
+ import Events from '../../../../events';
3
+
4
+ export function dispatchEventHandler(iframe) {
5
+ iframe.component.on(`${iframe.name}-dispatch`, ({ event, detail }) => {
6
+ Events[camelCase(event).replace(/-/, '')].dispatch(detail);
7
+ });
8
+ }
@@ -0,0 +1,9 @@
1
+ export function resizeComponentHandler(iframe) {
2
+ let prevHeight = '';
3
+ iframe.component.on(`${iframe.name}-resize-frame`, (height) => {
4
+ if (height !== prevHeight) {
5
+ prevHeight = height;
6
+ iframe.component.frame.style.height = height;
7
+ }
8
+ });
9
+ }
@@ -0,0 +1,5 @@
1
+ import { showError } from '../../../errors';
2
+
3
+ export function showErrorHandler(iframe) {
4
+ iframe.component.on(`${iframe.name}-show-error`, showError);
5
+ }
@@ -0,0 +1,9 @@
1
+ export function stopLoaderHandler(iframe, data) {
2
+ iframe.component.on(`${iframe.name}-stop-loading`, (id) => {
3
+ let {section} = data;
4
+ if (!section) {
5
+ section = id.includes('summary') ? 'summary' : 'form';
6
+ }
7
+ data.loader?.stopLoading({ section, id });
8
+ });
9
+ }
@@ -0,0 +1,18 @@
1
+ export function updateCouponsHandler(iframe) {
2
+ iframe.component.on(`${iframe.name}-update-coupon`, async ({
3
+ couponIds,
4
+ previewPurchase
5
+ } = {}) => {
6
+ iframe.state.data.couponIds = couponIds;
7
+ iframe.state.data.previewPurchase = previewPurchase;
8
+
9
+ const updateModel = {
10
+ data: iframe.state.data.toPostmatesModel(),
11
+ options: iframe.state.options
12
+ }
13
+ if (iframe.state.iframeComponents.summary) {
14
+ iframe.state.iframeComponents.summary.component.call('update', updateModel);
15
+ }
16
+ iframe.state.iframeComponents.form.component.call('update', updateModel);
17
+ });
18
+ }
@@ -1,11 +1,10 @@
1
1
  import BaseIframe from './base-iframe';
2
- import {
3
- dispatchRebillyInsturmentEventHandler,
4
- resizeComponentHandler,
5
- changeIframeSrcHandler,
6
- stopLoaderHandler,
7
- showErrorHandler
8
- } from './event-listeners';
2
+
3
+ import { changeIframeSrcHandler } from './events/change-iframe-src-handler';
4
+ import { resizeComponentHandler } from './events/resize-component-handler';
5
+ import { dispatchEventHandler } from './events/dispatch-event-handler';
6
+ import { showErrorHandler } from './events/show-error-handler';
7
+ import { stopLoaderHandler } from './events/stop-loader-handler';
9
8
 
10
9
  export class ModalIframe extends BaseIframe {
11
10
  constructor(args = {}) {
@@ -13,7 +12,7 @@ export class ModalIframe extends BaseIframe {
13
12
  }
14
13
 
15
14
  bindEventListeners({ close = () => {}, loader } = {}) {
16
- dispatchRebillyInsturmentEventHandler(this);
15
+ dispatchEventHandler(this);
17
16
  resizeComponentHandler(this);
18
17
  changeIframeSrcHandler(this);
19
18
  stopLoaderHandler(this, {
@@ -28,7 +27,7 @@ export class ModalIframe extends BaseIframe {
28
27
  close(...args);
29
28
  });
30
29
 
31
- // Close modal via postMessage (specifically during approal url flow)
30
+ // Close modal via postMessage (specifically during approval url flow)
32
31
  window.addEventListener('message', async (event) => {
33
32
  if(event.data === 'rebilly-instruments-approval-url-close') {
34
33
  if (this.state.options.transactionType === 'purchase') {
@@ -1,10 +1,10 @@
1
1
  import BaseIframe from './base-iframe';
2
- import {
3
- dispatchRebillyInsturmentEventHandler,
4
- resizeComponentHandler,
5
- stopLoaderHandler,
6
- showErrorHandler,
7
- } from './event-listeners';
2
+
3
+ import { resizeComponentHandler } from './events/resize-component-handler';
4
+ import { dispatchEventHandler } from './events/dispatch-event-handler';
5
+ import { updateCouponsHandler } from './events/update-coupons-handler';
6
+ import { showErrorHandler } from './events/show-error-handler';
7
+ import { stopLoaderHandler } from './events/stop-loader-handler';
8
8
 
9
9
  export class ViewIframe extends BaseIframe {
10
10
  constructor(args = {}) {
@@ -12,9 +12,10 @@ export class ViewIframe extends BaseIframe {
12
12
  }
13
13
 
14
14
  bindEventListeners({ loader } = {}) {
15
- dispatchRebillyInsturmentEventHandler(this);
15
+ dispatchEventHandler(this);
16
16
  resizeComponentHandler(this);
17
17
  stopLoaderHandler(this, { loader });
18
18
  showErrorHandler(this);
19
+ updateCouponsHandler(this);
19
20
  }
20
21
  }
@@ -1,6 +1,6 @@
1
1
  const SUPPORTED_EXPRESS_METHODS = ['Google Pay', 'Apple Pay', 'paypal'];
2
2
 
3
- export const SUPPORTED_METHODS = ['payment-card', 'ach'];
3
+ export const SUPPORTED_METHODS = ['payment-card', 'ach', 'cryptocurrency'];
4
4
 
5
5
  const isExpressMethod = ({ method, feature }) => (
6
6
  SUPPORTED_EXPRESS_METHODS.includes(method) ||
@@ -68,6 +68,7 @@ export async function mountMethodSelector({ state }) {
68
68
 
69
69
  const name = 'rebilly-instruments-form';
70
70
  const iframe = await new ViewIframe({
71
+ state,
71
72
  name,
72
73
  url: `${paymentMethodsUrl}`,
73
74
  container: METHODS_CONTAINER,
@@ -18,6 +18,7 @@ export async function mountResult({ payload, state }) {
18
18
  };
19
19
 
20
20
  const iframe = await new ViewIframe({
21
+ state,
21
22
  name: 'rebilly-instruments-result',
22
23
  url: `${paymentMethodsUrl}/result`,
23
24
  container,
@@ -10,6 +10,7 @@ export async function mountSummary({ state }) {
10
10
  const { paymentMethodsUrl } = state.options._computed;
11
11
 
12
12
  const iframe = await new ViewIframe({
13
+ state,
13
14
  name: 'rebilly-instruments-summary',
14
15
  url: `${paymentMethodsUrl}/summary`,
15
16
  container: state.summary,
@@ -1,50 +0,0 @@
1
- import camelCase from 'lodash.camelcase';
2
- import Events from '../../../events';
3
- import { showError } from '../../errors';
4
-
5
- export function dispatchRebillyInsturmentEventHandler(iframe) {
6
- iframe.component.on(`${iframe.name}-dispatch`, ({ event, detail }) => {
7
- Events[camelCase(event).replace(/-/, '')].dispatch(detail);
8
- });
9
- }
10
-
11
- export function resizeComponentHandler(iframe) {
12
- let prevHeight = '';
13
- iframe.component.on(`${iframe.name}-resize-frame`, (height) => {
14
- if (height !== prevHeight) {
15
- prevHeight = height;
16
- iframe.component.frame.style.height = height;
17
- }
18
- });
19
- }
20
-
21
- export function stopLoaderHandler(iframe, data) {
22
- iframe.component.on(`${iframe.name}-stop-loading`, (id) => {
23
- let {section} = data;
24
- if (!section) {
25
- section = id.includes('summary') ? 'summary' : 'form';
26
- }
27
- data.loader?.stopLoading({ section, id });
28
- });
29
- }
30
-
31
- export function changeIframeSrcHandler(iframe) {
32
- iframe.component.on(`${iframe.name}-change-iframe-src`, (url = null) => {
33
- iframe.component.frame.src = url;
34
- iframe.component.frame.style.height = '75vh';
35
- });
36
- }
37
-
38
- export function displayOverlay(iframe) {
39
- iframe.component.on(`${iframe.name}-change-overlay`, (showOverlay = true) => {
40
- if (showOverlay) {
41
- iframe.component.frame.classList.add('rebilly-instruments-iframe-overlay');
42
- } else {
43
- iframe.component.frame.classList.remove('rebilly-instruments-iframe-overlay');
44
- }
45
- });
46
- }
47
-
48
- export function showErrorHandler(iframe) {
49
- iframe.component.on(`${iframe.name}-show-error`, showError);
50
- }