@@ -32,6 +32,109 @@ val WritersideStyle = DataFrameHtmlData(
32
32
padding: 6px;
33
33
}
34
34
""" .trimIndent(),
35
+ script =
36
+ """
37
+ function sendHeight() {
38
+ let totalHeight = 0;
39
+
40
+ document.querySelectorAll('body > details, body > br').forEach(element => {
41
+ if (element.tagName === 'DETAILS') {
42
+ totalHeight += getElementHeight(element.querySelector(':scope > summary'));
43
+
44
+ if (element.open) {
45
+ totalHeight += getVisibleContentHeight(element);
46
+ }
47
+ } else if (element.tagName === 'BR') {
48
+ totalHeight += getElementHeight(element);
49
+ }
50
+ });
51
+
52
+ totalHeight += 10;
53
+
54
+ window.parent.postMessage({type: 'iframeHeight', height: Math.ceil(totalHeight)}, '*');
55
+ }
56
+
57
+ function getVisibleContentHeight(detailsElement) {
58
+ let height = 0;
59
+
60
+ detailsElement.querySelectorAll(':scope > details, :scope > table, :scope > p').forEach(child => {
61
+ if (child.tagName === 'DETAILS') {
62
+ const summary = child.querySelector(':scope > summary');
63
+ height += getElementHeight(summary);
64
+
65
+ if (child.open) {
66
+ height += getDirectVisibleContentHeight(child);
67
+ }
68
+ } else if (isElementVisible(child)) {
69
+ height += getElementHeight(child);
70
+ }
71
+ });
72
+
73
+ return height;
74
+ }
75
+
76
+ function getDirectVisibleContentHeight(element) {
77
+ let height = 0;
78
+ element.querySelectorAll(':scope > table, :scope > p, :scope > summary').forEach(child => {
79
+ if (isElementVisible(child)) {
80
+ height += getElementHeight(child);
81
+ }
82
+ });
83
+ return height;
84
+ }
85
+
86
+ function getElementHeight(el) {
87
+ const styles = getComputedStyle(el);
88
+ const margin = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
89
+
90
+ // More reliable cross-browser calculation
91
+ const rect = el.getBoundingClientRect();
92
+ return rect.height + margin;
93
+ }
94
+
95
+ function isElementVisible(el) {
96
+ return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
97
+ }
98
+
99
+ function sendInitialHeight() {
100
+ let initialHeight = 0;
101
+
102
+ document.querySelectorAll('body > details, body > br').forEach(element => {
103
+ if (element.tagName === 'DETAILS') {
104
+ initialHeight += getElementHeight(element.querySelector(':scope > summary'));
105
+ } else if (element.tagName === 'BR') {
106
+ initialHeight += getElementHeight(element);
107
+ }
108
+ });
109
+
110
+ initialHeight += 10;
111
+
112
+ window.parent.postMessage({type: 'iframeHeight', height: Math.ceil(initialHeight)}, '*');
113
+ }
114
+
115
+ function repeatHeightCalculation(maxRetries = 10, interval = 100) {
116
+ let retries = 0;
117
+ const intervalId = setInterval(() => {
118
+ sendInitialHeight();
119
+ retries++;
120
+ if (retries >= maxRetries) clearInterval(intervalId);
121
+ }, interval);
122
+ }
123
+
124
+ window.addEventListener('load', () => {
125
+ repeatHeightCalculation();
126
+
127
+
128
+ document.querySelectorAll('details').forEach(detail => {
129
+ detail.addEventListener('toggle', () => {
130
+ setTimeout(sendHeight, 50);
131
+ });
132
+ });
133
+
134
+ const observer = new MutationObserver(() => setTimeout(sendHeight, 50));
135
+ observer.observe(document.body, {childList: true, subtree: true, characterData: true});
136
+ });
137
+ """ .trimIndent(),
35
138
)
36
139
37
140
val WritersideFooter : (DataFrame <* >) -> String = { " " }
0 commit comments