File : dialogs/osmSearchDialog/osmSearchResults/OsmSearchResultsHTMLBuilder.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 theHTMLSanitizer from '../../../core/htmlSanitizer/HTMLSanitizer.js';
27
import theNoteDialogToolbarData from '../../notesDialog/toolbar/NoteDialogToolbarData.js';
28
import ObjId from '../../../data/ObjId.js';
29
import { ZERO } from '../../../main/Constants.js';
30
31
/* ------------------------------------------------------------------------------------------------------------------------- */
32
/**
33
HTML builder for the search results
34
*/
35
/* ------------------------------------------------------------------------------------------------------------------------- */
36
37
class OsmSearchResultsHTMLBuilder {
38
39
    /**
40
    The currently build search result HTMLElement
41
    @type {HTMLElement}
42
    */
43
44
    #searchResultsHTMLElement;
45
46
    /**
47
    Reference to the OsmElement for witch the HTMLElement is currently build
48
    @type {OsmElement}
49
    */
50
51
    #osmElement;
52
53
    /**
54
    An HTMLElement included in the search result HTMLElement with the text data
55
    @type {HTMLElement}
56
    */
57
58
    #searchResultCellHTMLElement;
59
60
    /**
61
    The max length for displayed links
62
    @type {Number}
63
    */
64
65
    // eslint-disable-next-line no-magic-numbers
66
    static get #LINKS_MAX_LENGTH ( ) { return 40; }
67
68
    /**
69
    Icon builder
70
    */
71
72
    #buildIcon ( ) {
73
        let iconContent = '';
74
        if ( this.#osmElement.tags.rcn_ref ) {
75
            iconContent =
76
                '<div class=\'TravelNotes-MapNote TravelNotes-MapNoteCategory-0073\'>' +
77
                '<svg viewBox=\'0 0 20 20\'><text class=\'\' x=10 y=14>' +
78
                this.#osmElement.tags.rcn_ref +
79
                '</text></svg></div>';
80
        }
81
        else {
82
            iconContent = theNoteDialogToolbarData.preDefinedIconDataFromName ( this.#osmElement.description ) || '';
83
        }
84
        const iconCell = theHTMLElementsFactory.create (
85
            'div',
86
            {
87
                className :    'TravelNotes-OsmSearchDialog-SearchResult-IconCell'
88
            },
89
            this.#searchResultsHTMLElement
90
        );
91
        theHTMLSanitizer.sanitizeToHtmlElement ( iconContent, iconCell );
92
    }
93
94
    /**
95
    generic builder
96
    @param {String} osmTagValue The value of the OSM tag
97
    */
98
99
    #addOsmTag ( osmTagValue ) {
100
        if ( osmTagValue ) {
101
            theHTMLElementsFactory.create ( 'div', { textContent : osmTagValue }, this.#searchResultCellHTMLElement    );
102
        }
103
    }
104
105
    /**
106
    Address builder
107
    */
108
109
    #addAddress ( ) {
110
        const street =
111
            this.#osmElement.tags [ 'addr:street' ]
112
                ?
113
                (
114
                    this.#osmElement.tags [ 'addr:housenumber' ]
115
                        ?
116
                        this.#osmElement.tags [ 'addr:housenumber' ] + ' '
117
                        :
118
                        ''
119
                ) +
120
                this.#osmElement.tags [ 'addr:street' ] + ' '
121
                :
122
                '';
123
        const city =
124
            this.#osmElement.tags [ 'addr:city' ]
125
                ?
126
                (
127
                    this.#osmElement.tags [ 'addr:postcode' ]
128
                        ?
129
                        ( this.#osmElement.tags [ 'addr:postcode' ] + ' ' )
130
                        :
131
                        ''
132
                ) +
133
                this.#osmElement.tags [ 'addr:city' ]
134
                :
135
                '';
136
        const address = street + city;
137
        if ( '' !== address ) {
138
            this.#addOsmTag ( address );
139
        }
140
    }
141
142
    /**
143
    Phone builder
144
    */
145
146
    #addPhone ( ) {
147
        if ( this.#osmElement.tags.phone ) {
148
            this.#addOsmTag ( '☎️ : ' + this.#osmElement.tags.phone, this.#searchResultCellHTMLElement );
149
        }
150
    }
151
152
    /**
153
    Mail builder
154
    */
155
156
    #addMail ( ) {
157
        if ( this.#osmElement.tags.email ) {
158
            theHTMLElementsFactory.create (
159
                'a',
160
                {
161
                    href : 'mailto:' + this.#osmElement.tags.email,
162
                    textContent : this.#osmElement.tags.email
163
                },
164
                theHTMLElementsFactory.create ( 'div', { textContent : '📧 : ' }, this.#searchResultCellHTMLElement )
165
            );
166
        }
167
    }
168
169
    /**
170
    Web site builder
171
    */
172
173
    #addWebSite ( ) {
174
        if ( this.#osmElement.tags.website ) {
175
            theHTMLElementsFactory.create (
176
                'a',
177
                {
178
                    href : this.#osmElement.tags.website,
179
                    target : '_blank',
180
                    textContent :
181
                        this.#osmElement.tags.website.length > OsmSearchResultsHTMLBuilder.#LINKS_MAX_LENGTH
182
                            ?
183
                            this.#osmElement.tags.website.substring (
184
                                ZERO,
185
                                OsmSearchResultsHTMLBuilder.#LINKS_MAX_LENGTH
186
                            ) + '...'
187
                            :
188
                            this.#osmElement.tags.website
189
                },
190
                theHTMLElementsFactory.create ( 'div', null, this.#searchResultCellHTMLElement )
191
            );
192
        }
193
    }
194
195
    /**
196
    Add all osm data
197
    */
198
199
    #addOsmData ( ) {
200
        this.#searchResultCellHTMLElement = theHTMLElementsFactory.create (
201
            'div',
202
            { className :    'TravelNotes-OsmSearchDialog-SearchResult-Cell'    },
203
            this.#searchResultsHTMLElement
204
        );
205
        this.#addOsmTag ( this.#osmElement.description );
206
        this.#addOsmTag ( this.#osmElement.tags.name );
207
        this.#addOsmTag ( this.#osmElement.tags.rcn_ref );
208
        this.#addAddress ( );
209
        this.#addPhone ( );
210
        this.#addMail ( );
211
        this.#addWebSite ( );
212
    }
213
214
    /**
215
    Title builder
216
    */
217
218
    #addTitle ( ) {
219
        for ( const [ KEY, VALUE ] of Object.entries ( this.#osmElement.tags ) ) {
220
            this.#searchResultsHTMLElement.title += KEY + '=' + VALUE + '\n';
221
        }
222
    }
223
224
    /**
225
    The constructor
226
    */
227
228
    constructor ( ) {
229
        Object.freeze ( this );
230
    }
231
232
    /**
233
    Build a search result htmlElement from the data in an osmElement
234
    @param {OsmElement} osmElement the osmelement with to needed data
235
    @param {Number} index The position of the osmElement in the array of osmElements
236
    */
237
238
    buildHTMLElement ( osmElement, index ) {
239
        this.#osmElement = osmElement;
240
        this.#searchResultsHTMLElement = theHTMLElementsFactory.create (
241
            'div',
242
            {
243
                className :    'TravelNotes-OsmSearchDialog-SearchResultHTMLElement',
244
                dataset : { ObjId : ObjId.nextObjId, ElementIndex : index }
245
            }
246
        );
247
        this.#buildIcon ( );
248
        this.#addOsmData ( );
249
        this.#addTitle ( );
250
        return this.#searchResultsHTMLElement;
251
    }
252
}
253
254
export default OsmSearchResultsHTMLBuilder;
255