@creative-web-solution/front-library 7.1.54 → 7.1.55
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/CHANGELOG.md +4 -0
- package/Modules/Popin/Popin.ts +291 -320
- package/Modules/Popin/PopinAccessibility.ts +74 -36
- package/Modules/Popin/PopinBackground.ts +26 -31
- package/Modules/Popin/PopinController.ts +82 -92
- package/Modules/Popin/Tools.ts +53 -59
- package/README.md +1 -1
- package/package.json +1 -1
package/Modules/Popin/Popin.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { on, off }
|
|
2
|
-
import KeyboardHandler
|
|
3
|
-
import { extend }
|
|
4
|
-
import { strToDOM }
|
|
5
|
-
import { append }
|
|
6
|
-
import { windowSize }
|
|
7
|
-
import PopinBackground
|
|
8
|
-
import PopinAccessibility
|
|
9
|
-
import { defaultOptions, CLICK_EVENT_NAME } from
|
|
10
|
-
import quickTemplate
|
|
11
|
-
|
|
1
|
+
import { on, off } from "../../Events/EventsManager";
|
|
2
|
+
import KeyboardHandler from "../../Events/KeyboardHandler";
|
|
3
|
+
import { extend } from "../../Helpers/Extend";
|
|
4
|
+
import { strToDOM } from "../../DOM/StrToDOM";
|
|
5
|
+
import { append } from "../../DOM/Manipulation";
|
|
6
|
+
import { windowSize } from "../../DOM/WindowSize";
|
|
7
|
+
import PopinBackground from "./PopinBackground";
|
|
8
|
+
import PopinAccessibility from "./PopinAccessibility";
|
|
9
|
+
import { defaultOptions, CLICK_EVENT_NAME } from "./Tools";
|
|
10
|
+
import quickTemplate from "../QuickTemplate";
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* Create a simple popin
|
|
@@ -22,437 +21,427 @@ import quickTemplate from '../QuickTemplate';
|
|
|
22
21
|
* ```
|
|
23
22
|
*/
|
|
24
23
|
export default class Popin {
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
#$popinContent: HTMLElement;
|
|
24
|
+
#loadingPromise: Promise<void> | null = null;
|
|
25
|
+
#loaderOpened = false;
|
|
26
|
+
#popinOpened = false;
|
|
27
|
+
#$loader: HTMLElement;
|
|
28
|
+
#templates: FLib.Popin.TemplatesOptions;
|
|
29
|
+
#selectors: FLib.Popin.SelectorsOptions;
|
|
30
|
+
#animations: FLib.Popin.AnimationsOptions;
|
|
31
|
+
#$popinContent: HTMLElement;
|
|
34
32
|
#$initialFocus;
|
|
35
|
-
#isInlinePopin:
|
|
36
|
-
#focusControl:
|
|
33
|
+
#isInlinePopin: boolean;
|
|
34
|
+
#focusControl: PopinAccessibility;
|
|
37
35
|
#keyboardControls;
|
|
38
|
-
#options:
|
|
36
|
+
#options: FLib.Popin.Options;
|
|
39
37
|
#controllerOptions: FLib.Popin.ControllerOptions | undefined;
|
|
40
|
-
#backgroundLayer:
|
|
38
|
+
#backgroundLayer: PopinBackground | undefined;
|
|
41
39
|
#tick;
|
|
42
|
-
#$popin:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
#$popin: HTMLElement;
|
|
41
|
+
|
|
42
|
+
constructor(
|
|
43
|
+
userOptions: FLib.Popin.OptionsInit = {},
|
|
44
|
+
$popin?: HTMLElement,
|
|
45
|
+
_controllerOptions?: FLib.Popin.ControllerOptions,
|
|
46
|
+
) {
|
|
47
|
+
if (!("AbortController" in window)) {
|
|
48
|
+
throw "This plugin uses fecth and AbortController. You may need to add a polyfill for this browser.";
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
this.#isInlinePopin
|
|
51
|
+
this.#isInlinePopin = !!$popin;
|
|
52
52
|
this.#controllerOptions = _controllerOptions;
|
|
53
53
|
|
|
54
|
-
if (
|
|
55
|
-
this.#options
|
|
56
|
-
this.#backgroundLayer =
|
|
57
|
-
|
|
58
|
-
else {
|
|
59
|
-
this.#options
|
|
60
|
-
this.#backgroundLayer = this.#options.isBackgroundAside
|
|
54
|
+
if (_controllerOptions) {
|
|
55
|
+
this.#options = userOptions as FLib.Popin.Options;
|
|
56
|
+
this.#backgroundLayer =
|
|
57
|
+
_controllerOptions.background as PopinBackground;
|
|
58
|
+
} else {
|
|
59
|
+
this.#options = extend(defaultOptions, userOptions);
|
|
60
|
+
this.#backgroundLayer = this.#options.isBackgroundAside
|
|
61
|
+
? new PopinBackground(this, this.#options)
|
|
62
|
+
: undefined;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
this.#
|
|
65
|
-
this.#selectors = this.#options.selectors;
|
|
65
|
+
this.#templates = this.#options.templates;
|
|
66
|
+
this.#selectors = this.#options.selectors;
|
|
66
67
|
this.#animations = this.#options.animations;
|
|
67
68
|
// Add loader in the popin
|
|
68
|
-
this.#$loader = strToDOM(
|
|
69
|
+
this.#$loader = strToDOM(this.#templates.popinLoader) as HTMLElement;
|
|
69
70
|
|
|
70
|
-
if (
|
|
71
|
+
if ($popin) {
|
|
71
72
|
this.#$popin = $popin;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
73
|
+
} else {
|
|
74
74
|
const popinHtml = this.#templates.popin;
|
|
75
75
|
|
|
76
76
|
// Add popin template
|
|
77
|
-
this.#$popin = strToDOM(
|
|
78
|
-
append(
|
|
77
|
+
this.#$popin = strToDOM(popinHtml) as HTMLElement;
|
|
78
|
+
append(this.#$popin, document.body);
|
|
79
79
|
|
|
80
|
-
append(
|
|
80
|
+
append(this.#$loader, this.#$popin);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
// Init the element that will receive the content
|
|
84
|
-
this.#$popinContent =
|
|
84
|
+
this.#$popinContent =
|
|
85
|
+
this.#$popin.querySelector(this.#selectors.popinContent) ||
|
|
86
|
+
this.#$popin;
|
|
85
87
|
|
|
86
88
|
// Keyboard TAB focus control
|
|
87
|
-
this.#focusControl = new PopinAccessibility(
|
|
88
|
-
|
|
89
|
+
this.#focusControl = new PopinAccessibility(this.#$popin);
|
|
89
90
|
|
|
90
91
|
// ------------------- BINDING
|
|
91
92
|
|
|
93
|
+
on(this.#$popin, {
|
|
94
|
+
eventsName: CLICK_EVENT_NAME,
|
|
95
|
+
selector: this.#selectors.links,
|
|
96
|
+
callback: this.#openPopinHandler,
|
|
97
|
+
});
|
|
92
98
|
|
|
93
|
-
on(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"callback": this.#openPopinHandler
|
|
99
|
-
}
|
|
100
|
-
);
|
|
99
|
+
on(this.#$popin, {
|
|
100
|
+
eventsName: "submit",
|
|
101
|
+
selector: this.#selectors.forms,
|
|
102
|
+
callback: this.#openPopinHandler,
|
|
103
|
+
});
|
|
101
104
|
|
|
102
|
-
on(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
on(
|
|
110
|
-
this.#$popin,
|
|
111
|
-
{
|
|
112
|
-
"eventsName": CLICK_EVENT_NAME,
|
|
113
|
-
"selector": this.#selectors.btClosePopin,
|
|
114
|
-
"callback": this.#closePopinHandler
|
|
115
|
-
}
|
|
116
|
-
);
|
|
105
|
+
on(this.#$popin, {
|
|
106
|
+
eventsName: CLICK_EVENT_NAME,
|
|
107
|
+
selector: this.#selectors.btClosePopin,
|
|
108
|
+
callback: this.#closePopinHandler,
|
|
109
|
+
});
|
|
117
110
|
|
|
118
111
|
if (!this.#options.isBackgroundAside && !this.#options.modal) {
|
|
119
|
-
on(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"callback": this.#clickBgHandler
|
|
124
|
-
}
|
|
125
|
-
);
|
|
112
|
+
on(this.#$popin, {
|
|
113
|
+
eventsName: CLICK_EVENT_NAME,
|
|
114
|
+
callback: this.#clickBgHandler,
|
|
115
|
+
});
|
|
126
116
|
}
|
|
127
117
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.#closePopinHandler( e );
|
|
118
|
+
if (this.#options.enableKeyboard) {
|
|
119
|
+
this.#keyboardControls = new KeyboardHandler(this.#$popin, {
|
|
120
|
+
preventDefault: false,
|
|
121
|
+
onEscape: (e) => {
|
|
122
|
+
this.#closePopinHandler(e);
|
|
134
123
|
},
|
|
135
|
-
|
|
136
|
-
this.#focusControl.handleBackwardTab(
|
|
124
|
+
onTabReverse: (e) => {
|
|
125
|
+
this.#focusControl.handleBackwardTab(e);
|
|
126
|
+
},
|
|
127
|
+
onTab: (e) => {
|
|
128
|
+
this.#focusControl.handleForwardTab(e);
|
|
137
129
|
},
|
|
138
|
-
"onTab": e => {
|
|
139
|
-
this.#focusControl.handleForwardTab( e );
|
|
140
|
-
}
|
|
141
130
|
});
|
|
142
131
|
}
|
|
143
132
|
}
|
|
144
133
|
|
|
145
|
-
|
|
146
134
|
#addAccessibility = (): void => {
|
|
147
135
|
this.#focusControl.refresh();
|
|
148
|
-
this.#focusControl.toggleTabIndexNavigation( true );
|
|
149
136
|
this.#focusControl.focusFirstElement();
|
|
150
|
-
}
|
|
151
|
-
|
|
137
|
+
};
|
|
152
138
|
|
|
153
139
|
// ------------------------------ LOADER
|
|
154
140
|
|
|
155
|
-
|
|
156
141
|
#openLoader = (): Promise<any> => {
|
|
157
|
-
if (
|
|
142
|
+
if (this.#loaderOpened) {
|
|
158
143
|
return Promise.resolve();
|
|
159
144
|
}
|
|
160
145
|
|
|
161
|
-
return this.#animations.openLoader(
|
|
146
|
+
return this.#animations.openLoader(this.#$loader).then(() => {
|
|
162
147
|
this.#loaderOpened = true;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
148
|
+
});
|
|
149
|
+
};
|
|
166
150
|
|
|
167
151
|
#closeLoader = (): Promise<void> => {
|
|
168
|
-
if (
|
|
152
|
+
if (!this.#loaderOpened) {
|
|
169
153
|
return Promise.resolve();
|
|
170
154
|
}
|
|
171
155
|
|
|
172
|
-
return this.#animations.closeLoader(
|
|
156
|
+
return this.#animations.closeLoader(this.#$loader).then(() => {
|
|
173
157
|
this.#loaderOpened = false;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
158
|
+
});
|
|
159
|
+
};
|
|
177
160
|
|
|
178
161
|
// ------------------------------ POPIN SHOW/HIDE
|
|
179
162
|
|
|
180
|
-
|
|
181
163
|
#showBackgroundLayer = (): Promise<void> => {
|
|
182
|
-
return this.#backgroundLayer
|
|
183
|
-
|
|
184
|
-
|
|
164
|
+
return this.#backgroundLayer
|
|
165
|
+
? this.#backgroundLayer.open()
|
|
166
|
+
: Promise.resolve();
|
|
167
|
+
};
|
|
185
168
|
|
|
186
169
|
#hideBackgroundLayer = (): Promise<void> => {
|
|
187
|
-
return this.#backgroundLayer
|
|
188
|
-
|
|
189
|
-
|
|
170
|
+
return this.#backgroundLayer
|
|
171
|
+
? this.#backgroundLayer.close()
|
|
172
|
+
: Promise.resolve();
|
|
173
|
+
};
|
|
190
174
|
|
|
191
175
|
#openPopin = (): Promise<void> => {
|
|
192
|
-
if (
|
|
176
|
+
if (this.#popinOpened) {
|
|
193
177
|
return Promise.resolve();
|
|
194
178
|
}
|
|
195
179
|
|
|
196
180
|
this.#$initialFocus = document.activeElement;
|
|
197
181
|
this.#resize();
|
|
198
182
|
|
|
199
|
-
if (
|
|
200
|
-
on(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
183
|
+
if (this.#options.autoResize) {
|
|
184
|
+
on(window, {
|
|
185
|
+
eventsName: "resize",
|
|
186
|
+
callback: this.#resizeHandler,
|
|
187
|
+
});
|
|
204
188
|
}
|
|
205
189
|
|
|
206
190
|
return this.#showBackgroundLayer()
|
|
207
|
-
.then(
|
|
208
|
-
return this.#animations.initOpenPopin(
|
|
209
|
-
}
|
|
210
|
-
.then(
|
|
211
|
-
if (
|
|
212
|
-
return this.#options.onOpen.call(
|
|
191
|
+
.then(() => {
|
|
192
|
+
return this.#animations.initOpenPopin(this.#$popin);
|
|
193
|
+
})
|
|
194
|
+
.then(() => {
|
|
195
|
+
if (this.#options.onOpen) {
|
|
196
|
+
return this.#options.onOpen.call(this, this.#$popin);
|
|
213
197
|
}
|
|
214
|
-
}
|
|
215
|
-
.then(
|
|
216
|
-
if (
|
|
198
|
+
})
|
|
199
|
+
.then(() => {
|
|
200
|
+
if (this.#isInlinePopin) {
|
|
217
201
|
this.#addAccessibility();
|
|
218
202
|
}
|
|
219
|
-
return this.#animations.openPopin(
|
|
220
|
-
}
|
|
221
|
-
.then(
|
|
203
|
+
return this.#animations.openPopin(this.#$popin);
|
|
204
|
+
})
|
|
205
|
+
.then(() => {
|
|
222
206
|
this.#popinOpened = true;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
207
|
+
});
|
|
208
|
+
};
|
|
226
209
|
|
|
227
210
|
#closePopin = (): Promise<void> => {
|
|
228
|
-
if (
|
|
211
|
+
if (!this.#popinOpened) {
|
|
229
212
|
return Promise.resolve();
|
|
230
213
|
}
|
|
231
214
|
|
|
232
|
-
off(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
215
|
+
off(window, {
|
|
216
|
+
eventsName: "resize",
|
|
217
|
+
callback: this.#resizeHandler,
|
|
218
|
+
});
|
|
236
219
|
|
|
237
220
|
return this.#animations
|
|
238
|
-
.closePopin(
|
|
239
|
-
.then(
|
|
240
|
-
.then(
|
|
241
|
-
if (
|
|
242
|
-
return this.#options.onClose.call(
|
|
221
|
+
.closePopin(this.#$popin)
|
|
222
|
+
.then(this.#hideBackgroundLayer.bind(this))
|
|
223
|
+
.then(() => {
|
|
224
|
+
if (this.#options.onClose) {
|
|
225
|
+
return this.#options.onClose.call(this, this.#$popin);
|
|
243
226
|
}
|
|
244
|
-
}
|
|
245
|
-
.then(
|
|
227
|
+
})
|
|
228
|
+
.then(() => {
|
|
246
229
|
this.#popinOpened = false;
|
|
247
230
|
|
|
248
|
-
if (
|
|
231
|
+
if (!this.#isInlinePopin) {
|
|
249
232
|
this.#clearPopin();
|
|
250
233
|
}
|
|
251
234
|
this.#$initialFocus.focus();
|
|
252
235
|
});
|
|
253
|
-
}
|
|
254
|
-
|
|
236
|
+
};
|
|
255
237
|
|
|
256
238
|
// ------------------------------ POPIN CONTENT
|
|
257
239
|
|
|
258
|
-
|
|
259
240
|
#resizeRAF = (): void => {
|
|
260
|
-
window.requestAnimationFrame(
|
|
261
|
-
}
|
|
262
|
-
|
|
241
|
+
window.requestAnimationFrame(this.#resize.bind(this));
|
|
242
|
+
};
|
|
263
243
|
|
|
264
|
-
#setPopin = (
|
|
244
|
+
#setPopin = (resp: string): Promise<void> => {
|
|
265
245
|
this.#$popinContent.innerHTML = resp;
|
|
266
246
|
|
|
267
|
-
return this.#options
|
|
268
|
-
|
|
269
|
-
|
|
247
|
+
return this.#options
|
|
248
|
+
.onLoad(this.#$popin)
|
|
249
|
+
.then(this.#resizeRAF.bind(this));
|
|
250
|
+
};
|
|
270
251
|
|
|
271
252
|
#clearPopin = (): void => {
|
|
272
|
-
this.#$popinContent.innerHTML =
|
|
253
|
+
this.#$popinContent.innerHTML = "";
|
|
273
254
|
this.#resizeRAF();
|
|
274
|
-
this.#focusControl.
|
|
275
|
-
}
|
|
255
|
+
this.#focusControl.clean();
|
|
256
|
+
};
|
|
276
257
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
258
|
+
#setPopinError = (message: string): void => {
|
|
259
|
+
this.#$popinContent.innerHTML = quickTemplate(
|
|
260
|
+
this.#templates.errorMessage,
|
|
261
|
+
{ message: message },
|
|
262
|
+
);
|
|
280
263
|
this.#resizeRAF();
|
|
281
|
-
}
|
|
282
|
-
|
|
264
|
+
};
|
|
283
265
|
|
|
284
266
|
// ------------------------------ POPIN LOADING
|
|
285
267
|
|
|
268
|
+
#_load = (
|
|
269
|
+
url: string,
|
|
270
|
+
type: FLib.Popin.ResponseType,
|
|
271
|
+
userRequestOptions?: RequestInit,
|
|
272
|
+
): Promise<void> => {
|
|
273
|
+
let requestOptions: RequestInit;
|
|
286
274
|
|
|
287
|
-
|
|
288
|
-
let requestOptions: RequestInit ;
|
|
289
|
-
|
|
290
|
-
this.#loadingPromise = new Promise( ( resolve, reject ) => {
|
|
275
|
+
this.#loadingPromise = new Promise((resolve, reject) => {
|
|
291
276
|
const myHeaders = new Headers();
|
|
292
|
-
myHeaders.append(
|
|
277
|
+
myHeaders.append("X-Requested-With", "XMLHttpRequest");
|
|
293
278
|
requestOptions = {
|
|
294
|
-
|
|
279
|
+
headers: myHeaders,
|
|
295
280
|
};
|
|
296
281
|
|
|
297
|
-
if (
|
|
298
|
-
requestOptions = extend(
|
|
282
|
+
if (userRequestOptions) {
|
|
283
|
+
requestOptions = extend({}, requestOptions, userRequestOptions);
|
|
299
284
|
}
|
|
300
285
|
|
|
301
286
|
this.#openPopin()
|
|
302
|
-
.then(
|
|
303
|
-
.then(
|
|
304
|
-
fetch(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
287
|
+
.then(() => this.#openLoader())
|
|
288
|
+
.then(() => {
|
|
289
|
+
fetch(url, requestOptions)
|
|
290
|
+
.then((response) => {
|
|
291
|
+
if (
|
|
292
|
+
!this.#options.autoHandleAjaxError ||
|
|
293
|
+
(response.status >= 200 &&
|
|
294
|
+
response.status < 300)
|
|
295
|
+
) {
|
|
310
296
|
return response;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
297
|
+
} else {
|
|
298
|
+
const error: Error & { response? } = new Error(
|
|
299
|
+
response.statusText,
|
|
300
|
+
);
|
|
314
301
|
error.response = response;
|
|
315
302
|
throw error;
|
|
316
303
|
}
|
|
317
304
|
})
|
|
318
|
-
.then(
|
|
305
|
+
.then((response) => {
|
|
319
306
|
let prom;
|
|
320
307
|
|
|
321
|
-
if (
|
|
308
|
+
if (type === "arrayBuffer") {
|
|
322
309
|
prom = response.arrayBuffer();
|
|
323
|
-
}
|
|
324
|
-
else if ( type === 'blob' ) {
|
|
310
|
+
} else if (type === "blob") {
|
|
325
311
|
prom = response.blob();
|
|
326
|
-
}
|
|
327
|
-
else if ( type === 'json' ) {
|
|
312
|
+
} else if (type === "json") {
|
|
328
313
|
prom = response.json();
|
|
329
|
-
}
|
|
330
|
-
else if ( type === 'formData' ) {
|
|
314
|
+
} else if (type === "formData") {
|
|
331
315
|
prom = response.formData();
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
316
|
+
} else {
|
|
334
317
|
prom = response.text();
|
|
335
318
|
}
|
|
336
319
|
|
|
337
|
-
return prom.then(
|
|
338
|
-
return [
|
|
339
|
-
}
|
|
340
|
-
}
|
|
320
|
+
return prom.then((ct) => {
|
|
321
|
+
return [ct, response];
|
|
322
|
+
});
|
|
323
|
+
})
|
|
341
324
|
.then(
|
|
342
|
-
data => {
|
|
343
|
-
const [
|
|
344
|
-
const isHttpError =
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
325
|
+
(data) => {
|
|
326
|
+
const [body, response] = data;
|
|
327
|
+
const isHttpError =
|
|
328
|
+
response.status < 200 ||
|
|
329
|
+
response.status >= 300;
|
|
330
|
+
const normResponse = this.#options.normalize(
|
|
331
|
+
body,
|
|
332
|
+
response,
|
|
333
|
+
isHttpError,
|
|
334
|
+
this.#$popin,
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
if (normResponse.success) {
|
|
338
|
+
this.#setPopin(normResponse.data).then(
|
|
339
|
+
() => {
|
|
340
|
+
this.#addAccessibility();
|
|
341
|
+
resolve();
|
|
342
|
+
},
|
|
343
|
+
);
|
|
344
|
+
} else {
|
|
345
|
+
this.#setPopinError(
|
|
346
|
+
this.#options.errorMessage,
|
|
347
|
+
);
|
|
355
348
|
this.#addAccessibility();
|
|
356
349
|
reject();
|
|
357
350
|
}
|
|
358
351
|
},
|
|
359
|
-
err => {
|
|
360
|
-
this.#setPopinError(
|
|
352
|
+
(err) => {
|
|
353
|
+
this.#setPopinError(this.#options.errorMessage);
|
|
361
354
|
this.#addAccessibility();
|
|
362
|
-
reject(
|
|
363
|
-
}
|
|
355
|
+
reject(err);
|
|
356
|
+
},
|
|
364
357
|
)
|
|
365
|
-
.finally(
|
|
358
|
+
.finally(() => {
|
|
366
359
|
this.#loadingPromise = null;
|
|
367
360
|
this.#closeLoader();
|
|
368
|
-
}
|
|
361
|
+
});
|
|
369
362
|
})
|
|
370
|
-
.catch(
|
|
371
|
-
|
|
372
|
-
} );
|
|
363
|
+
.catch((err) => reject(err));
|
|
364
|
+
});
|
|
373
365
|
|
|
374
366
|
return this.#loadingPromise;
|
|
375
|
-
}
|
|
367
|
+
};
|
|
376
368
|
|
|
377
|
-
|
|
378
|
-
#_loadLink = ( $link: HTMLAnchorElement ): Promise<void> => {
|
|
369
|
+
#_loadLink = ($link: HTMLAnchorElement): Promise<void> => {
|
|
379
370
|
return this.#_load(
|
|
380
371
|
$link.href,
|
|
381
|
-
this.#options.setLinkResponseType(
|
|
372
|
+
this.#options.setLinkResponseType($link.href, $link, this.#$popin),
|
|
382
373
|
);
|
|
383
|
-
}
|
|
384
|
-
|
|
374
|
+
};
|
|
385
375
|
|
|
386
|
-
#_loadForm = (
|
|
376
|
+
#_loadForm = ($form: HTMLFormElement): Promise<void> => {
|
|
387
377
|
let validationResult;
|
|
388
378
|
|
|
389
|
-
if (
|
|
390
|
-
validationResult = this.#options.checkValidity(
|
|
391
|
-
if (
|
|
379
|
+
if (this.#options.checkValidity) {
|
|
380
|
+
validationResult = this.#options.checkValidity($form, this.#$popin);
|
|
381
|
+
if (validationResult === false) {
|
|
392
382
|
return Promise.reject();
|
|
393
383
|
}
|
|
394
384
|
}
|
|
395
385
|
|
|
396
|
-
const validationProm =
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
.then( () => {
|
|
401
|
-
return this.#_load(
|
|
402
|
-
$form.action,
|
|
403
|
-
this.#options.setFormResponseType( $form, this.#$popin ),
|
|
404
|
-
{
|
|
405
|
-
"body": new FormData( $form ),
|
|
406
|
-
"method": $form.method || 'POST'
|
|
407
|
-
} );
|
|
408
|
-
} );
|
|
409
|
-
}
|
|
386
|
+
const validationProm =
|
|
387
|
+
!validationResult || validationResult === true
|
|
388
|
+
? Promise.resolve()
|
|
389
|
+
: validationResult;
|
|
410
390
|
|
|
391
|
+
return validationProm.then(() => {
|
|
392
|
+
return this.#_load(
|
|
393
|
+
$form.action,
|
|
394
|
+
this.#options.setFormResponseType($form, this.#$popin),
|
|
395
|
+
{
|
|
396
|
+
body: new FormData($form),
|
|
397
|
+
method: $form.method || "POST",
|
|
398
|
+
},
|
|
399
|
+
);
|
|
400
|
+
});
|
|
401
|
+
};
|
|
411
402
|
|
|
412
|
-
#openPopinHandler = (
|
|
403
|
+
#openPopinHandler = (e: Event, $target: HTMLElement): void => {
|
|
413
404
|
e.preventDefault();
|
|
414
405
|
|
|
415
|
-
if (
|
|
406
|
+
if (this.#loadingPromise) {
|
|
416
407
|
return;
|
|
417
408
|
}
|
|
418
409
|
|
|
419
|
-
if (
|
|
420
|
-
this.#_loadForm(
|
|
410
|
+
if ($target.nodeName === "FORM") {
|
|
411
|
+
this.#_loadForm($target as HTMLFormElement);
|
|
421
412
|
return;
|
|
422
413
|
}
|
|
423
414
|
|
|
424
|
-
const url = $target.getAttribute(
|
|
415
|
+
const url = $target.getAttribute("href");
|
|
425
416
|
|
|
426
|
-
if (
|
|
417
|
+
if (url && url.indexOf("#") === 0) {
|
|
427
418
|
return;
|
|
428
419
|
}
|
|
429
420
|
|
|
430
|
-
this.#_loadLink(
|
|
431
|
-
}
|
|
432
|
-
|
|
421
|
+
this.#_loadLink($target as HTMLAnchorElement);
|
|
422
|
+
};
|
|
433
423
|
|
|
434
|
-
#closePopinHandler = (
|
|
424
|
+
#closePopinHandler = (e: Event): void => {
|
|
435
425
|
e.preventDefault();
|
|
436
426
|
|
|
437
|
-
if (
|
|
427
|
+
if (this.#controllerOptions) {
|
|
438
428
|
this.#controllerOptions.controller.close();
|
|
439
429
|
return;
|
|
440
430
|
}
|
|
441
431
|
|
|
442
432
|
this.#closePopin();
|
|
443
|
-
}
|
|
433
|
+
};
|
|
444
434
|
|
|
445
|
-
#clickBgHandler = (
|
|
435
|
+
#clickBgHandler = (e: Event): void => {
|
|
446
436
|
const $target = e.target as HTMLElement;
|
|
447
437
|
|
|
448
438
|
if (!$target?.closest(this.#options.selectors.popinBody)) {
|
|
449
439
|
this.#closePopinHandler(e);
|
|
450
440
|
}
|
|
451
|
-
}
|
|
452
|
-
|
|
441
|
+
};
|
|
453
442
|
|
|
454
443
|
#resize = (): void => {
|
|
455
|
-
if (
|
|
444
|
+
if (!this.#options.autoResize) {
|
|
456
445
|
return;
|
|
457
446
|
}
|
|
458
447
|
|
|
@@ -460,62 +449,58 @@ export default class Popin {
|
|
|
460
449
|
|
|
461
450
|
const maxHeight = viewportSize.height - this.#options.marginHeight * 2;
|
|
462
451
|
|
|
463
|
-
this.#$popinContent.style.maxHeight = `${
|
|
452
|
+
this.#$popinContent.style.maxHeight = `${maxHeight}px`;
|
|
464
453
|
|
|
465
454
|
this.#tick = false;
|
|
466
|
-
}
|
|
467
|
-
|
|
455
|
+
};
|
|
468
456
|
|
|
469
457
|
#resizeHandler = (): void => {
|
|
470
|
-
if (
|
|
458
|
+
if (this.#tick) {
|
|
471
459
|
return;
|
|
472
460
|
}
|
|
473
461
|
|
|
474
462
|
this.#tick = true;
|
|
475
463
|
|
|
476
|
-
window.requestAnimationFrame(
|
|
477
|
-
}
|
|
478
|
-
|
|
464
|
+
window.requestAnimationFrame(this.#resize.bind(this));
|
|
465
|
+
};
|
|
479
466
|
|
|
480
467
|
/**
|
|
481
468
|
* Load a page from a link and display the result it in the popin
|
|
482
469
|
*/
|
|
483
|
-
loadLink(
|
|
484
|
-
if (
|
|
470
|
+
loadLink($link: HTMLAnchorElement): Promise<void> {
|
|
471
|
+
if (this.#loadingPromise) {
|
|
485
472
|
return this.#loadingPromise;
|
|
486
473
|
}
|
|
487
474
|
|
|
488
|
-
return this.#_loadLink(
|
|
475
|
+
return this.#_loadLink($link);
|
|
489
476
|
}
|
|
490
477
|
|
|
491
|
-
|
|
492
478
|
/**
|
|
493
479
|
* Send a form and display the result it in the popin
|
|
494
480
|
*/
|
|
495
|
-
loadForm(
|
|
496
|
-
if (
|
|
481
|
+
loadForm($form: HTMLFormElement): Promise<void> {
|
|
482
|
+
if (this.#loadingPromise) {
|
|
497
483
|
return this.#loadingPromise;
|
|
498
484
|
}
|
|
499
485
|
|
|
500
|
-
return this.#_loadForm(
|
|
486
|
+
return this.#_loadForm($form);
|
|
501
487
|
}
|
|
502
488
|
|
|
503
|
-
|
|
504
489
|
/**
|
|
505
490
|
* Load a file and display it in the popin
|
|
506
491
|
*
|
|
507
492
|
* @param data - All parameters available for window.fetch
|
|
508
493
|
*/
|
|
509
|
-
load(
|
|
510
|
-
|
|
494
|
+
load(
|
|
495
|
+
url: string,
|
|
496
|
+
data?: RequestInit,
|
|
497
|
+
type: FLib.Popin.ResponseType = "text",
|
|
498
|
+
): Promise<void> {
|
|
499
|
+
if (this.#loadingPromise) {
|
|
511
500
|
return this.#loadingPromise;
|
|
512
501
|
}
|
|
513
502
|
|
|
514
|
-
return this.#_load(
|
|
515
|
-
url,
|
|
516
|
-
type,
|
|
517
|
-
data
|
|
518
|
-
);
|
|
503
|
+
return this.#_load(url, type, data);
|
|
519
504
|
}
|
|
520
505
|
|
|
521
506
|
/**
|
|
@@ -523,14 +508,13 @@ export default class Popin {
|
|
|
523
508
|
*
|
|
524
509
|
* @param openFirst - Open the popin THEN insert the html
|
|
525
510
|
*/
|
|
526
|
-
set(
|
|
527
|
-
if (
|
|
528
|
-
return this.#openPopin().then(
|
|
511
|
+
set(html: string, openFirst?: boolean): Promise<void> {
|
|
512
|
+
if (openFirst) {
|
|
513
|
+
return this.#openPopin().then(() => this.#setPopin(html));
|
|
529
514
|
}
|
|
530
|
-
return this.#setPopin(
|
|
515
|
+
return this.#setPopin(html).then(() => this.#openPopin());
|
|
531
516
|
}
|
|
532
517
|
|
|
533
|
-
|
|
534
518
|
/**
|
|
535
519
|
* Remove the content of the popin
|
|
536
520
|
*/
|
|
@@ -538,7 +522,6 @@ export default class Popin {
|
|
|
538
522
|
return this.#clearPopin();
|
|
539
523
|
}
|
|
540
524
|
|
|
541
|
-
|
|
542
525
|
/**
|
|
543
526
|
* Close the popin
|
|
544
527
|
*/
|
|
@@ -546,7 +529,6 @@ export default class Popin {
|
|
|
546
529
|
return this.#closePopin();
|
|
547
530
|
}
|
|
548
531
|
|
|
549
|
-
|
|
550
532
|
/**
|
|
551
533
|
* Open the popin
|
|
552
534
|
*/
|
|
@@ -554,51 +536,40 @@ export default class Popin {
|
|
|
554
536
|
return this.#openPopin();
|
|
555
537
|
}
|
|
556
538
|
|
|
557
|
-
|
|
558
539
|
/**
|
|
559
540
|
* Open the popin loading
|
|
560
541
|
*/
|
|
561
542
|
openLoading(): Promise<void> {
|
|
562
|
-
return this.#openLoader()
|
|
543
|
+
return this.#openLoader();
|
|
563
544
|
}
|
|
564
545
|
|
|
565
546
|
/**
|
|
566
547
|
* Close the popin loading
|
|
567
548
|
*/
|
|
568
549
|
closeLoading(): Promise<void> {
|
|
569
|
-
return this.#closeLoader()
|
|
550
|
+
return this.#closeLoader();
|
|
570
551
|
}
|
|
571
552
|
|
|
572
|
-
|
|
573
553
|
/**
|
|
574
554
|
* Remove all events, css class or inline styles
|
|
575
555
|
*/
|
|
576
556
|
destroy(): void {
|
|
577
|
-
off(
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
off(
|
|
594
|
-
this.#$popin,
|
|
595
|
-
{
|
|
596
|
-
"eventsName": CLICK_EVENT_NAME,
|
|
597
|
-
"callback": this.#closePopinHandler
|
|
598
|
-
}
|
|
599
|
-
);
|
|
600
|
-
|
|
601
|
-
if ( this.#keyboardControls ) {
|
|
557
|
+
off(this.#$popin, {
|
|
558
|
+
eventsName: `${CLICK_EVENT_NAME} submit`,
|
|
559
|
+
callback: this.#openPopinHandler,
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
off(window, {
|
|
563
|
+
eventsName: "resize",
|
|
564
|
+
callback: this.#resizeHandler,
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
off(this.#$popin, {
|
|
568
|
+
eventsName: CLICK_EVENT_NAME,
|
|
569
|
+
callback: this.#closePopinHandler,
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
if (this.#keyboardControls) {
|
|
602
573
|
this.#keyboardControls.off();
|
|
603
574
|
}
|
|
604
575
|
}
|