@aehrc/smart-forms-renderer 0.42.0 → 0.43.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.
- package/.storybook/iframeResizerChild.js +1063 -0
- package/.storybook/preview.tsx +1 -0
- package/README.md +3 -1
- package/lib/components/Renderer/SmartFormsRenderer.js +0 -1
- package/lib/components/Renderer/SmartFormsRenderer.js.map +1 -1
- package/lib/stories/storybookWrappers/InitialiseFormWrapperForStorybook.d.ts +0 -1
- package/lib/stories/storybookWrappers/InitialiseFormWrapperForStorybook.js +0 -1
- package/lib/stories/storybookWrappers/InitialiseFormWrapperForStorybook.js.map +1 -1
- package/package.json +11 -12
- package/src/components/Renderer/SmartFormsRenderer.tsx +0 -2
- package/src/stories/storybookWrappers/BuildFormButtonTesterWrapperForStorybook.tsx +0 -1
- package/src/stories/storybookWrappers/BuildFormWrapperForStorybook.tsx +0 -1
- package/src/stories/storybookWrappers/FormValidationTesterWrapperForStorybook.tsx +0 -1
- package/src/stories/storybookWrappers/IdRemoverDebuggerWrapperForStorybook.tsx +0 -1
- package/src/stories/storybookWrappers/InitialiseFormWrapperForStorybook.tsx +0 -1
|
@@ -0,0 +1,1063 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Commonwealth Scientific and Industrial Research
|
|
3
|
+
* Organisation (CSIRO) ABN 41 687 119 230.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*
|
|
17
|
+
* Modified from:
|
|
18
|
+
* GitHub: https://github.com/davidjbradshaw/iframe-resizer/tree/v4
|
|
19
|
+
* Author: David J. Bradshaw - info@iframe-resizer.com
|
|
20
|
+
* License: MIT
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const SIZE_ATTR = 'data-iframe-size';
|
|
24
|
+
const OVERFLOW_ATTR = 'data-overflowed';
|
|
25
|
+
|
|
26
|
+
const HEIGHT_EDGE = 'bottom';
|
|
27
|
+
const WIDTH_EDGE = 'right';
|
|
28
|
+
|
|
29
|
+
function addEventListener(el, evt, func, options) {
|
|
30
|
+
el.addEventListener(evt, func, options || false);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function removeEventListener(el, evt, func) {
|
|
34
|
+
el.removeEventListener(evt, func, false);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const id = (x) => x;
|
|
38
|
+
|
|
39
|
+
function overflowObserver(options) {
|
|
40
|
+
const side = options.side || HEIGHT_EDGE;
|
|
41
|
+
const onChange = options.onChange || id;
|
|
42
|
+
|
|
43
|
+
const observerOptions = {
|
|
44
|
+
root: options.root,
|
|
45
|
+
rootMargin: '0px',
|
|
46
|
+
threshold: 1
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function emit() {
|
|
50
|
+
const overflowedNodeList = document.querySelectorAll(`[${OVERFLOW_ATTR}]`);
|
|
51
|
+
onChange(overflowedNodeList);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const emitAfterReflow = () => requestAnimationFrame(emit);
|
|
55
|
+
|
|
56
|
+
function callback(entries) {
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
const { boundingClientRect, rootBounds, target } = entry;
|
|
59
|
+
const edge = boundingClientRect[side];
|
|
60
|
+
const hasOverflow = edge === 0 || edge > rootBounds[side];
|
|
61
|
+
target.toggleAttribute(OVERFLOW_ATTR, hasOverflow);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
emitAfterReflow();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const observer = new IntersectionObserver(callback, observerOptions);
|
|
68
|
+
const observed = new WeakSet();
|
|
69
|
+
|
|
70
|
+
return function (nodeList) {
|
|
71
|
+
for (const node of nodeList) {
|
|
72
|
+
if (node.nodeType !== Node.ELEMENT_NODE || observed.has(node)) continue;
|
|
73
|
+
|
|
74
|
+
observer.observe(node);
|
|
75
|
+
observed.add(node);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function iframeResizerChild() {
|
|
81
|
+
const checkVisibilityOptions = {
|
|
82
|
+
contentVisibilityAuto: true,
|
|
83
|
+
opacityProperty: true,
|
|
84
|
+
visibilityProperty: true
|
|
85
|
+
};
|
|
86
|
+
const customCalcMethods = {
|
|
87
|
+
height: () => {
|
|
88
|
+
return getHeight.auto();
|
|
89
|
+
},
|
|
90
|
+
width: () => {
|
|
91
|
+
return getWidth.auto();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const eventCancelTimer = 128;
|
|
95
|
+
const eventHandlersByName = {};
|
|
96
|
+
const hasCheckVisibility = 'checkVisibility' in window;
|
|
97
|
+
const msgID = '[iFrameSizer]'; // Must match host page msg ID
|
|
98
|
+
const msgIdLen = msgID.length;
|
|
99
|
+
const resetRequiredMethods = {
|
|
100
|
+
max: 1,
|
|
101
|
+
min: 1,
|
|
102
|
+
bodyScroll: 1,
|
|
103
|
+
documentElementScroll: 1
|
|
104
|
+
};
|
|
105
|
+
const widthCalcModeDefault = 'scroll';
|
|
106
|
+
|
|
107
|
+
let autoResize = true;
|
|
108
|
+
let bodyBackground = '';
|
|
109
|
+
let bodyMargin = 0;
|
|
110
|
+
let bodyMarginStr = '';
|
|
111
|
+
let bodyPadding = '';
|
|
112
|
+
let calculateHeight = true;
|
|
113
|
+
let calculateWidth = false;
|
|
114
|
+
let firstRun = true;
|
|
115
|
+
let hasOverflow = false;
|
|
116
|
+
let hasTags = false;
|
|
117
|
+
let height = 1;
|
|
118
|
+
let heightCalcModeDefault = 'auto';
|
|
119
|
+
let heightCalcMode = heightCalcModeDefault;
|
|
120
|
+
let initLock = true;
|
|
121
|
+
let initMsg = '';
|
|
122
|
+
let inPageLinks = {};
|
|
123
|
+
let mouseEvents = false;
|
|
124
|
+
let myID = '';
|
|
125
|
+
let offsetHeight;
|
|
126
|
+
let offsetWidth;
|
|
127
|
+
let observeOverflow = id;
|
|
128
|
+
let overflowedNodeList = [];
|
|
129
|
+
let resizeFrom = 'child';
|
|
130
|
+
let resizeObserver = null;
|
|
131
|
+
let taggedElements = [];
|
|
132
|
+
let target = window.parent;
|
|
133
|
+
let targetOriginDefault = '*';
|
|
134
|
+
let timerActive;
|
|
135
|
+
let tolerance = 0;
|
|
136
|
+
let triggerLocked = false;
|
|
137
|
+
let width = 1;
|
|
138
|
+
let widthCalcMode = widthCalcModeDefault;
|
|
139
|
+
let win = window;
|
|
140
|
+
|
|
141
|
+
let onReady = () => {};
|
|
142
|
+
let onPageInfo = null;
|
|
143
|
+
let onParentInfo = null;
|
|
144
|
+
|
|
145
|
+
function init() {
|
|
146
|
+
readDataFromParent();
|
|
147
|
+
readDataFromPage();
|
|
148
|
+
|
|
149
|
+
checkHeightMode();
|
|
150
|
+
checkWidthMode();
|
|
151
|
+
checkDeprecatedAttrs();
|
|
152
|
+
|
|
153
|
+
checkAndSetupTags();
|
|
154
|
+
|
|
155
|
+
setupObserveOverflow();
|
|
156
|
+
setupPublicMethods();
|
|
157
|
+
setupMouseEvents();
|
|
158
|
+
inPageLinks = setupInPageLinks();
|
|
159
|
+
|
|
160
|
+
addOverflowObservers(getAllElements(document)());
|
|
161
|
+
|
|
162
|
+
setMargin();
|
|
163
|
+
setBodyStyle('background', bodyBackground);
|
|
164
|
+
setBodyStyle('padding', bodyPadding);
|
|
165
|
+
|
|
166
|
+
injectClearFixIntoBodyElement();
|
|
167
|
+
stopInfiniteResizingOfIframe();
|
|
168
|
+
|
|
169
|
+
sendSize('init', 'Init message from host page', undefined, undefined, undefined);
|
|
170
|
+
|
|
171
|
+
initEventListeners();
|
|
172
|
+
setTimeout(onReady);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function onOverflowChange(nodeList) {
|
|
176
|
+
overflowedNodeList = nodeList;
|
|
177
|
+
hasOverflow = overflowedNodeList.length > 0;
|
|
178
|
+
|
|
179
|
+
sendSize('overflowChanged', 'Overflow updated');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function setupObserveOverflow() {
|
|
183
|
+
if (calculateHeight === calculateWidth) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
observeOverflow = overflowObserver({
|
|
188
|
+
onChange: onOverflowChange,
|
|
189
|
+
root: document.documentElement,
|
|
190
|
+
side: calculateHeight ? HEIGHT_EDGE : WIDTH_EDGE
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function checkAndSetupTags() {
|
|
195
|
+
taggedElements = document.querySelectorAll(`[${SIZE_ATTR}]`);
|
|
196
|
+
hasTags = taggedElements.length > 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function addOverflowObservers(nodeList) {
|
|
200
|
+
if (!hasTags) {
|
|
201
|
+
observeOverflow(nodeList);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function readDataFromParent() {
|
|
206
|
+
const strBool = (str) => str === 'true';
|
|
207
|
+
const data = initMsg.slice(msgIdLen).split(':');
|
|
208
|
+
|
|
209
|
+
myID = data[0];
|
|
210
|
+
bodyMargin = undefined === data[1] ? bodyMargin : Number(data[1]); // For V1 compatibility
|
|
211
|
+
calculateWidth = undefined === data[2] ? calculateWidth : strBool(data[2]);
|
|
212
|
+
autoResize = undefined === data[3] ? autoResize : strBool(data[3]);
|
|
213
|
+
bodyMarginStr = data[4];
|
|
214
|
+
heightCalcMode = undefined === data[5] ? heightCalcMode : data[5];
|
|
215
|
+
bodyBackground = data[6];
|
|
216
|
+
bodyPadding = data[7];
|
|
217
|
+
tolerance = undefined === data[8] ? tolerance : Number(data[8]);
|
|
218
|
+
inPageLinks.enable = undefined === data[9] ? false : strBool(data[9]);
|
|
219
|
+
resizeFrom = undefined === data[10] ? resizeFrom : data[10];
|
|
220
|
+
widthCalcMode = undefined === data[11] ? widthCalcMode : data[11];
|
|
221
|
+
mouseEvents = undefined === data[12] ? mouseEvents : strBool(data[12]);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function readDataFromPage() {
|
|
225
|
+
function readData(data) {
|
|
226
|
+
if (typeof data?.offset === 'number') {
|
|
227
|
+
if (calculateHeight) offsetHeight = data?.offset;
|
|
228
|
+
if (calculateWidth) offsetWidth = data?.offset;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (typeof data?.offsetSize === 'number') {
|
|
232
|
+
if (calculateHeight) offsetHeight = data?.offsetSize;
|
|
233
|
+
if (calculateWidth) offsetWidth = data?.offsetSize;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
targetOriginDefault = data?.targetOrigin || targetOriginDefault;
|
|
237
|
+
heightCalcMode = data?.heightCalculationMethod || heightCalcMode;
|
|
238
|
+
widthCalcMode = data?.widthCalculationMethod || widthCalcMode;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function setupCustomCalcMethods(calcMode, calcFunc) {
|
|
242
|
+
if (typeof calcMode === 'function') {
|
|
243
|
+
customCalcMethods[calcFunc] = calcMode;
|
|
244
|
+
calcMode = 'custom';
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return calcMode;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const data = window.iframeResizer || window.iFrameResizer;
|
|
251
|
+
|
|
252
|
+
if (typeof data !== 'object') {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
readData(data);
|
|
257
|
+
heightCalcMode = setupCustomCalcMethods(heightCalcMode, 'height');
|
|
258
|
+
widthCalcMode = setupCustomCalcMethods(widthCalcMode, 'width');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function chkCSS(attr, value) {
|
|
262
|
+
if (value.includes('-')) {
|
|
263
|
+
value = '';
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return value;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function setBodyStyle(attr, value) {
|
|
270
|
+
if (undefined !== value && value !== '' && value !== 'null') {
|
|
271
|
+
document.body.style.setProperty(attr, value);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function setMargin() {
|
|
276
|
+
// If called via V1 script, convert bodyMargin from int to str
|
|
277
|
+
if (undefined === bodyMarginStr) {
|
|
278
|
+
bodyMarginStr = `${bodyMargin}px`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
setBodyStyle('margin', chkCSS('margin', bodyMarginStr));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function stopInfiniteResizingOfIframe() {
|
|
285
|
+
const setAutoHeight = (el) =>
|
|
286
|
+
el.style.setProperty('height', heightCalcModeDefault, 'important');
|
|
287
|
+
|
|
288
|
+
setAutoHeight(document.documentElement);
|
|
289
|
+
setAutoHeight(document.body);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function manageTriggerEvent(options) {
|
|
293
|
+
const listener = {
|
|
294
|
+
add(eventName) {
|
|
295
|
+
function handleEvent() {
|
|
296
|
+
sendSize(options.eventName, options.eventType);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
eventHandlersByName[eventName] = handleEvent;
|
|
300
|
+
|
|
301
|
+
addEventListener(window, eventName, handleEvent, { passive: true });
|
|
302
|
+
},
|
|
303
|
+
remove(eventName) {
|
|
304
|
+
const handleEvent = eventHandlersByName[eventName];
|
|
305
|
+
delete eventHandlersByName[eventName];
|
|
306
|
+
|
|
307
|
+
removeEventListener(window, eventName, handleEvent);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
listener[options.method](options.eventName);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function manageEventListeners(method) {
|
|
315
|
+
manageTriggerEvent({
|
|
316
|
+
method,
|
|
317
|
+
eventType: 'After Print',
|
|
318
|
+
eventName: 'afterprint'
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
manageTriggerEvent({
|
|
322
|
+
method,
|
|
323
|
+
eventType: 'Before Print',
|
|
324
|
+
eventName: 'beforeprint'
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
manageTriggerEvent({
|
|
328
|
+
method,
|
|
329
|
+
eventType: 'Ready State Change',
|
|
330
|
+
eventName: 'readystatechange'
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function checkDeprecatedAttrs() {
|
|
335
|
+
let found = false;
|
|
336
|
+
|
|
337
|
+
const checkAttrs = (attr) =>
|
|
338
|
+
document.querySelectorAll(`[${attr}]`).forEach((el) => {
|
|
339
|
+
found = true;
|
|
340
|
+
el.removeAttribute(attr);
|
|
341
|
+
el.toggleAttribute(SIZE_ATTR, true);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
checkAttrs('data-iframe-height');
|
|
345
|
+
checkAttrs('data-iframe-width');
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function checkCalcMode(calcMode, calcModeDefault, modes) {
|
|
349
|
+
if (calcModeDefault !== calcMode) {
|
|
350
|
+
if (!(calcMode in modes)) {
|
|
351
|
+
calcMode = calcModeDefault;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return calcMode;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function checkHeightMode() {
|
|
359
|
+
heightCalcMode = checkCalcMode(heightCalcMode, heightCalcModeDefault, getHeight);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function checkWidthMode() {
|
|
363
|
+
widthCalcMode = checkCalcMode(widthCalcMode, widthCalcModeDefault, getWidth);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function initEventListeners() {
|
|
367
|
+
manageEventListeners('add');
|
|
368
|
+
setupMutationObserver();
|
|
369
|
+
setupResizeObservers();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function injectClearFixIntoBodyElement() {
|
|
373
|
+
const clearFix = document.createElement('div');
|
|
374
|
+
|
|
375
|
+
clearFix.style.clear = 'both';
|
|
376
|
+
// Guard against the following having been globally redefined in CSS.
|
|
377
|
+
clearFix.style.display = 'block';
|
|
378
|
+
clearFix.style.height = '0';
|
|
379
|
+
document.body.append(clearFix);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function setupInPageLinks() {
|
|
383
|
+
function getPagePosition() {
|
|
384
|
+
return {
|
|
385
|
+
x: document.documentElement.scrollLeft,
|
|
386
|
+
y: document.documentElement.scrollTop
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function getElementPosition(el) {
|
|
391
|
+
const elPosition = el.getBoundingClientRect();
|
|
392
|
+
const { x, y } = getPagePosition();
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
x: parseInt(elPosition.left, 10) + parseInt(x.toString(), 10),
|
|
396
|
+
y: parseInt(elPosition.top, 10) + parseInt(y.toString(), 10)
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function findTarget(location) {
|
|
401
|
+
function jumpToTarget(target) {
|
|
402
|
+
const jumpPosition = getElementPosition(target);
|
|
403
|
+
|
|
404
|
+
sendMsg(jumpPosition.y, jumpPosition.x, 'scrollToOffset'); // X&Y reversed at sendMsg uses height/width
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const hash = location.split('#')[1] || location; // Remove # if present
|
|
408
|
+
const hashData = decodeURIComponent(hash);
|
|
409
|
+
const target = document.getElementById(hashData) || document.getElementsByName(hashData)[0];
|
|
410
|
+
|
|
411
|
+
if (target !== undefined) {
|
|
412
|
+
jumpToTarget(target);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
sendMsg(0, 0, 'inPageLink', `#${hash}`);
|
|
417
|
+
|
|
418
|
+
// Don't run for server side render
|
|
419
|
+
if (typeof window !== 'undefined') {
|
|
420
|
+
iframeResizerChild();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function checkLocationHash() {
|
|
425
|
+
const { hash, href } = window.location;
|
|
426
|
+
|
|
427
|
+
if (hash !== '' && hash !== '#') {
|
|
428
|
+
findTarget(href);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function bindAnchors() {
|
|
433
|
+
for (const link of document.querySelectorAll('a[href^="#"]')) {
|
|
434
|
+
if (link.getAttribute('href') !== '#') {
|
|
435
|
+
addEventListener(link, 'click', (e) => {
|
|
436
|
+
e.preventDefault();
|
|
437
|
+
findTarget(link.getAttribute('href'));
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function bindLocationHash() {
|
|
444
|
+
addEventListener(window, 'hashchange', checkLocationHash);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function initCheck() {
|
|
448
|
+
// Check if page loaded with location hash after init resize
|
|
449
|
+
setTimeout(checkLocationHash, eventCancelTimer);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function enableInPageLinks() {
|
|
453
|
+
bindAnchors();
|
|
454
|
+
bindLocationHash();
|
|
455
|
+
initCheck();
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (inPageLinks.enable) {
|
|
459
|
+
enableInPageLinks();
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
findTarget
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function setupMouseEvents() {
|
|
468
|
+
if (mouseEvents !== true) return;
|
|
469
|
+
|
|
470
|
+
function sendMouse(e) {
|
|
471
|
+
sendMsg(0, 0, e.type, `${e.screenY}:${e.screenX}`);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function addMouseListener(evt) {
|
|
475
|
+
addEventListener(window.document, evt, sendMouse);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
addMouseListener('mouseenter');
|
|
479
|
+
addMouseListener('mouseleave');
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function setupPublicMethods() {
|
|
483
|
+
win.parentIframe = Object.freeze({
|
|
484
|
+
autoResize: (resize) => {
|
|
485
|
+
if (resize === true && autoResize === false) {
|
|
486
|
+
autoResize = true;
|
|
487
|
+
sendSize('autoResizeEnabled', 'Auto Resize enabled');
|
|
488
|
+
} else if (resize === false && autoResize === true) {
|
|
489
|
+
autoResize = false;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
sendMsg(0, 0, 'autoResize', JSON.stringify(autoResize));
|
|
493
|
+
|
|
494
|
+
return autoResize;
|
|
495
|
+
},
|
|
496
|
+
|
|
497
|
+
close() {
|
|
498
|
+
sendMsg(0, 0, 'close');
|
|
499
|
+
},
|
|
500
|
+
|
|
501
|
+
getId: () => myID,
|
|
502
|
+
|
|
503
|
+
getPageInfo(callback) {
|
|
504
|
+
if (typeof callback === 'function') {
|
|
505
|
+
onPageInfo = callback;
|
|
506
|
+
sendMsg(0, 0, 'pageInfo');
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
onPageInfo = null;
|
|
511
|
+
sendMsg(0, 0, 'pageInfoStop');
|
|
512
|
+
},
|
|
513
|
+
|
|
514
|
+
getParentProps(callback) {
|
|
515
|
+
if (typeof callback !== 'function') {
|
|
516
|
+
throw new TypeError('parentIframe.getParentProps(callback) callback not a function');
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
onParentInfo = callback;
|
|
520
|
+
sendMsg(0, 0, 'parentInfo');
|
|
521
|
+
|
|
522
|
+
return () => {
|
|
523
|
+
onParentInfo = null;
|
|
524
|
+
sendMsg(0, 0, 'parentInfoStop');
|
|
525
|
+
};
|
|
526
|
+
},
|
|
527
|
+
|
|
528
|
+
getParentProperties(callback) {
|
|
529
|
+
this.getParentProps(callback);
|
|
530
|
+
},
|
|
531
|
+
|
|
532
|
+
moveToAnchor(hash) {
|
|
533
|
+
inPageLinks.findTarget(hash);
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
reset() {
|
|
537
|
+
resetIframe();
|
|
538
|
+
},
|
|
539
|
+
|
|
540
|
+
scrollBy(x, y) {
|
|
541
|
+
sendMsg(y, x, 'scrollBy'); // X&Y reversed at sendMsg uses height/width
|
|
542
|
+
},
|
|
543
|
+
|
|
544
|
+
scrollTo(x, y) {
|
|
545
|
+
sendMsg(y, x, 'scrollTo'); // X&Y reversed at sendMsg uses height/width
|
|
546
|
+
},
|
|
547
|
+
|
|
548
|
+
scrollToOffset(x, y) {
|
|
549
|
+
sendMsg(y, x, 'scrollToOffset'); // X&Y reversed at sendMsg uses height/width
|
|
550
|
+
},
|
|
551
|
+
|
|
552
|
+
sendMessage(msg, targetOrigin) {
|
|
553
|
+
sendMsg(0, 0, 'message', JSON.stringify(msg), targetOrigin);
|
|
554
|
+
},
|
|
555
|
+
|
|
556
|
+
setHeightCalculationMethod(heightCalculationMethod) {
|
|
557
|
+
heightCalcMode = heightCalculationMethod;
|
|
558
|
+
checkHeightMode();
|
|
559
|
+
},
|
|
560
|
+
|
|
561
|
+
setWidthCalculationMethod(widthCalculationMethod) {
|
|
562
|
+
widthCalcMode = widthCalculationMethod;
|
|
563
|
+
checkWidthMode();
|
|
564
|
+
},
|
|
565
|
+
|
|
566
|
+
setTargetOrigin(targetOrigin) {
|
|
567
|
+
targetOriginDefault = targetOrigin;
|
|
568
|
+
},
|
|
569
|
+
|
|
570
|
+
resize(customHeight, customWidth) {
|
|
571
|
+
const valString = `${customHeight || ''}${customWidth ? `,${customWidth}` : ''}`;
|
|
572
|
+
|
|
573
|
+
sendSize('resizeParent', `parentIframe.resize(${valString})`, customHeight, customWidth);
|
|
574
|
+
},
|
|
575
|
+
|
|
576
|
+
size(customHeight, customWidth) {
|
|
577
|
+
this.resize(customHeight, customWidth);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
win.parentIFrame = win.parentIframe;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function resizeObserved(entries) {
|
|
585
|
+
if (!Array.isArray(entries) || entries.length === 0) return;
|
|
586
|
+
|
|
587
|
+
sendSize('resizeObserver', `Resize Observed:`);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const resizeSet = new WeakSet();
|
|
591
|
+
|
|
592
|
+
// This function has to iterate over all page elements during load
|
|
593
|
+
// so is optimized for performance, rather than best practices.
|
|
594
|
+
function attachResizeObserverToNonStaticElements(rootElement) {
|
|
595
|
+
if (rootElement.nodeType !== Node.ELEMENT_NODE) return;
|
|
596
|
+
|
|
597
|
+
if (!resizeSet.has(rootElement)) {
|
|
598
|
+
const position = getComputedStyle(rootElement)?.position;
|
|
599
|
+
if (!(position === '' || position === 'static')) {
|
|
600
|
+
resizeObserver.observe(rootElement);
|
|
601
|
+
resizeSet.add(rootElement);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const nodeList = getAllElements(rootElement)();
|
|
606
|
+
|
|
607
|
+
for (const node of nodeList) {
|
|
608
|
+
if (resizeSet.has(node) || node?.nodeType !== Node.ELEMENT_NODE) continue;
|
|
609
|
+
|
|
610
|
+
const position = getComputedStyle(node)?.position;
|
|
611
|
+
if (position === '' || position === 'static') continue;
|
|
612
|
+
|
|
613
|
+
resizeObserver.observe(node);
|
|
614
|
+
resizeSet.add(node);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function setupResizeObservers() {
|
|
619
|
+
resizeObserver = new ResizeObserver(resizeObserved);
|
|
620
|
+
resizeObserver.observe(document.body);
|
|
621
|
+
resizeSet.add(document.body);
|
|
622
|
+
attachResizeObserverToNonStaticElements(document.body);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
function setupMutationObserver() {
|
|
626
|
+
const observedMutations = new Set();
|
|
627
|
+
let pending = false;
|
|
628
|
+
let newMutations = [];
|
|
629
|
+
|
|
630
|
+
const updateMutation = (mutations) => {
|
|
631
|
+
for (const mutation of mutations) {
|
|
632
|
+
const { addedNodes, removedNodes } = mutation;
|
|
633
|
+
|
|
634
|
+
for (const node of addedNodes) {
|
|
635
|
+
observedMutations.add(node);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
for (const node of removedNodes) {
|
|
639
|
+
observedMutations.delete(node);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
let delayCount = 1;
|
|
645
|
+
|
|
646
|
+
function processMutations() {
|
|
647
|
+
delayCount = 1;
|
|
648
|
+
|
|
649
|
+
newMutations.forEach(updateMutation);
|
|
650
|
+
newMutations = [];
|
|
651
|
+
|
|
652
|
+
if (observedMutations.size === 0) {
|
|
653
|
+
pending = false;
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Rebuild tagged elements list for size calculation
|
|
658
|
+
checkAndSetupTags();
|
|
659
|
+
|
|
660
|
+
// Add observers to new elements
|
|
661
|
+
addOverflowObservers(observedMutations);
|
|
662
|
+
observedMutations.forEach(attachResizeObserverToNonStaticElements);
|
|
663
|
+
|
|
664
|
+
observedMutations.clear();
|
|
665
|
+
|
|
666
|
+
pending = false;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
function mutationObserved(mutations) {
|
|
670
|
+
newMutations.push(mutations);
|
|
671
|
+
if (pending) return;
|
|
672
|
+
|
|
673
|
+
pending = true;
|
|
674
|
+
requestAnimationFrame(processMutations);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function createMutationObserver() {
|
|
678
|
+
const observer = new window.MutationObserver(mutationObserved);
|
|
679
|
+
const target = document.querySelector('body');
|
|
680
|
+
const config = {
|
|
681
|
+
attributes: false,
|
|
682
|
+
attributeOldValue: false,
|
|
683
|
+
characterData: false,
|
|
684
|
+
characterDataOldValue: false,
|
|
685
|
+
childList: true,
|
|
686
|
+
subtree: true
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
observer.observe(target, config);
|
|
690
|
+
|
|
691
|
+
return observer;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const observer = createMutationObserver();
|
|
695
|
+
|
|
696
|
+
return {
|
|
697
|
+
disconnect() {
|
|
698
|
+
observer.disconnect();
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
function getMaxElement(side) {
|
|
704
|
+
let elVal = 0;
|
|
705
|
+
let maxEl = document.documentElement;
|
|
706
|
+
let maxVal = hasTags ? 0 : document.documentElement.getBoundingClientRect().bottom;
|
|
707
|
+
|
|
708
|
+
const targetElements = hasTags
|
|
709
|
+
? taggedElements
|
|
710
|
+
: hasOverflow
|
|
711
|
+
? overflowedNodeList
|
|
712
|
+
: getAllElements(document)(); // We should never get here, but just in case
|
|
713
|
+
|
|
714
|
+
let len = targetElements.length;
|
|
715
|
+
|
|
716
|
+
for (const element of targetElements) {
|
|
717
|
+
if (
|
|
718
|
+
!hasTags &&
|
|
719
|
+
hasCheckVisibility && // Safari was missing checkVisibility until March 2024
|
|
720
|
+
!element.checkVisibility(checkVisibilityOptions ?? undefined)
|
|
721
|
+
) {
|
|
722
|
+
len -= 1;
|
|
723
|
+
continue;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
elVal =
|
|
727
|
+
element.getBoundingClientRect()[side] +
|
|
728
|
+
parseFloat(getComputedStyle(element).getPropertyValue(`margin-${side}`));
|
|
729
|
+
|
|
730
|
+
if (elVal > maxVal) {
|
|
731
|
+
maxVal = elVal;
|
|
732
|
+
maxEl = element;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
return maxVal;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
const getAllMeasurements = (dimension) => [
|
|
740
|
+
dimension.bodyOffset(),
|
|
741
|
+
dimension.bodyScroll(),
|
|
742
|
+
dimension.documentElementOffset(),
|
|
743
|
+
dimension.documentElementScroll(),
|
|
744
|
+
dimension.boundingClientRect()
|
|
745
|
+
];
|
|
746
|
+
|
|
747
|
+
const getAllElements = (element) => () =>
|
|
748
|
+
element.querySelectorAll(
|
|
749
|
+
'* :not(head):not(meta):not(base):not(title):not(script):not(link):not(style):not(map):not(area):not(option):not(optgroup):not(template):not(track):not(wbr):not(nobr)'
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
const prevScrollSize = {
|
|
753
|
+
height: 0,
|
|
754
|
+
width: 0
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
const prevBoundingSize = {
|
|
758
|
+
height: 0,
|
|
759
|
+
width: 0
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
const getAdjustedScroll = (getDimension) =>
|
|
763
|
+
getDimension.documentElementScroll() + Math.max(0, getDimension.getOffset());
|
|
764
|
+
|
|
765
|
+
function getAutoSize(getDimension) {
|
|
766
|
+
function returnBoundingClientRect() {
|
|
767
|
+
prevBoundingSize[dimension] = boundingSize;
|
|
768
|
+
prevScrollSize[dimension] = scrollSize;
|
|
769
|
+
return boundingSize;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const isHeight = getDimension === getHeight;
|
|
773
|
+
const dimension = isHeight ? 'height' : 'width';
|
|
774
|
+
const boundingSize = getDimension.boundingClientRect();
|
|
775
|
+
const ceilBoundingSize = Math.ceil(boundingSize);
|
|
776
|
+
const floorBoundingSize = Math.floor(boundingSize);
|
|
777
|
+
const scrollSize = getAdjustedScroll(getDimension);
|
|
778
|
+
|
|
779
|
+
switch (true) {
|
|
780
|
+
case !getDimension.enabled():
|
|
781
|
+
return scrollSize;
|
|
782
|
+
|
|
783
|
+
case hasTags:
|
|
784
|
+
return getDimension.taggedElement();
|
|
785
|
+
|
|
786
|
+
case !hasOverflow && prevBoundingSize[dimension] === 0 && prevScrollSize[dimension] === 0:
|
|
787
|
+
return returnBoundingClientRect();
|
|
788
|
+
|
|
789
|
+
case triggerLocked &&
|
|
790
|
+
boundingSize === prevBoundingSize[dimension] &&
|
|
791
|
+
scrollSize === prevScrollSize[dimension]:
|
|
792
|
+
return Math.max(boundingSize, scrollSize);
|
|
793
|
+
|
|
794
|
+
case boundingSize === 0:
|
|
795
|
+
return scrollSize;
|
|
796
|
+
|
|
797
|
+
case !hasOverflow &&
|
|
798
|
+
boundingSize !== prevBoundingSize[dimension] &&
|
|
799
|
+
scrollSize <= prevScrollSize[dimension]:
|
|
800
|
+
return returnBoundingClientRect();
|
|
801
|
+
|
|
802
|
+
case !isHeight:
|
|
803
|
+
return getDimension.taggedElement();
|
|
804
|
+
|
|
805
|
+
case !hasOverflow && boundingSize < prevBoundingSize[dimension]:
|
|
806
|
+
return returnBoundingClientRect();
|
|
807
|
+
|
|
808
|
+
case scrollSize === floorBoundingSize || scrollSize === ceilBoundingSize:
|
|
809
|
+
return returnBoundingClientRect();
|
|
810
|
+
|
|
811
|
+
case boundingSize > scrollSize:
|
|
812
|
+
return returnBoundingClientRect();
|
|
813
|
+
|
|
814
|
+
default:
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
return Math.max(getDimension.taggedElement(), returnBoundingClientRect());
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
const getBodyOffset = () => {
|
|
821
|
+
const { body } = document;
|
|
822
|
+
const style = getComputedStyle(body);
|
|
823
|
+
|
|
824
|
+
return body.offsetHeight + parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
const getHeight = {
|
|
828
|
+
enabled: () => calculateHeight,
|
|
829
|
+
getOffset: () => offsetHeight,
|
|
830
|
+
auto: () => getAutoSize(getHeight),
|
|
831
|
+
bodyOffset: getBodyOffset,
|
|
832
|
+
bodyScroll: () => document.body.scrollHeight,
|
|
833
|
+
offset: () => getHeight.bodyOffset(), // Backwards compatibility
|
|
834
|
+
custom: () => customCalcMethods.height(),
|
|
835
|
+
documentElementOffset: () => document.documentElement.offsetHeight,
|
|
836
|
+
documentElementScroll: () => document.documentElement.scrollHeight,
|
|
837
|
+
boundingClientRect: () =>
|
|
838
|
+
Math.max(
|
|
839
|
+
document.documentElement.getBoundingClientRect().bottom,
|
|
840
|
+
document.body.getBoundingClientRect().bottom
|
|
841
|
+
),
|
|
842
|
+
max: () => Math.max(...getAllMeasurements(getHeight)),
|
|
843
|
+
min: () => Math.min(...getAllMeasurements(getHeight)),
|
|
844
|
+
grow: () => getHeight.max(),
|
|
845
|
+
taggedElement: () => getMaxElement(HEIGHT_EDGE)
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
const getWidth = {
|
|
849
|
+
enabled: () => calculateWidth,
|
|
850
|
+
getOffset: () => offsetWidth,
|
|
851
|
+
auto: () => getAutoSize(getWidth),
|
|
852
|
+
bodyScroll: () => document.body.scrollWidth,
|
|
853
|
+
bodyOffset: () => document.body.offsetWidth,
|
|
854
|
+
custom: () => customCalcMethods.width(),
|
|
855
|
+
documentElementScroll: () => document.documentElement.scrollWidth,
|
|
856
|
+
documentElementOffset: () => document.documentElement.offsetWidth,
|
|
857
|
+
boundingClientRect: () =>
|
|
858
|
+
Math.max(
|
|
859
|
+
document.documentElement.getBoundingClientRect().right,
|
|
860
|
+
document.body.getBoundingClientRect().right
|
|
861
|
+
),
|
|
862
|
+
max: () => Math.max(...getAllMeasurements(getWidth)),
|
|
863
|
+
min: () => Math.min(...getAllMeasurements(getWidth)),
|
|
864
|
+
scroll: () => Math.max(getWidth.bodyScroll(), getWidth.documentElementScroll()),
|
|
865
|
+
taggedElement: () => getMaxElement(WIDTH_EDGE)
|
|
866
|
+
};
|
|
867
|
+
|
|
868
|
+
const checkTolerance = (a, b) => !(Math.abs(a - b) <= tolerance);
|
|
869
|
+
|
|
870
|
+
function sizeIframe(triggerEvent, triggerEventDesc, customHeight, customWidth, msg) {
|
|
871
|
+
const isForceResizableEvent = () => !(triggerEvent in { init: 1, interval: 1, size: 1 });
|
|
872
|
+
|
|
873
|
+
const isForceResizableCalcMode = () =>
|
|
874
|
+
(calculateHeight && heightCalcMode in resetRequiredMethods) ||
|
|
875
|
+
(calculateWidth && widthCalcMode in resetRequiredMethods);
|
|
876
|
+
|
|
877
|
+
const isSizeChangeDetected = () =>
|
|
878
|
+
(calculateHeight && checkTolerance(height, newHeight)) ||
|
|
879
|
+
(calculateWidth && checkTolerance(width, newWidth));
|
|
880
|
+
|
|
881
|
+
const newHeight = undefined === customHeight ? getHeight[heightCalcMode]() : customHeight;
|
|
882
|
+
const newWidth = undefined === customWidth ? getWidth[widthCalcMode]() : customWidth;
|
|
883
|
+
|
|
884
|
+
if (isSizeChangeDetected() || triggerEvent === 'init') {
|
|
885
|
+
lockTrigger();
|
|
886
|
+
height = newHeight;
|
|
887
|
+
width = newWidth;
|
|
888
|
+
sendMsg(height, width, triggerEvent, msg);
|
|
889
|
+
} else if (isForceResizableEvent() && isForceResizableCalcMode()) {
|
|
890
|
+
resetIframe();
|
|
891
|
+
} else {
|
|
892
|
+
timerActive = false; // We're not resizing, so turn off the timer
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
let sendPending = false;
|
|
897
|
+
|
|
898
|
+
function sendSize(triggerEvent, triggerEventDesc, customHeight, customWidth, msg) {
|
|
899
|
+
if (!autoResize && triggerEvent in { reset: 1, resetPage: 1, init: 1 }) {
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
if (document.hidden) {
|
|
904
|
+
// Currently only correctly supported in firefox
|
|
905
|
+
// This is checked again on the parent page
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (!sendPending) {
|
|
910
|
+
timerActive = true;
|
|
911
|
+
sizeIframe(triggerEvent, triggerEventDesc, customHeight, customWidth, msg);
|
|
912
|
+
requestAnimationFrame(() => {
|
|
913
|
+
sendPending = false;
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
sendPending = true;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
function lockTrigger() {
|
|
921
|
+
if (triggerLocked) return;
|
|
922
|
+
|
|
923
|
+
triggerLocked = true;
|
|
924
|
+
|
|
925
|
+
requestAnimationFrame(() => {
|
|
926
|
+
triggerLocked = false;
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
function triggerReset(triggerEvent) {
|
|
931
|
+
height = getHeight[heightCalcMode]();
|
|
932
|
+
width = getWidth[widthCalcMode]();
|
|
933
|
+
|
|
934
|
+
sendMsg(height, width, triggerEvent);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
function resetIframe() {
|
|
938
|
+
const hcm = heightCalcMode;
|
|
939
|
+
heightCalcMode = heightCalcModeDefault;
|
|
940
|
+
|
|
941
|
+
lockTrigger();
|
|
942
|
+
triggerReset('reset');
|
|
943
|
+
|
|
944
|
+
heightCalcMode = hcm;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
function sendMsg(height, width, triggerEvent, msg, targetOrigin) {
|
|
948
|
+
function setTargetOrigin() {
|
|
949
|
+
if (undefined === targetOrigin) {
|
|
950
|
+
targetOrigin = targetOriginDefault;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
function sendToParent() {
|
|
955
|
+
const size = `${height + (offsetHeight || 0)}:${width + (offsetWidth || 0)}`;
|
|
956
|
+
const message = `${myID}:${size}:${triggerEvent}${undefined === msg ? '' : `:${msg}`}`;
|
|
957
|
+
|
|
958
|
+
timerActive = false;
|
|
959
|
+
|
|
960
|
+
target.postMessage(msgID + message, targetOrigin);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
setTargetOrigin();
|
|
964
|
+
sendToParent();
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
function receiver(event) {
|
|
968
|
+
const processRequestFromParent = {
|
|
969
|
+
init: function initFromParent() {
|
|
970
|
+
initMsg = event.data;
|
|
971
|
+
target = event.source;
|
|
972
|
+
|
|
973
|
+
init();
|
|
974
|
+
firstRun = false;
|
|
975
|
+
setTimeout(() => {
|
|
976
|
+
initLock = false;
|
|
977
|
+
}, eventCancelTimer);
|
|
978
|
+
},
|
|
979
|
+
|
|
980
|
+
reset() {
|
|
981
|
+
if (initLock) {
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
triggerReset('resetPage');
|
|
985
|
+
},
|
|
986
|
+
|
|
987
|
+
resize() {
|
|
988
|
+
sendSize('resizeParent', 'Parent window requested size check');
|
|
989
|
+
},
|
|
990
|
+
|
|
991
|
+
moveToAnchor() {
|
|
992
|
+
inPageLinks.findTarget(getData());
|
|
993
|
+
},
|
|
994
|
+
|
|
995
|
+
inPageLink() {
|
|
996
|
+
this.moveToAnchor();
|
|
997
|
+
}, // Backward compatibility
|
|
998
|
+
|
|
999
|
+
pageInfo() {
|
|
1000
|
+
const msgBody = getData();
|
|
1001
|
+
if (onPageInfo) {
|
|
1002
|
+
setTimeout(() => onPageInfo(JSON.parse(msgBody)));
|
|
1003
|
+
} else {
|
|
1004
|
+
// not expected, so cancel more messages
|
|
1005
|
+
sendMsg(0, 0, 'pageInfoStop');
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
const isMessageForUs = () => msgID === `${event.data}`.slice(0, msgIdLen);
|
|
1011
|
+
|
|
1012
|
+
const getMessageType = () => event.data.split(']')[1].split(':')[0];
|
|
1013
|
+
|
|
1014
|
+
const getData = () => event.data.slice(event.data.indexOf(':') + 1);
|
|
1015
|
+
|
|
1016
|
+
// Test if this message is from a child below us. This is an ugly test, however, updating
|
|
1017
|
+
// the message format would break backwards compatibility.
|
|
1018
|
+
const isInitMsg = () => event.data.split(':')[2] in { true: 1, false: 1 };
|
|
1019
|
+
|
|
1020
|
+
function callFromParent() {
|
|
1021
|
+
const messageType = getMessageType();
|
|
1022
|
+
|
|
1023
|
+
if (messageType in processRequestFromParent) {
|
|
1024
|
+
processRequestFromParent[messageType]();
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
function processMessage() {
|
|
1029
|
+
if (firstRun === false) {
|
|
1030
|
+
callFromParent();
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
if (isInitMsg()) {
|
|
1035
|
+
processRequestFromParent.init();
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
if (isMessageForUs()) {
|
|
1040
|
+
processMessage();
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// Normally the parent kicks things off when it detects the iFrame has loaded.
|
|
1045
|
+
// If this script is async-loaded, then tell parent page to retry init.
|
|
1046
|
+
function chkLateLoaded() {
|
|
1047
|
+
if (document.readyState !== 'loading') {
|
|
1048
|
+
window.parent.postMessage('[iFrameResizerChild]Ready', '*');
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
if (!('iframeChildListener' in window)) {
|
|
1053
|
+
window.iframeChildListener = (data) => setTimeout(() => receiver({ data }));
|
|
1054
|
+
addEventListener(window, 'message', receiver);
|
|
1055
|
+
addEventListener(window, 'readystatechange', chkLateLoaded);
|
|
1056
|
+
chkLateLoaded();
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// Don't run for server side render
|
|
1061
|
+
if (typeof window !== 'undefined') {
|
|
1062
|
+
iframeResizerChild();
|
|
1063
|
+
}
|
package/.storybook/preview.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import '@fontsource/material-icons';
|
|
|
7
7
|
import { withThemeFromJSXProvider } from '@storybook/addon-styling';
|
|
8
8
|
import { createTheme } from '@mui/material/styles';
|
|
9
9
|
import { CssBaseline, ThemeProvider } from '@mui/material';
|
|
10
|
+
import './iframeResizerChild';
|
|
10
11
|
|
|
11
12
|
export const decorators = [
|
|
12
13
|
withThemeFromJSXProvider({
|
package/README.md
CHANGED
|
@@ -5,7 +5,9 @@ It acts as a reference implementation for the [SDC Form Filler](https://hl7.org/
|
|
|
5
5
|
|
|
6
6
|
<h4><a href="https://smartforms.csiro.au/docs/dev">Check out the documentation 📚</a></h4>
|
|
7
7
|
|
|
8
|
+
View the changelog [here](https://github.com/aehrc/smart-forms/blob/main/CHANGELOG.md).
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
---
|
|
10
12
|
|
|
11
|
-
Copyright ©
|
|
13
|
+
Copyright © 2024, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230. All rights reserved.
|
|
@@ -23,7 +23,6 @@ import Typography from '@mui/material/Typography';
|
|
|
23
23
|
import { QueryClientProvider } from '@tanstack/react-query';
|
|
24
24
|
import useRendererQueryClient from '../../hooks/useRendererQueryClient';
|
|
25
25
|
import BaseRenderer from './BaseRenderer';
|
|
26
|
-
// Will be deprecated in version 1.0.0. Use alternative() instead. //FIXME add alternative
|
|
27
26
|
/**
|
|
28
27
|
* A self-initialising wrapper around the BaseRenderer rendering engine.
|
|
29
28
|
* Will be deprecated in version 1.0.0. For alternative usage, see:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartFormsRenderer.js","sourceRoot":"","sources":["../../../src/components/Renderer/SmartFormsRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,qBAAqB,MAAM,mBAAmB,CAAC;AAEtD,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAC9D,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,gBAAgB,MAAM,gCAAgC,CAAC;AAC9D,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,sBAAsB,MAAM,oCAAoC,CAAC;AACxE,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAwB1C
|
|
1
|
+
{"version":3,"file":"SmartFormsRenderer.js","sourceRoot":"","sources":["../../../src/components/Renderer/SmartFormsRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,qBAAqB,MAAM,mBAAmB,CAAC;AAEtD,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAC9D,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,gBAAgB,MAAM,gCAAgC,CAAC;AAC9D,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,sBAAsB,MAAM,oCAAoC,CAAC;AACxE,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAwB1C;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,KAA8B;IACxD,MAAM,EACJ,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,QAAQ,EACT,GAAG,KAAK,CAAC;IAEV,MAAM,SAAS,GAAG,iBAAiB,CACjC,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,CACX,CAAC;IACF,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;IAE7C,IAAI,SAAS,EAAE;QACb,OAAO,CACL,oBAAC,GAAG,IAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC;YAClD,oBAAC,gBAAgB,OAAG;YACpB,oBAAC,UAAU,mCAAsC,CAC7C,CACP,CAAC;KACH;IAED,OAAO,CACL,oBAAC,qBAAqB;QACpB,oBAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW;YACtC,oBAAC,YAAY,OAAG,CACI,CACA,CACzB,CAAC;AACJ,CAAC;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Questionnaire, QuestionnaireResponse } from 'fhir/r4';
|
|
3
3
|
import type Client from 'fhirclient/lib/Client';
|
|
4
|
-
import '@iframe-resizer/child';
|
|
5
4
|
export interface InitialiseFormWrapperProps {
|
|
6
5
|
questionnaire: Questionnaire;
|
|
7
6
|
questionnaireResponse?: QuestionnaireResponse;
|
|
@@ -24,7 +24,6 @@ import useInitialiseForm from '../../hooks/useInitialiseForm';
|
|
|
24
24
|
import Box from '@mui/material/Box';
|
|
25
25
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
26
26
|
import Typography from '@mui/material/Typography';
|
|
27
|
-
import '@iframe-resizer/child';
|
|
28
27
|
/**
|
|
29
28
|
* This is a one-to-one replacement for the SmartFormsRenderer for demo purposes.
|
|
30
29
|
* Instead of using this React component, define your own wrapper component that uses the BaseRenderer directly.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InitialiseFormWrapperForStorybook.js","sourceRoot":"","sources":["../../../src/stories/storybookWrappers/InitialiseFormWrapperForStorybook.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,aAAa;AACb,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,qBAAqB,MAAM,mBAAmB,CAAC;AACtD,OAAO,sBAAsB,MAAM,oCAAoC,CAAC;AAExE,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAC9D,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,gBAAgB,MAAM,gCAAgC,CAAC;AAC9D,OAAO,UAAU,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"InitialiseFormWrapperForStorybook.js","sourceRoot":"","sources":["../../../src/stories/storybookWrappers/InitialiseFormWrapperForStorybook.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,aAAa;AACb,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,qBAAqB,MAAM,mBAAmB,CAAC;AACtD,OAAO,sBAAsB,MAAM,oCAAoC,CAAC;AAExE,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAC9D,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,gBAAgB,MAAM,gCAAgC,CAAC;AAC9D,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAWlD;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,iCAAiC,CAAC,KAAiC;IAC1E,MAAM,EACJ,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,GAAG,KAAK,CAAC;IAEV,qFAAqF;IACrF,MAAM,WAAW,GAAG,sBAAsB,EAAE,CAAC;IAE7C;;;;;OAKG;IACH,MAAM,cAAc,GAAG,iBAAiB,CACtC,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,CACX,CAAC;IAEF,qDAAqD;IACrD,IAAI,cAAc,EAAE;QAClB,OAAO,CACL,oBAAC,GAAG,IAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC;YAClD,oBAAC,gBAAgB,OAAG;YACpB,oBAAC,UAAU,mCAAsC,CAC7C,CACP,CAAC;KACH;IAED,OAAO,CACL,oBAAC,qBAAqB;QACpB,oBAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW;YACtC,oBAAC,YAAY,OAAG,CACI,CACA,CACzB,CAAC;AACJ,CAAC;AAED,eAAe,iCAAiC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aehrc/smart-forms-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@aehrc/sdc-populate": "^2.3.1",
|
|
31
31
|
"@iconify/react": "^4.1.1",
|
|
32
|
-
"@iframe-resizer/child": "^5.3.1",
|
|
33
32
|
"dayjs": "^1.11.10",
|
|
34
33
|
"deep-diff": "^1.0.2",
|
|
35
34
|
"fhirclient": "^2.5.2",
|
|
@@ -63,15 +62,15 @@
|
|
|
63
62
|
"devDependencies": {
|
|
64
63
|
"@babel/core": "^7.24.4",
|
|
65
64
|
"@chromatic-com/storybook": "^1.3.5",
|
|
66
|
-
"@storybook/addon-essentials": "^8.
|
|
67
|
-
"@storybook/addon-interactions": "^8.3.
|
|
68
|
-
"@storybook/addon-links": "^8.
|
|
69
|
-
"@storybook/addon-onboarding": "^8.
|
|
70
|
-
"@storybook/blocks": "^8.
|
|
71
|
-
"@storybook/react": "^8.
|
|
72
|
-
"@storybook/react-vite": "^8.
|
|
73
|
-
"@storybook/test": "^8.
|
|
74
|
-
"@storybook/types": "^8.
|
|
65
|
+
"@storybook/addon-essentials": "^8.3.4",
|
|
66
|
+
"@storybook/addon-interactions": "^8.3.4",
|
|
67
|
+
"@storybook/addon-links": "^8.3.4",
|
|
68
|
+
"@storybook/addon-onboarding": "^8.3.4",
|
|
69
|
+
"@storybook/blocks": "^8.3.4",
|
|
70
|
+
"@storybook/react": "^8.3.4",
|
|
71
|
+
"@storybook/react-vite": "^8.3.4",
|
|
72
|
+
"@storybook/test": "^8.3.4",
|
|
73
|
+
"@storybook/types": "^8.3.4",
|
|
75
74
|
"@swc/cli": "^0.1.63",
|
|
76
75
|
"@swc/core": "^1.5.28",
|
|
77
76
|
"@testing-library/jest-dom": "^6.1.2",
|
|
@@ -91,7 +90,7 @@
|
|
|
91
90
|
"chokidar": "^3.6.0",
|
|
92
91
|
"jest": "^29.7.0",
|
|
93
92
|
"jest-environment-jsdom": "^29.7.0",
|
|
94
|
-
"storybook": "^8.
|
|
93
|
+
"storybook": "^8.3.4",
|
|
95
94
|
"ts-jest": "^29.1.1",
|
|
96
95
|
"tslib": "^2.6.3",
|
|
97
96
|
"typescript": "^5.2.2"
|
|
@@ -49,8 +49,6 @@ export interface SmartFormsRendererProps {
|
|
|
49
49
|
readOnly?: boolean;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
// Will be deprecated in version 1.0.0. Use alternative() instead. //FIXME add alternative
|
|
53
|
-
|
|
54
52
|
/**
|
|
55
53
|
* A self-initialising wrapper around the BaseRenderer rendering engine.
|
|
56
54
|
* Will be deprecated in version 1.0.0. For alternative usage, see:
|
|
@@ -24,7 +24,6 @@ import { RendererThemeProvider } from '../../theme';
|
|
|
24
24
|
import { useBuildForm, useRendererQueryClient } from '../../hooks';
|
|
25
25
|
import BuildFormButtonForStorybook from './BuildFormButtonForStorybook';
|
|
26
26
|
import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
|
|
27
|
-
import '@iframe-resizer/child';
|
|
28
27
|
|
|
29
28
|
interface BuildFormButtonTesterWrapperForStorybookProps {
|
|
30
29
|
questionnaire: Questionnaire;
|
|
@@ -24,7 +24,6 @@ import RendererThemeProvider from '../../theme/Theme';
|
|
|
24
24
|
import { useBuildForm } from '../../hooks';
|
|
25
25
|
import useRendererQueryClient from '../../hooks/useRendererQueryClient';
|
|
26
26
|
import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
|
|
27
|
-
import '@iframe-resizer/child';
|
|
28
27
|
|
|
29
28
|
interface BuildFormWrapperForStorybookProps {
|
|
30
29
|
questionnaire: Questionnaire;
|
|
@@ -25,7 +25,6 @@ import { useBuildForm, useRendererQueryClient } from '../../hooks';
|
|
|
25
25
|
import { Grid } from '@mui/material';
|
|
26
26
|
import FormValidationViewerForStorybook from './FormValidationViewerForStorybook';
|
|
27
27
|
import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
|
|
28
|
-
import '@iframe-resizer/child';
|
|
29
28
|
|
|
30
29
|
interface FormValidationTesterWrapperForStorybookProps {
|
|
31
30
|
questionnaire: Questionnaire;
|
|
@@ -26,7 +26,6 @@ import { STORYBOOK_TERMINOLOGY_SERVER_URL } from './globals';
|
|
|
26
26
|
import IdRemoverButtonForStorybook from './IdRemoverButtonForStorybook';
|
|
27
27
|
import { Grid } from '@mui/material';
|
|
28
28
|
import { useQuestionnaireResponseStore, useQuestionnaireStore } from '../../stores';
|
|
29
|
-
import '@iframe-resizer/child';
|
|
30
29
|
|
|
31
30
|
interface IdRemoverDebuggerWrapperForStorybookProps {
|
|
32
31
|
questionnaire: Questionnaire;
|
|
@@ -27,7 +27,6 @@ import useInitialiseForm from '../../hooks/useInitialiseForm';
|
|
|
27
27
|
import Box from '@mui/material/Box';
|
|
28
28
|
import CircularProgress from '@mui/material/CircularProgress';
|
|
29
29
|
import Typography from '@mui/material/Typography';
|
|
30
|
-
import '@iframe-resizer/child';
|
|
31
30
|
|
|
32
31
|
export interface InitialiseFormWrapperProps {
|
|
33
32
|
questionnaire: Questionnaire;
|