File : dialogs/baseDialog/BaseDialog.js

1
/*
2
Copyright - 2017 2023 - wwwouaiebe - Contact: https://www.ouaie.be/
3
4
This  program is free software;
5
you can redistribute it and/or modify it under the terms of the
6
GNU General Public License as published by the Free Software Foundation;
7
either version 3 of the License, or any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
*/
18
/*
19
Changes:
20
    - v4.0.0:
21
        - created from v3.6.0
22
Doc reviewed 202208
23
 */
24
25
import theHTMLElementsFactory from '../../core/uiLib/HTMLElementsFactory.js';
26
import theTranslator from '../../core/uiLib/Translator.js';
27
import BaseDialogOptions from './BaseDialogOptions.js';
28
import CancelButtonClickEL from './CancelButtonClickEL.js';
29
import TopBarDragStartEL from './TopBarDragStartEL.js';
30
import TopBarDragEndEL from './TopBarDragEndEL.js';
31
import TopBarTouchEL from './TopBarTouchEL.js';
32
import BaseDialogMover from './BaseDialogMover.js';
33
34
// import GarbageCollectorTester from '../core/uiLib/GarbageCollectorTester.js';
35
36
/* ------------------------------------------------------------------------------------------------------------------------- */
37
/**
38
Base class used for dialogs
39
*/
40
/* ------------------------------------------------------------------------------------------------------------------------- */
41
42
class BaseDialog {
43
44
    /*
45
    Garbage collector testing. Only for memory free tests on dev.
46
    */
47
48
    // #garbageCollectorTester = new GarbageCollectorTester ( );
49
50
    /**
51
    The container HTMLElement of the dialog
52
    @type {HTMLElement}
53
    */
54
55
    #dialogHTMLElement;
56
57
    /**
58
    The topbar HTMLElement
59
    @type {HTMLElement}
60
    */
61
62
    #topBarHTMLElement;
63
64
    /**
65
    The cancel button on the top bar
66
    @type {HTMLElement}
67
    */
68
69
    #cancelButton;
70
71
    /**
72
    The content HTMLElement
73
    @type {HTMLElement}
74
    */
75
76
    #contentHTMLElement;
77
78
    /**
79
    BaseDialogMover for drag ond drop and touch operations
80
    @type {BaseDialogMover}
81
    */
82
83
    #baseDialogMover;
84
85
    /**
86
    Top bar drag start event listener
87
    @type {TopBarDragStartEL}
88
    */
89
90
    #topBarDragStartEL;
91
92
    /**
93
    Top bar drag end event listener
94
    @type {TopBarDragEndEL}
95
    */
96
97
    #topBarDragEndEL;
98
99
    /**
100
    Top bar touch event listener
101
    @type {TopBarTouchEL}
102
    */
103
104
    #topBarTouchEL;
105
106
    /**
107
    Cancel button click event listener
108
    @type {CancelButtonClickEL}
109
    */
110
111
    #cancelButtonClickEL;
112
113
    /**
114
    options parameter
115
    @type {?Object}
116
    */
117
118
    #options = null;
119
120
    /**
121
    Create the dialog container
122
    */
123
124
    #createDialogHTMLElement ( ) {
125
126
        // the dialog is created
127
        this.#dialogHTMLElement = theHTMLElementsFactory.create (
128
            'div',
129
            {
130
                className : 'TravelNotes-BaseDialog-DialogHTMLElement'
131
            }
132
        );
133
        this.mover.dialogHTMLElement = this.#dialogHTMLElement;
134
    }
135
136
    /**
137
    Create the top bar
138
    */
139
140
    #createTopBarHTMLElement ( ) {
141
142
        this.#topBarHTMLElement = theHTMLElementsFactory.create (
143
            'div',
144
            {
145
                className : 'TravelNotes-BaseDialog-TopBarHTMLElement',
146
                draggable : true
147
            },
148
            this.#dialogHTMLElement
149
        );
150
151
        this.#topBarTouchEL = new TopBarTouchEL ( this.mover );
152
        this.#topBarHTMLElement.addEventListener ( 'touchstart', this.#topBarTouchEL, false );
153
        this.#topBarHTMLElement.addEventListener ( 'touchmove', this.#topBarTouchEL, false );
154
        this.#topBarHTMLElement.addEventListener ( 'touchend', this.#topBarTouchEL, false );
155
        this.#topBarHTMLElement.addEventListener ( 'touchcancel', this.#topBarTouchEL, false );
156
        this.#topBarDragStartEL = new TopBarDragStartEL ( this.mover );
157
        this.#topBarHTMLElement.addEventListener ( 'dragstart', this.#topBarDragStartEL, false );
158
        this.#topBarDragEndEL = new TopBarDragEndEL ( this.mover );
159
        this.#topBarHTMLElement.addEventListener ( 'dragend', this.#topBarDragEndEL, false );
160
161
        this.#cancelButton = theHTMLElementsFactory.create (
162
            'div',
163
            {
164
                textContent : '❌',
165
                className : 'TravelNotes-BaseDialog-CancelButton',
166
                title : theTranslator.getText ( 'BaseDialog - Cancel' )
167
            },
168
            this.#topBarHTMLElement
169
        );
170
        theHTMLElementsFactory.create (
171
            'div',
172
            {
173
                textContent : this.title,
174
                className : 'TravelNotes-BaseDialog-Title'
175
            },
176
            this.#topBarHTMLElement
177
        );
178
        this.#cancelButtonClickEL = new CancelButtonClickEL ( this );
179
        this.#cancelButton.addEventListener ( 'click', this.#cancelButtonClickEL, false );
180
        this.mover.topBarHTMLElement = this.#topBarHTMLElement;
181
    }
182
183
    /**
184
    Create the toolbar HTMLElement
185
    */
186
187
    #createToolbarHTMLElement ( ) {
188
        if ( this.toolbarHTMLElement ) {
189
            theHTMLElementsFactory.create (
190
                'div',
191
                {
192
                    className : 'TravelNotes-BaseDialog-ToolbarHTMLElement'
193
                },
194
                this.#dialogHTMLElement
195
            ).appendChild ( this.toolbarHTMLElement );
196
        }
197
    }
198
199
    /**
200
    Create the content HTMLElement
201
    */
202
203
    #createContentHTMLElement ( ) {
204
        this.#contentHTMLElement = theHTMLElementsFactory.create (
205
            'div',
206
            {
207
                className : 'TravelNotes-BaseDialog-ContentHTMLElement'
208
            },
209
            this.#dialogHTMLElement
210
        );
211
212
        this.contentHTMLElements.forEach (
213
            contentHTMLElement => this.#contentHTMLElement.appendChild ( contentHTMLElement )
214
        );
215
    }
216
217
    /**
218
    Create the HTML dialog
219
    */
220
221
    #createHTML ( ) {
222
        this.#createDialogHTMLElement ( );
223
        this.#createTopBarHTMLElement ( );
224
        this.#createToolbarHTMLElement ( );
225
        this.#createContentHTMLElement ( );
226
    }
227
228
    /**
229
    The constructor
230
    @param {BaseDialogOptions} options the options for the dialog
231
    */
232
233
    constructor ( options ) {
234
        Object.freeze ( this );
235
        this.#options = new BaseDialogOptions ( options );
236
    }
237
238
    /**
239
    Remove all events listeners and events dispatchers so all references to the dialog are released and
240
    finally remove all the htmlElements from the document
241
    */
242
243
    #destructor ( ) {
244
        this.#topBarHTMLElement.removeEventListener ( 'dragstart', this.#topBarDragStartEL, false );
245
        this.#topBarDragStartEL = null;
246
        this.#topBarHTMLElement.removeEventListener ( 'dragend', this.#topBarDragEndEL, false );
247
        this.#topBarDragEndEL = null;
248
249
        this.#topBarHTMLElement.removeEventListener ( 'touchstart', this.#topBarTouchEL, false );
250
        this.#topBarHTMLElement.removeEventListener ( 'touchmove', this.#topBarTouchEL, false );
251
        this.#topBarHTMLElement.removeEventListener ( 'touchend', this.#topBarTouchEL, false );
252
        this.#topBarHTMLElement.removeEventListener ( 'touchcancel', this.#topBarTouchEL, false );
253
        this.#topBarTouchEL = null;
254
255
        this.#cancelButton.removeEventListener ( 'click', this.#cancelButtonClickEL, false );
256
        this.#cancelButtonClickEL = null;
257
258
        if ( this.#baseDialogMover ) {
259
            this.#baseDialogMover = null;
260
        }
261
    }
262
263
    /**
264
    Get the mover object used with this dialog. Create the object if needed.
265
    Can be overloaded in the derived classes
266
    @type {BaseDialogMover}
267
    */
268
269
    get mover ( ) { return this.#baseDialogMover ? this.#baseDialogMover : this.#baseDialogMover = new BaseDialogMover ( ); }
270
271
    /**
272
    Cancel button handler. Can be overloaded in the derived classes
273
    */
274
275
    onCancel ( ) {
276
        this.#destructor ( );
277
    }
278
279
    /**
280
    Ok button handler. Can be overloaded in the derived classes
281
    */
282
283
    onOk ( ) {
284
        this.#destructor ( );
285
    }
286
287
    /**
288
    The title of the dialog. Can be overloaded in the derived classes
289
    @type {String}
290
    */
291
292
    get title ( ) { return ''; }
293
294
    /**
295
    An HTMLElement that have to be added as toolbar for the dialog.
296
    Can be overloaded in the derived classes
297
    @type {?HTMLElement}
298
    */
299
300
    get toolbarHTMLElement ( ) { return null; }
301
302
    /**
303
    An array with the HTMLElements that have to be added in the content of the dialog.
304
    Can be overloaded in the derived classes
305
    @type {Array.<HTMLElement>}
306
    */
307
308
    get contentHTMLElements ( ) { return []; }
309
310
    /**
311
    Show the dialog
312
    */
313
314
    show ( ) {
315
        this.createContentHTML ( );
316
        this.#createHTML ( );
317
    }
318
319
    /**
320
    Remove the container from the background
321
    @param {HTMLElement} backgroundElement the used background. The background can be the background created
322
    by the modal dialogs or the document.body for non modal dialogs
323
    */
324
325
    removeFromBackground ( backgroundElement ) {
326
        backgroundElement.removeChild ( this.#dialogHTMLElement );
327
    }
328
329
    /**
330
    Add the container to the background.
331
    @param {HTMLElement} backgroundElement the used background. The background can be the background created
332
    by the modal dialogs or the document.body for non modal dialogs
333
    */
334
335
    addToBackground ( backgroundElement ) {
336
        backgroundElement.appendChild ( this.#dialogHTMLElement );
337
    }
338
339
    /**
340
    Add an element to the container
341
    @param {HTMLElement} htmlElement The element to add
342
    */
343
344
    addToDialog ( htmlElement ) {
345
        this.#dialogHTMLElement.appendChild ( htmlElement );
346
    }
347
348
    /**
349
    The options of the dialog box
350
    @type {BaseDialogOptions}
351
    */
352
353
    get options ( ) { return this.#options; }
354
355
    /**
356
    Add a css class to the #dialogHTMLElement, so some css settings can be overloaded for a specific dialog
357
    @param {String} cssClass The css class to add
358
    */
359
360
    addCssClass ( cssClass ) {
361
        this.#dialogHTMLElement.classList.add ( cssClass );
362
    }
363
364
}
365
366
export default BaseDialog;
367
368
/* --- End of file --------------------------------------------------------------------------------------------------------- */
369