@jsenv/plugin-toolbar 0.1.1 → 0.1.2

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 (66) hide show
  1. package/dist/css/document_execution_indicator.css +87 -0
  2. package/dist/css/globals.css +75 -0
  3. package/dist/css/server_indicator.css +83 -0
  4. package/dist/css/theme_light.css +110 -0
  5. package/dist/css/toolbar.css +7 -683
  6. package/dist/css/toolbar_menu_overflow.css +59 -0
  7. package/dist/css/toolbar_settings.css +202 -0
  8. package/dist/css/tooltips.css +67 -0
  9. package/dist/js/animation.js +282 -0
  10. package/dist/js/animation_actions.js +7 -0
  11. package/dist/js/animation_effects.js +10 -0
  12. package/dist/js/animation_signals.js +4 -0
  13. package/dist/js/changes_actions.js +7 -0
  14. package/dist/js/changes_indicator.js +57 -0
  15. package/dist/js/changes_signals.js +2 -0
  16. package/dist/js/document_execution_indicator.js +62 -0
  17. package/dist/js/document_index_link.js +4 -0
  18. package/dist/js/dom.js +48 -0
  19. package/dist/js/execution_actions.js +46 -0
  20. package/dist/js/execution_effects.js +16 -0
  21. package/dist/js/execution_signals.js +17 -0
  22. package/dist/js/hooks.mjs +185 -0
  23. package/dist/js/iframe_to_parent_href.js +10 -0
  24. package/dist/js/notification_actions.js +60 -0
  25. package/dist/js/notification_context.js +1 -0
  26. package/dist/js/notification_effects.js +9 -0
  27. package/dist/js/notification_signals.js +5 -0
  28. package/dist/js/parent_window_actions.js +39 -0
  29. package/dist/js/parent_window_context.js +6 -0
  30. package/dist/js/parent_window_effects.js +15 -0
  31. package/dist/js/parent_window_signals.js +25 -0
  32. package/dist/js/preact.mjs +316 -0
  33. package/dist/js/responsive.js +104 -0
  34. package/dist/js/server_actions.js +7 -0
  35. package/dist/js/server_effects.js +9 -0
  36. package/dist/js/server_indicator.js +52 -0
  37. package/dist/js/server_signals.js +10 -0
  38. package/dist/js/settings_actions.js +7 -0
  39. package/dist/js/settings_signals.js +2 -0
  40. package/dist/js/signals-core.mjs +339 -0
  41. package/dist/js/signals.mjs +202 -0
  42. package/dist/js/theme_actions.js +7 -0
  43. package/dist/js/theme_effects.js +6 -0
  44. package/dist/js/theme_signals.js +4 -0
  45. package/dist/js/toolbar_animation_setting.js +21 -0
  46. package/dist/js/toolbar_autoreload_setting.js +67 -0
  47. package/dist/js/toolbar_close_button.js +14 -0
  48. package/dist/js/toolbar_core.js +8 -1792
  49. package/dist/js/toolbar_injector.js +2 -4
  50. package/dist/js/toolbar_menu_overflow.js +81 -0
  51. package/dist/js/toolbar_notification_setting.js +72 -0
  52. package/dist/js/toolbar_open_actions.js +7 -0
  53. package/dist/js/toolbar_open_effects.js +4 -0
  54. package/dist/js/toolbar_open_signals.js +4 -0
  55. package/dist/js/toolbar_opening.js +65 -0
  56. package/dist/js/toolbar_overlay.js +69 -0
  57. package/dist/js/toolbar_settings.js +44 -0
  58. package/dist/js/toolbar_state_context.js +1 -0
  59. package/dist/js/toolbar_state_effects.js +8 -0
  60. package/dist/js/toolbar_state_signals.js +17 -0
  61. package/dist/js/toolbar_theme_setting.js +13 -0
  62. package/dist/js/toolbar_ui.js +20 -0
  63. package/dist/js/tooltip_actions.js +6 -0
  64. package/dist/js/variant.js +53 -0
  65. package/dist/jsenv_plugin_toolbar.js +3 -6
  66. package/package.json +2 -2
@@ -0,0 +1,59 @@
1
+ #menu_overflow_button {
2
+ width: 40px;
3
+ background: #404040;
4
+ display: none;
5
+ position: absolute;
6
+ top: 0;
7
+ right: 0;
8
+ }
9
+
10
+ #menu_overflow_icon {
11
+ width: 25px;
12
+ }
13
+
14
+ #menu_overflow {
15
+ visibility: hidden;
16
+ width: 100%;
17
+ height: 100%;
18
+ opacity: 0;
19
+ background: #404040;
20
+ display: none;
21
+ position: absolute;
22
+ top: 0;
23
+ bottom: 0;
24
+ left: 100%;
25
+ }
26
+
27
+ #menu_overflow[data-animate] {
28
+ transition-property: left, opacity;
29
+ transition-duration: .3s;
30
+ }
31
+
32
+ #menu_overflow > * {
33
+ vertical-align: middle;
34
+ text-align: center;
35
+ }
36
+
37
+ #toolbar[data-menu-overflow-enabled] #menu_overflow_button {
38
+ display: block;
39
+ }
40
+
41
+ #toolbar[data-menu-overflow-opened] #menu_overflow_button {
42
+ background: #030713;
43
+ }
44
+
45
+ #toolbar[data-menu-overflow-enabled][data-menu-overflow-opened] #toolbar-wrapper {
46
+ visibility: hidden;
47
+ }
48
+
49
+ #toolbar[data-menu-overflow-opened] #menu_overflow {
50
+ visibility: visible;
51
+ opacity: 1;
52
+ margin-left: -40px;
53
+ display: block;
54
+ left: 0;
55
+ }
56
+
57
+ #toolbar[data-menu-overflow-enabled] #settings_box {
58
+ right: -40px;
59
+ }
@@ -0,0 +1,202 @@
1
+ @import "./theme_light.css";
2
+
3
+ #settings_button {
4
+ position: relative;
5
+ }
6
+
7
+ #settings_button[data-warning] svg {
8
+ fill: #cb5909;
9
+ }
10
+
11
+ #settings_button[data-warning] svg:hover {
12
+ fill: #ff8c00 !important;
13
+ }
14
+
15
+ #settings_box {
16
+ text-align: center;
17
+ color: #fff;
18
+ min-width: 250px;
19
+ min-height: 150px;
20
+ z-index: -1;
21
+ background-color: #030713;
22
+ border-radius: 5px 5px 0 0;
23
+ padding: 17px;
24
+ font-size: 14px;
25
+ display: none;
26
+ position: absolute;
27
+ bottom: 40px;
28
+ right: 0;
29
+ }
30
+
31
+ [data-active] #settings_box {
32
+ animation: .3s comeUp;
33
+ display: block;
34
+ }
35
+
36
+ @keyframes comeUp {
37
+ 0% {
38
+ opacity: 0;
39
+ transform: translate(0, 90px);
40
+ }
41
+
42
+ 100% {
43
+ opacity: 1;
44
+ transform: translate(0);
45
+ }
46
+ }
47
+
48
+ #settings_box_body {
49
+ text-align: left;
50
+ max-height: 80vh;
51
+ width: 100vw;
52
+ justify-content: center;
53
+ padding: 18px 0;
54
+ display: flex;
55
+ overflow: auto;
56
+ }
57
+
58
+ .settings_box_items_wrapper {
59
+ max-width: 700px;
60
+ flex-wrap: wrap;
61
+ justify-content: center;
62
+ display: flex;
63
+ }
64
+
65
+ .settings_box_item {
66
+ width: 250px;
67
+ background: #0c111b;
68
+ margin: 9px 18px;
69
+ padding: 15px;
70
+ }
71
+
72
+ #settings_box_header .settings_icon {
73
+ fill: none;
74
+ stroke: #24b1b0;
75
+ stroke-width: 2px;
76
+ width: 22px;
77
+ height: 22px;
78
+ margin-right: 10px;
79
+ position: relative;
80
+ top: 4px;
81
+ }
82
+
83
+ #settings_box h3 {
84
+ color: #24b1b0;
85
+ margin: 10px 0;
86
+ font-size: 20px;
87
+ display: inline-block;
88
+ }
89
+
90
+ #settings_close_button {
91
+ float: right;
92
+ fill: #24b1b0;
93
+ }
94
+
95
+ #settings_close_button:hover {
96
+ opacity: .6;
97
+ }
98
+
99
+ label {
100
+ color: #a9a8a8;
101
+ padding-bottom: 3px;
102
+ font-size: 14px;
103
+ display: block;
104
+ }
105
+
106
+ #settings_box .category_title {
107
+ color: #24b1b0;
108
+ margin-top: 4px;
109
+ margin-bottom: 15px;
110
+ font-size: 16px;
111
+ display: inline-block;
112
+ }
113
+
114
+ #settings_box .category_title svg {
115
+ fill: currentColor;
116
+ vertical-align: top;
117
+ width: 18px;
118
+ height: 18px;
119
+ margin-right: 5px;
120
+ }
121
+
122
+ #settings_box .category_subtitle {
123
+ color: #a9a8a8;
124
+ max-width: 220px;
125
+ font-size: 14px;
126
+ }
127
+
128
+ .switch {
129
+ float: right;
130
+ width: 3.5em;
131
+ height: 2em;
132
+ cursor: pointer;
133
+ padding: 0;
134
+ position: relative;
135
+ }
136
+
137
+ .switch input {
138
+ opacity: 0;
139
+ width: 0;
140
+ height: 0;
141
+ position: absolute;
142
+ }
143
+
144
+ .switch .slider {
145
+ vertical-align: middle;
146
+ height: .3em;
147
+ background-color: #4c4c4c;
148
+ border-radius: .15em;
149
+ margin-top: -.15em;
150
+ transition: all .4s;
151
+ position: absolute;
152
+ top: 50%;
153
+ left: .5em;
154
+ right: .5em;
155
+ }
156
+
157
+ .switch .square {
158
+ content: "";
159
+ height: 1em;
160
+ width: 1em;
161
+ color: #030713;
162
+ background-color: #4c4c4c;
163
+ border-radius: .15em;
164
+ margin-top: -.5em;
165
+ transition: all .4s;
166
+ position: absolute;
167
+ top: 50%;
168
+ left: .5em;
169
+ }
170
+
171
+ .switch input + * {
172
+ width: 100%;
173
+ height: 100%;
174
+ border: 1px solid #0000;
175
+ position: relative;
176
+ }
177
+
178
+ .switch input:checked + * .slider {
179
+ background-color: #24b1b0;
180
+ }
181
+
182
+ .switch input:checked + * .square {
183
+ background-color: #24b1b0;
184
+ transform: translateX(1.6em);
185
+ }
186
+
187
+ .settings_box_item[data-disabled] {
188
+ cursor: default;
189
+ background-color: #0c111b66;
190
+ }
191
+
192
+ .settings_box_item[data-disabled] .category_title, .settings_box_item[data-disabled] .switch, .settings_box_item[data-disabled] .category_subtitle {
193
+ opacity: .4;
194
+ }
195
+
196
+ .settings_box_item[data-disabled] .category_title span, .settings_box_item[data-disabled] .category_subtitle {
197
+ text-decoration: line-through;
198
+ }
199
+
200
+ .settings_box_item[data-disabled] .switch {
201
+ cursor: default;
202
+ }
@@ -0,0 +1,67 @@
1
+ .tooltip {
2
+ color: #fff;
3
+ text-align: center;
4
+ max-width: 260px;
5
+ cursor: default;
6
+ background-color: #5e5e5e;
7
+ border-radius: 6px;
8
+ margin-bottom: 6px;
9
+ padding: 10px;
10
+ font-size: 14px;
11
+ display: none;
12
+ position: absolute;
13
+ bottom: 100%;
14
+ }
15
+
16
+ .tooltip:after {
17
+ content: "";
18
+ border: 5px solid #0000;
19
+ border-top-color: #5e5e5e;
20
+ position: absolute;
21
+ top: 100%;
22
+ left: 14px;
23
+ }
24
+
25
+ .tooltip[data-toolip-left] {
26
+ margin-right: 5px;
27
+ }
28
+
29
+ .tooltip[data-toolip-left]:after {
30
+ left: 15px;
31
+ }
32
+
33
+ [data-tooltip-visible] .tooltip, [data-tooltip-auto-visible] .tooltip {
34
+ animation: .4s fadeIn;
35
+ display: block;
36
+ }
37
+
38
+ @keyframes fadeIn {
39
+ 0% {
40
+ opacity: 0;
41
+ }
42
+
43
+ 100% {
44
+ opacity: 1;
45
+ }
46
+ }
47
+
48
+ .tooltip_action {
49
+ border: 1px solid #a0a0a0;
50
+ border-radius: 3px;
51
+ margin-top: 6px;
52
+ padding: 3px 7px;
53
+ display: inline-block;
54
+ }
55
+
56
+ .tooltip_action a {
57
+ vertical-align: middle;
58
+ color: #fff;
59
+ text-decoration: none;
60
+ }
61
+
62
+ .tooltip_icon {
63
+ fill: #fff;
64
+ width: 20px;
65
+ height: 20px;
66
+ vertical-align: middle;
67
+ }
@@ -0,0 +1,282 @@
1
+ import { setStyles } from "./dom.js";
2
+ const animateFallback = () => {
3
+ return Promise.resolve();
4
+ };
5
+ const animateNative = (node, keyframes, {
6
+ signal,
7
+ ...options
8
+ } = {}) => {
9
+ const animation = node.animate(keyframes, options);
10
+ if (signal) {
11
+ signal.addEventListener("abort", () => {
12
+ animation.cancel();
13
+ });
14
+ }
15
+ return new Promise(resolve => {
16
+ animation.onfinish = resolve;
17
+ });
18
+ };
19
+ export const canUseAnimation = () => typeof HTMLElement.prototype.animate === "function";
20
+ export const animateElement = canUseAnimation() ? animateNative : animateFallback;
21
+ export const fadeIn = (node, options) => animateElement(node, [{
22
+ opacity: 0
23
+ }, {
24
+ opacity: 1
25
+ }], options);
26
+ export const fadeOut = (node, options) => animateElement(node, [{
27
+ opacity: 1
28
+ }, {
29
+ opacity: 0
30
+ }], options);
31
+ export const move = (fromNode, toNode, options) => {
32
+ const fromComputedStyle = window.getComputedStyle(fromNode);
33
+ const toComputedStyle = window.getComputedStyle(toNode);
34
+ // get positions of input in toolbar and aElement
35
+ const fromPosition = fromNode.getBoundingClientRect();
36
+ const toPosition = toNode.getBoundingClientRect();
37
+
38
+ // we'll do the animation in a div preventing overflow and pointer events
39
+ const div = document.createElement("div");
40
+ div.style.position = "absolute";
41
+ div.style.left = 0;
42
+ div.style.top = 0;
43
+ div.style.width = `${document.documentElement.scrollWidth}px`;
44
+ div.style.height = `${document.documentElement.scrollHeight}px`;
45
+ div.style.overflow = "hidden";
46
+ div.style.pointerEvents = "none";
47
+ const documentScroll = {
48
+ left: window.pageXOffset || document.documentElement.scrollLeft,
49
+ top: window.pageYOffset || document.documentElement.scrollTop
50
+ };
51
+
52
+ // clone node and style it
53
+ const copy = fromNode.cloneNode(true);
54
+ copy.style.position = "absolute";
55
+ copy.style.left = `${documentScroll.left + fromPosition.left}px`;
56
+ copy.style.top = `${documentScroll.top + fromPosition.top}px`;
57
+ copy.style.maxWidth = `${fromPosition.right - fromPosition.left}px`;
58
+ copy.style.overflow = toComputedStyle.overflow;
59
+ copy.style.textOverflow = toComputedStyle.textOverflow;
60
+ div.appendChild(copy);
61
+ document.body.appendChild(div);
62
+ const left = toPosition.left - fromPosition.left - (parseInt(fromComputedStyle.paddingLeft) || 0);
63
+ const top = toPosition.top - fromPosition.top - (parseInt(fromComputedStyle.paddingTop) || 0);
64
+ // define final position of new element and the duration
65
+ const translate = `translate(${left}px, ${top}px)`;
66
+
67
+ // animate new element
68
+ return animateElement(copy, [{
69
+ transform: "translate(0px, 0px)",
70
+ backgroundColor: fromComputedStyle.backgroundColor,
71
+ color: fromComputedStyle.color,
72
+ fontSize: fromComputedStyle.fontSize,
73
+ height: `${fromPosition.bottom - fromPosition.top}px`,
74
+ width: "100%"
75
+ }, {
76
+ offset: 0.9,
77
+ backgroundColor: fromComputedStyle.backgroundColor,
78
+ color: fromComputedStyle.color
79
+ }, {
80
+ transform: translate,
81
+ backgroundColor: toComputedStyle.backgroundColor,
82
+ color: toComputedStyle.color,
83
+ fontSize: toComputedStyle.fontSize,
84
+ height: `${toPosition.bottom - toPosition.top}px`,
85
+ width: toComputedStyle.width
86
+ }], options).then(() => {
87
+ div.parentNode.removeChild(div);
88
+ });
89
+ };
90
+
91
+ // the whole point of this toolbar animation wass to flight a visual imperfection when it's done by css transition.
92
+ // This imperfection is a white line sometimes flickering at the bottom of the page.
93
+ // It got fixed by removing the usage of calc(100vh - 40px)
94
+ // It was hapenning in chrome, safari but not inside Firefox
95
+ // I assume it's because Firefox does not read parent element min-height while
96
+ // chrome use it to compute min-height: 100%
97
+ export const createToolbarAnimation = () => {
98
+ const collapsedState = {
99
+ "#page": {
100
+ paddingBottom: 0
101
+ },
102
+ "footer": {
103
+ height: 0
104
+ },
105
+ "#toolbar": {
106
+ visibility: "hidden"
107
+ }
108
+ };
109
+ const expandedState = {
110
+ "#page": {
111
+ paddingBottom: "40px"
112
+ },
113
+ "footer": {
114
+ height: "40px"
115
+ },
116
+ "#toolbar": {
117
+ visibility: "visible"
118
+ }
119
+ };
120
+ const expandTransition = transit(collapsedState, expandedState, {
121
+ duration: 300
122
+ });
123
+ const expand = () => {
124
+ expandTransition.play();
125
+ };
126
+ const collapse = () => {
127
+ expandTransition.reverse();
128
+ };
129
+ return {
130
+ expand,
131
+ collapse
132
+ };
133
+ };
134
+ export const transit = (fromState, toState, {
135
+ commitStyles = true,
136
+ fill = "both",
137
+ duration = 300
138
+ } = {}) => {
139
+ const steps = [];
140
+ Object.keys(fromState).forEach(selector => {
141
+ const fromStyles = {};
142
+ const toStyles = {};
143
+ const element = document.querySelector(selector);
144
+ const keyframes = [];
145
+ const fromProperties = fromState[selector];
146
+ const toProperties = toState[selector];
147
+ Object.keys(fromProperties).forEach(propertyName => {
148
+ const from = fromProperties[propertyName];
149
+ const to = toProperties[propertyName];
150
+ fromStyles[propertyName] = from;
151
+ toStyles[propertyName] = to;
152
+ });
153
+ keyframes.push(fromStyles, toStyles);
154
+ let animation;
155
+ if (canUseAnimation()) {
156
+ const effect = new KeyframeEffect(element, keyframes, {
157
+ fill,
158
+ duration
159
+ });
160
+ animation = new Animation(effect);
161
+ } else {
162
+ animation = {
163
+ playbackRate: 1,
164
+ play: () => {
165
+ animation.onfinish();
166
+ },
167
+ reverse: () => {
168
+ animation.playbackRate = -1;
169
+ animation.onfinish();
170
+ },
171
+ finish: () => {},
172
+ onfinish: () => {}
173
+ };
174
+ }
175
+ steps.push({
176
+ element,
177
+ animation,
178
+ fromStyles,
179
+ toStyles
180
+ });
181
+ });
182
+ const play = async () => {
183
+ await Promise.all(steps.map(({
184
+ animation,
185
+ element,
186
+ toStyles
187
+ }) => {
188
+ return new Promise(resolve => {
189
+ animation.onfinish = () => {
190
+ if (commitStyles) {
191
+ setStyles(element, toStyles);
192
+ }
193
+ resolve();
194
+ };
195
+ if (animation.playbackRate === -1) {
196
+ animation.reverse();
197
+ } else {
198
+ animation.play();
199
+ }
200
+ });
201
+ }));
202
+ };
203
+ const reverse = async () => {
204
+ await Promise.all(steps.map(({
205
+ animation,
206
+ element,
207
+ fromStyles
208
+ }) => {
209
+ return new Promise(resolve => {
210
+ animation.onfinish = () => {
211
+ if (commitStyles) {
212
+ setStyles(element, fromStyles);
213
+ }
214
+ resolve();
215
+ };
216
+ animation.reverse();
217
+ });
218
+ }));
219
+ };
220
+ const finish = async () => {
221
+ steps.forEach(({
222
+ animation
223
+ }) => {
224
+ animation.finish();
225
+ });
226
+ };
227
+ return {
228
+ play,
229
+ reverse,
230
+ finish
231
+ };
232
+ };
233
+ export const startJavaScriptAnimation = ({
234
+ duration = 300,
235
+ timingFunction = t => t,
236
+ onProgress = () => {},
237
+ onCancel = () => {},
238
+ onComplete = () => {}
239
+ }) => {
240
+ if (isNaN(duration)) {
241
+ // console.warn(`duration must be a number, received ${duration}`)
242
+ return () => {};
243
+ }
244
+ duration = parseInt(duration, 10);
245
+ const startMs = performance.now();
246
+ let currentRequestAnimationFrameId;
247
+ let done = false;
248
+ let rawProgress = 0;
249
+ let progress = 0;
250
+ const handler = () => {
251
+ currentRequestAnimationFrameId = null;
252
+ const nowMs = performance.now();
253
+ rawProgress = Math.min((nowMs - startMs) / duration, 1);
254
+ progress = timingFunction(rawProgress);
255
+ done = rawProgress === 1;
256
+ onProgress({
257
+ done,
258
+ rawProgress,
259
+ progress
260
+ });
261
+ if (done) {
262
+ onComplete();
263
+ } else {
264
+ currentRequestAnimationFrameId = window.requestAnimationFrame(handler);
265
+ }
266
+ };
267
+ handler();
268
+ const stop = () => {
269
+ if (currentRequestAnimationFrameId) {
270
+ window.cancelAnimationFrame(currentRequestAnimationFrameId);
271
+ currentRequestAnimationFrameId = null;
272
+ }
273
+ if (!done) {
274
+ done = true;
275
+ onCancel({
276
+ rawProgress,
277
+ progress
278
+ });
279
+ }
280
+ };
281
+ return stop;
282
+ };
@@ -0,0 +1,7 @@
1
+ import { animationsEnabledSignal } from "./animation_signals.js";
2
+ export const enableAnimations = () => {
3
+ animationsEnabledSignal.value = true;
4
+ };
5
+ export const disableAnimations = () => {
6
+ animationsEnabledSignal.value = false;
7
+ };
@@ -0,0 +1,10 @@
1
+ import { effect } from "./signals.mjs";
2
+ import { animationsEnabledSignal } from "./animation_signals.js";
3
+ effect(() => {
4
+ const animationsEnabled = animationsEnabledSignal.value;
5
+ if (animationsEnabled) {
6
+ document.documentElement.removeAttribute("data-animation-disabled");
7
+ } else {
8
+ document.documentElement.setAttribute("data-animation-disabled", "");
9
+ }
10
+ });
@@ -0,0 +1,4 @@
1
+ import { signal } from "./signals.mjs";
2
+ import { paramsFromParentWindow } from "./parent_window_context.js";
3
+ import { stateFromLocalStorage } from "./toolbar_state_context.js";
4
+ export const animationsEnabledSignal = signal(typeof stateFromLocalStorage.animationsEnabled === "boolean" ? stateFromLocalStorage.animationsEnabled : typeof paramsFromParentWindow.animationsEnabled === "boolean" ? paramsFromParentWindow.animationsEnabled : false);
@@ -0,0 +1,7 @@
1
+ import { changesTooltipOpenedSignal } from "./changes_signals.js";
2
+ export const openChangesToolip = () => {
3
+ changesTooltipOpenedSignal.value = true;
4
+ };
5
+ export const closeChangesToolip = () => {
6
+ changesTooltipOpenedSignal.value = false;
7
+ };
@@ -0,0 +1,57 @@
1
+ import { effect } from "./signals.mjs";
2
+ import { parentWindowReloader } from "./parent_window_context.js";
3
+ import { autoreloadEnabledSignal, changesSignal } from "./parent_window_signals.js";
4
+ import { changesTooltipOpenedSignal } from "./changes_signals.js";
5
+ import { openChangesToolip, closeChangesToolip } from "./changes_actions.js";
6
+ import { enableVariant } from "./variant.js";
7
+ const changesIndicator = document.querySelector("#changes_indicator");
8
+ export const renderChangesIndicator = () => {
9
+ effect(() => {
10
+ const autoreloadEnabled = autoreloadEnabledSignal.value;
11
+ const changes = changesSignal.value;
12
+ const changeCount = changes.length;
13
+ enableVariant(changesIndicator, {
14
+ changes: !autoreloadEnabled && changeCount ? "yes" : "no"
15
+ });
16
+ if (changeCount) {
17
+ changesIndicator.querySelector(".tooltip_text").innerHTML = computeTooltipText({
18
+ changes
19
+ });
20
+ changesIndicator.querySelector(".tooltip_text a").onclick = () => {
21
+ // eslint-disable-next-line no-alert
22
+ window.alert(JSON.stringify(changes, null, " "));
23
+ console.log(changes);
24
+ };
25
+ changesIndicator.querySelector(".changes_text").innerHTML = changeCount;
26
+ }
27
+ });
28
+ changesIndicator.querySelector(".tooltip_action").onclick = () => {
29
+ parentWindowReloader.reload();
30
+ };
31
+ effect(() => {
32
+ const changesTooltipOpened = changesTooltipOpenedSignal.value;
33
+ if (changesTooltipOpened) {
34
+ changesIndicator.setAttribute("data-tooltip-visible", "");
35
+ } else {
36
+ changesIndicator.removeAttribute("data-tooltip-visible");
37
+ }
38
+ });
39
+ const button = changesIndicator.querySelector("button");
40
+ button.onclick = () => {
41
+ const changesTooltipOpened = changesTooltipOpenedSignal.value;
42
+ if (changesTooltipOpened) {
43
+ closeChangesToolip();
44
+ } else {
45
+ openChangesToolip();
46
+ }
47
+ };
48
+ };
49
+ const computeTooltipText = ({
50
+ changes
51
+ }) => {
52
+ const changesCount = changes.length;
53
+ if (changesCount === 1) {
54
+ return `There is <a href="javascript:void(0)">1</a> change to apply`;
55
+ }
56
+ return `There is <a href="javascript:void(0)">${changesCount}<a> changes to apply`;
57
+ };
@@ -0,0 +1,2 @@
1
+ import { signal } from "./signals.mjs";
2
+ export const changesTooltipOpenedSignal = signal(false);