opening_hours 3.10.0 → 3.11.0
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 +70 -0
- package/Makefile +7 -2
- package/README.md +14 -18
- package/build/opening_hours.esm.mjs +14896 -19393
- package/build/opening_hours.esm.mjs.map +1 -1
- package/build/opening_hours.js +14900 -19396
- package/package.json +2 -4
- package/site/js/countryToLanguageMapping.js +2 -3
- package/site/js/helpers.js +474 -313
- package/site/js/i18n-resources.js +554 -70
- package/site/js/main.js +379 -0
- package/site/js/opening_hours_table.js +233 -74
- package/site/js/theme.js +70 -0
- package/site/js/yohours_model.js +17 -15
- package/src/locales/i18n.js +62 -0
- package/src/locales/core.js +0 -20
package/site/js/helpers.js
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
// Import dependencies
|
|
2
|
+
import i18next from '../../node_modules/i18next/dist/esm/i18next.bundled.js';
|
|
3
|
+
import { OpeningHoursTable } from './opening_hours_table.js';
|
|
4
|
+
import { mapCountryToLanguage } from './countryToLanguageMapping.js';
|
|
5
|
+
import { updateTimeButtonLabels } from './main.js';
|
|
6
|
+
import { YoHoursChecker } from './yohours_model.js';
|
|
7
|
+
|
|
8
|
+
// Access global variables set by main.js or UMD scripts
|
|
9
|
+
const { opening_hours, default_lat, default_lon } = window;
|
|
10
|
+
|
|
11
|
+
// Export date/time state
|
|
12
|
+
export let currentDateTime = {
|
|
13
|
+
year: 2013,
|
|
14
|
+
month: 0, // January (0-indexed)
|
|
15
|
+
day: 2,
|
|
16
|
+
hour: 22,
|
|
17
|
+
minute: 21
|
|
18
|
+
};
|
|
2
19
|
|
|
3
20
|
/* Constants {{{ */
|
|
4
21
|
const nominatim_api_url = 'https://nominatim.openstreetmap.org/reverse';
|
|
@@ -9,27 +26,28 @@ const evaluation_tool_colors = {
|
|
|
9
26
|
'warn': '#FFA500',
|
|
10
27
|
'error': '#DEB887',
|
|
11
28
|
};
|
|
29
|
+
|
|
30
|
+
const OSM_MAX_VALUE_LENGTH = 255;
|
|
12
31
|
/* }}} */
|
|
13
32
|
|
|
14
33
|
// load nominatim_data in JOSM {{{
|
|
15
|
-
// Using a different way to load stuff in JOSM than https://github.com/
|
|
34
|
+
// Using a different way to load stuff in JOSM than https://github.com/vibrog/OpenLinkMap/
|
|
16
35
|
// prevent josm remote plugin of showing message
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
export function josm(url_param) {
|
|
37
|
+
fetch(`http://localhost:8111/${url_param}`)
|
|
38
|
+
.then(response => {
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
alert(i18next.t('texts.JOSM remote conn error'));
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
.catch(() => {
|
|
24
44
|
alert(i18next.t('texts.JOSM remote conn error'));
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
xhr.send(null);
|
|
45
|
+
});
|
|
28
46
|
}
|
|
29
47
|
// }}}
|
|
30
48
|
|
|
31
49
|
// add calculation for calendar week to date {{{
|
|
32
|
-
function dateAtWeek(date, week) {
|
|
50
|
+
export function dateAtWeek(date, week) {
|
|
33
51
|
const minutes_in_day = 60 * 24;
|
|
34
52
|
const msec_in_day = 1000 * 60 * minutes_in_day;
|
|
35
53
|
const msec_in_week = msec_in_day * 7;
|
|
@@ -40,63 +58,55 @@ function dateAtWeek(date, week) {
|
|
|
40
58
|
}
|
|
41
59
|
// }}}
|
|
42
60
|
|
|
43
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Reverse geocode coordinates to get localized place names from Nominatim.
|
|
63
|
+
*
|
|
44
64
|
* The names of countries and states are localized in OSM and opening_hours.js
|
|
45
65
|
* (holidays) so we need to get the localized names from Nominatim as well.
|
|
66
|
+
*
|
|
67
|
+
* @param {number} lat - Latitude
|
|
68
|
+
* @param {number} lon - Longitude
|
|
69
|
+
* @param {string} preferredLanguage - Preferred language code (e.g., 'de', 'en')
|
|
70
|
+
* @returns {Promise<Object>} Nominatim response with address data
|
|
46
71
|
*/
|
|
47
|
-
function reverseGeocodeLocation(
|
|
48
|
-
|
|
49
|
-
|
|
72
|
+
async function reverseGeocodeLocation(lat, lon, preferredLanguage) {
|
|
73
|
+
// Cached response for default coordinates to avoid queries on initial load
|
|
74
|
+
if (lat === 48.7769 && lon === 9.1844) {
|
|
75
|
+
return { place_id: '159221147', licence: 'Data © OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright', osm_type: 'relation', osm_id: '62611', lat: '48.6296972', lon: '9.1949534', display_name: 'Baden-Württemberg, Deutschland', address: { state: 'Baden-Württemberg', country: 'Deutschland', country_code: 'de' }, boundingbox: ['47.5324787', '49.7912941', '7.5117461', '10.4955731'] };
|
|
50
76
|
}
|
|
51
77
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
78
|
+
const params = new URLSearchParams({
|
|
79
|
+
format: 'json',
|
|
80
|
+
lat: String(lat),
|
|
81
|
+
lon: String(lon),
|
|
82
|
+
zoom: '5',
|
|
83
|
+
addressdetails: '1',
|
|
84
|
+
email: 'ypid23@aol.de',
|
|
85
|
+
'accept-language': preferredLanguage
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
async function fetchNominatim() {
|
|
89
|
+
const response = await fetch(`${nominatim_api_url}?${params}`);
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
throw new Error(`Nominatim request failed: ${response.status}`);
|
|
92
|
+
}
|
|
93
|
+
return response.json();
|
|
55
94
|
}
|
|
56
95
|
|
|
57
|
-
|
|
58
|
-
+ '?format=json'
|
|
59
|
-
+ query
|
|
60
|
-
+ '&zoom=5'
|
|
61
|
-
+ '&addressdetails=1'
|
|
62
|
-
+ '&email=ypid23@aol.de';
|
|
96
|
+
let data = await fetchNominatim();
|
|
63
97
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
98
|
+
// Refetch with localized language if country differs from preferred language
|
|
99
|
+
const countryCode = data.address?.country_code;
|
|
100
|
+
if (countryCode && countryCode !== preferredLanguage) {
|
|
101
|
+
params.set('accept-language', mapCountryToLanguage(countryCode));
|
|
102
|
+
data = await fetchNominatim();
|
|
67
103
|
}
|
|
68
104
|
|
|
69
|
-
|
|
70
|
-
// console.log(JSON.stringify(nominatim_data, null, '\t'));
|
|
71
|
-
if (nominatim_data.address.country_code === guessed_language_for_location) {
|
|
72
|
-
on_success(nominatim_data);
|
|
73
|
-
} else {
|
|
74
|
-
nominatim_api_url_query += '&accept-language=' + mapCountryToLanguage(nominatim_data.address.country_code);
|
|
75
|
-
$.getJSON(nominatim_api_url_query, function(nominatim_data) {
|
|
76
|
-
on_success(nominatim_data);
|
|
77
|
-
}).error(on_error);
|
|
78
|
-
}
|
|
79
|
-
}).error(on_error);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// eslint-disable-next-line no-unused-vars
|
|
83
|
-
function submitenter(myfield,e) {
|
|
84
|
-
Evaluate();
|
|
85
|
-
// let keycode;
|
|
86
|
-
// if (window.event) keycode = window.event.keyCode;
|
|
87
|
-
// else if (e) keycode = e.which;
|
|
88
|
-
// else return true;
|
|
89
|
-
|
|
90
|
-
// if (keycode === 13) {
|
|
91
|
-
// Evaluate();
|
|
92
|
-
// return false;
|
|
93
|
-
// } else
|
|
94
|
-
// return true;
|
|
105
|
+
return data;
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
/* JS for toggling examples on and off {{{ */
|
|
98
|
-
|
|
99
|
-
function toggle(control){
|
|
109
|
+
export function toggle(control){
|
|
100
110
|
const elem = document.getElementById(control);
|
|
101
111
|
|
|
102
112
|
if (elem.style.display === 'none') {
|
|
@@ -107,19 +117,296 @@ function toggle(control){
|
|
|
107
117
|
}
|
|
108
118
|
/* }}} */
|
|
109
119
|
|
|
110
|
-
|
|
111
|
-
function copyToClipboard(text) {
|
|
120
|
+
export function copyToClipboard(text) {
|
|
112
121
|
window.prompt('Copy to clipboard: Ctrl+C, Enter', text);
|
|
113
122
|
}
|
|
114
123
|
|
|
124
|
+
// Internal state for geocoding and date
|
|
115
125
|
let lat, lon, string_lat, string_lon, nominatim;
|
|
116
126
|
let date;
|
|
117
127
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
128
|
+
/* Helper functions for Evaluate {{{ */
|
|
129
|
+
|
|
130
|
+
function getFragmentIdentifier(selectorType) {
|
|
131
|
+
switch(selectorType) {
|
|
132
|
+
case '24/7':
|
|
133
|
+
return 'selector_sequence';
|
|
134
|
+
case 'state':
|
|
135
|
+
return 'section:rule_modifier';
|
|
136
|
+
case 'comment':
|
|
137
|
+
return 'comment';
|
|
138
|
+
default:
|
|
139
|
+
return `selector:${selectorType}`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function generateRuleSeparatorHTML(ruleSeparator) {
|
|
144
|
+
return `<span title="${i18next.t('texts.rule separator ' + ruleSeparator)}" class="rule_separator">` +
|
|
145
|
+
`<a target="_blank" class="specification" href="${window.specification_url}#section:rule_separators">${ruleSeparator}</a></span><br>`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function generateSelectorHTML(selectorType, selectorValue) {
|
|
149
|
+
const fragmentIdentifier = getFragmentIdentifier(selectorType);
|
|
150
|
+
const translationKey = selectorType.match(/(?:state|comment)/) ? 'modifier' : 'selector';
|
|
151
|
+
|
|
152
|
+
return `<span title="${i18next.t(`words.${translationKey}`, { name: selectorType })}" class="${selectorType}">` +
|
|
153
|
+
`<a target="_blank" class="specification" href="${window.specification_url}#${fragmentIdentifier}">${selectorValue}</a></span>`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Generate HTML explanation for prettified opening hours value.
|
|
158
|
+
*
|
|
159
|
+
* Converts the internal rule structure into human-readable HTML with links
|
|
160
|
+
* to the specification for each selector type and rule separator.
|
|
161
|
+
*
|
|
162
|
+
* @param {Array} prettifiedValueArray - Array containing [rules, ruleSeparators]
|
|
163
|
+
* @returns {string} HTML string with formatted value explanation
|
|
164
|
+
*/
|
|
165
|
+
function generateValueExplanation(prettifiedValueArray) {
|
|
166
|
+
const [rules, ruleSeparators] = prettifiedValueArray;
|
|
167
|
+
const parts = [
|
|
168
|
+
`${i18next.t('texts.prettified value for displaying')}:<br />`,
|
|
169
|
+
'<p class="value_explanation">'
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
for (const [ruleIndex, selectors] of rules.entries()) {
|
|
173
|
+
if (ruleIndex !== 0) {
|
|
174
|
+
const separatorData = ruleSeparators[ruleIndex];
|
|
175
|
+
const ruleSeparator = separatorData[1]
|
|
176
|
+
? ' ||'
|
|
177
|
+
: (separatorData[0][0][1] === 'rule separator' ? ',' : ';');
|
|
178
|
+
|
|
179
|
+
parts.push(generateRuleSeparatorHTML(ruleSeparator));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
parts.push('<span class="one_rule">');
|
|
183
|
+
|
|
184
|
+
for (const [selectorIndex, selector] of selectors.entries()) {
|
|
185
|
+
const [typeArray, selectorValue] = selector;
|
|
186
|
+
const selectorType = typeArray[2];
|
|
187
|
+
|
|
188
|
+
parts.push(generateSelectorHTML(selectorType, selectorValue));
|
|
189
|
+
|
|
190
|
+
const isLastSelector = selectorIndex === selectors.length - 1;
|
|
191
|
+
if (!isLastSelector) {
|
|
192
|
+
parts.push(' ');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
parts.push('</span>');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
parts.push('</p></div>');
|
|
200
|
+
return parts.join('');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function generateResultsHTML() {
|
|
204
|
+
return `
|
|
205
|
+
<div class="matching-rule-card">
|
|
206
|
+
<div class="status-label">${i18next.t('texts.MatchingRule')}</div>
|
|
207
|
+
<div class="matching-rule-value" id="matching-rule-display"></div>
|
|
208
|
+
</div>
|
|
209
|
+
`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Generate HTML display for deviation information between two opening hours values.
|
|
214
|
+
*
|
|
215
|
+
* @param {Object} oh1 - The first opening_hours instance
|
|
216
|
+
* @param {Object} oh2 - The second opening_hours instance
|
|
217
|
+
* @param {Object} deviationInfo - Deviation data from isEqualTo comparison
|
|
218
|
+
* @returns {string} HTML string with formatted deviation information
|
|
219
|
+
*/
|
|
220
|
+
function generateDeviationHTML(oh1, oh2, deviationInfo) {
|
|
221
|
+
const parts = ['<div class="diff-deviation">'];
|
|
222
|
+
|
|
223
|
+
// Show which rules are matching
|
|
224
|
+
if (typeof deviationInfo.matching_rule !== 'undefined' || typeof deviationInfo.matching_rule_other !== 'undefined') {
|
|
225
|
+
parts.push('<div class="diff-rules">');
|
|
226
|
+
parts.push(`<strong>${i18next.t('texts.Affected rules')}:</strong> `);
|
|
227
|
+
if (typeof deviationInfo.matching_rule !== 'undefined') {
|
|
228
|
+
parts.push(`${i18next.t('texts.Original')}: ${i18next.t('texts.Rule')} ${deviationInfo.matching_rule + 1}`);
|
|
229
|
+
}
|
|
230
|
+
if (typeof deviationInfo.matching_rule_other !== 'undefined') {
|
|
231
|
+
parts.push(` / ${i18next.t('texts.Comparison')}: ${i18next.t('texts.Rule')} ${deviationInfo.matching_rule_other + 1}`);
|
|
232
|
+
}
|
|
233
|
+
parts.push('</div>');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Show time-based deviations with actual values
|
|
237
|
+
if (deviationInfo.deviation_for_time && typeof deviationInfo.deviation_for_time === 'object') {
|
|
238
|
+
for (const [timeCode, deviations] of Object.entries(deviationInfo.deviation_for_time)) {
|
|
239
|
+
const deviationDate = new Date(parseInt(timeCode));
|
|
240
|
+
const timeString = deviationDate.toLocaleString(i18next.language, {
|
|
241
|
+
year: 'numeric',
|
|
242
|
+
month: '2-digit',
|
|
243
|
+
day: '2-digit',
|
|
244
|
+
hour: '2-digit',
|
|
245
|
+
minute: '2-digit',
|
|
246
|
+
hour12: false
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Build readable comparison lines
|
|
250
|
+
const line1Parts = [];
|
|
251
|
+
const line2Parts = [];
|
|
252
|
+
|
|
253
|
+
if (deviations.includes('getState') || deviations.includes('getDate')) {
|
|
254
|
+
const state1 = oh1.getState(deviationDate);
|
|
255
|
+
const state2 = oh2.getState(deviationDate);
|
|
256
|
+
const unknown1 = oh1.getUnknown(deviationDate);
|
|
257
|
+
const unknown2 = oh2.getUnknown(deviationDate);
|
|
258
|
+
|
|
259
|
+
const stateText1 = unknown1 ? i18next.t('words.unknown') : i18next.t(`words.${state1 ? 'open' : 'closed'}`);
|
|
260
|
+
const stateText2 = unknown2 ? i18next.t('words.unknown') : i18next.t(`words.${state2 ? 'open' : 'closed'}`);
|
|
261
|
+
|
|
262
|
+
line1Parts.push(stateText1);
|
|
263
|
+
line2Parts.push(stateText2);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (deviations.includes('getComment')) {
|
|
267
|
+
const comment1 = oh1.getComment(deviationDate);
|
|
268
|
+
const comment2 = oh2.getComment(deviationDate);
|
|
269
|
+
|
|
270
|
+
if (comment1) line1Parts.push(`"${comment1}"`);
|
|
271
|
+
if (comment2) line2Parts.push(`"${comment2}"`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const comparisonHTML = `
|
|
275
|
+
<div class="diff-times">
|
|
276
|
+
<strong>${i18next.t('texts.Deviation at')} ${timeString}</strong><br>
|
|
277
|
+
${i18next.t('texts.Original')}: ${line1Parts.join(', ')}<br>
|
|
278
|
+
${i18next.t('texts.Comparison')}: ${line2Parts.join(', ')}
|
|
279
|
+
</div>
|
|
280
|
+
`;
|
|
281
|
+
|
|
282
|
+
parts.push(comparisonHTML);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Show raw JSON for developers
|
|
287
|
+
const deviationJson = JSON.stringify(deviationInfo);
|
|
288
|
+
parts.push(`<div class="diff-raw"><code>${deviationJson}</code></div>`);
|
|
289
|
+
|
|
290
|
+
parts.push('</div>');
|
|
291
|
+
return parts.join('');
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Compare opening hours value with a diff value and update UI accordingly.
|
|
296
|
+
*
|
|
297
|
+
* Compares the current opening hours object with another value and sets
|
|
298
|
+
* the background color of the diff input field to indicate the result:
|
|
299
|
+
* - Green (ok): Values are equivalent
|
|
300
|
+
* - Orange (warn): Values differ, shows deviation details in #compare-result
|
|
301
|
+
* - Brown (error): Diff value failed to parse
|
|
302
|
+
*
|
|
303
|
+
* @param {Object} oh - The opening_hours instance to compare
|
|
304
|
+
* @param {string} diffValue - The opening hours value to compare against
|
|
305
|
+
* @param {number} mode - The parsing mode for opening hours
|
|
306
|
+
* @param {Date} startDate - The date to start comparison from
|
|
307
|
+
*/
|
|
308
|
+
function handleDiffComparison(oh, diffValue, mode, startDate) {
|
|
309
|
+
const diffValueElement = document.getElementById('diff_value');
|
|
310
|
+
const compareResult = document.getElementById('compare-result');
|
|
311
|
+
|
|
312
|
+
if (diffValue.length === 0) {
|
|
313
|
+
diffValueElement.style.backgroundColor = '';
|
|
314
|
+
compareResult.innerHTML = '';
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
let comparisonOh;
|
|
319
|
+
let comparisonResult;
|
|
320
|
+
try {
|
|
321
|
+
comparisonOh = new opening_hours(diffValue, nominatim, {
|
|
322
|
+
'mode': mode,
|
|
323
|
+
'warnings_severity': 7,
|
|
324
|
+
'locale': i18next.language
|
|
325
|
+
});
|
|
326
|
+
comparisonResult = oh.isEqualTo(comparisonOh, startDate);
|
|
327
|
+
} catch {
|
|
328
|
+
diffValueElement.style.backgroundColor = evaluation_tool_colors.error;
|
|
329
|
+
compareResult.innerHTML = '';
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (!Array.isArray(comparisonResult)) {
|
|
334
|
+
compareResult.innerHTML = '';
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const [isEqual, deviationInfo] = comparisonResult;
|
|
339
|
+
|
|
340
|
+
if (isEqual) {
|
|
341
|
+
diffValueElement.style.backgroundColor = evaluation_tool_colors.ok;
|
|
342
|
+
compareResult.innerHTML = '';
|
|
343
|
+
} else {
|
|
344
|
+
diffValueElement.style.backgroundColor = evaluation_tool_colors.warn;
|
|
345
|
+
compareResult.innerHTML = generateDeviationHTML(oh, comparisonOh, deviationInfo);
|
|
121
346
|
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function generateJosmHTML(value) {
|
|
350
|
+
const josmUrl = 'import?url=' + encodeURIComponent(
|
|
351
|
+
`https://overpass-api.de/api/xapi_meta?*[opening_hours=${value}]`
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
return `<div class="action-description">${i18next.t('texts.load osm objects')}</div>` +
|
|
355
|
+
`<div><a href="#" class="josm-link" data-url="${josmUrl}">JOSM</a></div>`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function generateYoHoursHTML(value, crashed) {
|
|
359
|
+
const yoHoursChecker = new YoHoursChecker();
|
|
360
|
+
if (!crashed && yoHoursChecker.canRead(value)) {
|
|
361
|
+
const yohoursUrl = `https://projets.pavie.info/yohours/?oh=${value}`;
|
|
362
|
+
return `<div class="action-description">${i18next.t('texts.yohours description')}</div>` +
|
|
363
|
+
`<div><a href="${yohoursUrl}" target="_blank">YoHours</a></div>`;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return `<div class="action-description">${i18next.t('texts.yohours description')}</div>` +
|
|
367
|
+
`<div class="yohours-warning">${i18next.t('texts.yohours incompatible')}</div>`;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function generatePrettifiedValueHTML(prettified) {
|
|
371
|
+
const escapedValue = prettified.replace(/"/g, '"');
|
|
372
|
+
|
|
373
|
+
// Build translation with placeholder for the link
|
|
374
|
+
const translatedText = i18next.t('texts.prettified value', { copyFunc: '__COPY_LINK__' });
|
|
375
|
+
const linkHtml = `<a href="#" class="copy-prettified-value" data-value="${escapedValue}">`;
|
|
376
|
+
const finalText = translatedText.replace('<a href="__COPY_LINK__">', linkHtml);
|
|
377
|
+
|
|
378
|
+
const copyTooltip = i18next.t('texts.copy');
|
|
379
|
+
|
|
380
|
+
return `<div class="prettified-value-section">
|
|
381
|
+
<p>${finalText}:</p>
|
|
382
|
+
<div class="prettified-value-container">
|
|
383
|
+
<code class="prettified-value-display" data-value="${escapedValue}">${prettified}</code>
|
|
384
|
+
<button type="button" class="copy-btn copy-prettified-btn" data-value="${escapedValue}" title="${copyTooltip}">📋</button>
|
|
385
|
+
</div>
|
|
386
|
+
</div>`;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function generateWarningsHTML(warnings) {
|
|
390
|
+
if (warnings.length === 0) return '';
|
|
391
|
+
|
|
392
|
+
return `<div class="warning">${i18next.t('texts.filter.error')}` +
|
|
393
|
+
`<div class="warning_error_message">${warnings.join('\n')}</div></div>`;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function generateValueTooLongHTML(prettified, value) {
|
|
397
|
+
if (prettified.length <= OSM_MAX_VALUE_LENGTH) return '';
|
|
398
|
+
|
|
399
|
+
return `<div class="warning">${i18next.t('texts.filter.error')}` +
|
|
400
|
+
`<div class="warning_error_message">${i18next.t('texts.value to long for osm', {
|
|
401
|
+
pretLength: prettified.length,
|
|
402
|
+
valLength: value.length,
|
|
403
|
+
maxLength: OSM_MAX_VALUE_LENGTH
|
|
404
|
+
})}</div></div>`;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* }}} */
|
|
122
408
|
|
|
409
|
+
export async function Evaluate (offset = 0, reset) {
|
|
123
410
|
if (document.forms.check.elements['lat'].value !== string_lat || document.forms.check.elements['lon'].value !== string_lon) {
|
|
124
411
|
string_lat = document.forms.check.elements['lat'].value;
|
|
125
412
|
string_lon = document.forms.check.elements['lon'].value;
|
|
@@ -135,59 +422,67 @@ function Evaluate (offset, reset) {
|
|
|
135
422
|
console.log('Please enter numbers for latitude and longitude.');
|
|
136
423
|
return;
|
|
137
424
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
425
|
+
try {
|
|
426
|
+
nominatim = await reverseGeocodeLocation(
|
|
427
|
+
lat,
|
|
428
|
+
lon,
|
|
429
|
+
mapCountryToLanguage(i18next.language)
|
|
430
|
+
);
|
|
431
|
+
document.forms.check.elements['cc'].value = nominatim.address.country_code;
|
|
432
|
+
document.forms.check.elements['state'].value = nominatim.address.state;
|
|
433
|
+
Evaluate();
|
|
434
|
+
} catch (error) {
|
|
435
|
+
/* Set fallback Nominatim answer to allow using the evaluation tool even without Nominatim. */
|
|
436
|
+
console.error('Reverse geocoding failed:', error);
|
|
437
|
+
alert('Reverse geocoding of the coordinates using Nominatim was not successful. The evaluation of features of the opening_hours specification which depend this information will be unreliable. Otherwise, this tool will work as expected using a fallback answer. You might want to check your browser settings to fix this.');
|
|
438
|
+
nominatim = {'place_id':'44651229','licence':'Data \u00a9 OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright','osm_type':'way','osm_id':'36248375','lat':'49.5400039','lon':'9.7937133','display_name':'K 2847, Lauda-K\u00f6nigshofen, Main-Tauber-Kreis, Regierungsbezirk Stuttgart, Baden-W\u00fcrttemberg, Germany, European Union','address':{'road':'K 2847','city':'Lauda-K\u00f6nigshofen','county':'Main-Tauber-Kreis','state_district':'Regierungsbezirk Stuttgart','state':'Baden-W\u00fcrttemberg','country':'Germany','country_code':'de','continent':'European Union'}};
|
|
439
|
+
document.forms.check.elements['cc'].value = nominatim.address.country_code;
|
|
440
|
+
document.forms.check.elements['state'].value = nominatim.address.state;
|
|
441
|
+
Evaluate();
|
|
442
|
+
}
|
|
443
|
+
return;
|
|
156
444
|
}
|
|
157
445
|
|
|
158
446
|
date = reset
|
|
159
447
|
? new Date()
|
|
160
448
|
: new Date(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
449
|
+
currentDateTime.year,
|
|
450
|
+
currentDateTime.month,
|
|
451
|
+
currentDateTime.day,
|
|
452
|
+
currentDateTime.hour,
|
|
453
|
+
currentDateTime.minute,
|
|
166
454
|
offset
|
|
167
455
|
);
|
|
168
456
|
|
|
169
|
-
|
|
457
|
+
// Update module state
|
|
458
|
+
currentDateTime = {
|
|
459
|
+
year: date.getFullYear(),
|
|
460
|
+
month: date.getMonth(),
|
|
461
|
+
day: date.getDate(),
|
|
462
|
+
hour: date.getHours(),
|
|
463
|
+
minute: date.getMinutes()
|
|
464
|
+
};
|
|
170
465
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
document.forms.check.elements['dd'].value = u2(date.getDate());
|
|
174
|
-
document.forms.check.elements['HH'].value = u2(date.getHours());
|
|
175
|
-
document.forms.check.elements['MM'].value = u2(date.getMinutes());
|
|
176
|
-
document.forms.check.elements['wday'].value = date.toLocaleString(i18next.language, {weekday: 'short'});
|
|
177
|
-
document.forms.check.elements['week'].value = 'W'+u2(dateAtWeek(date, 0) + 1);
|
|
466
|
+
// Update time button labels with current values
|
|
467
|
+
updateTimeButtonLabels(date);
|
|
178
468
|
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
const
|
|
469
|
+
// Cache DOM elements
|
|
470
|
+
const showTimeTable = document.getElementById('show_time_table');
|
|
471
|
+
const showWarningsOrErrors = document.getElementById('show_warnings_or_errors');
|
|
472
|
+
const showResults = document.getElementById('show_results');
|
|
473
|
+
const actionJosm = document.getElementById('action-josm');
|
|
474
|
+
const actionYoHours = document.getElementById('action-yohours');
|
|
182
475
|
|
|
183
|
-
|
|
476
|
+
showWarningsOrErrors.innerHTML = '';
|
|
184
477
|
|
|
478
|
+
// Parse opening hours value
|
|
185
479
|
let crashed = false;
|
|
186
480
|
const value = document.forms.check.elements['expression'].value;
|
|
187
|
-
const
|
|
481
|
+
const diffValue = document.forms.check.elements['diff_value'].value;
|
|
188
482
|
const mode = parseInt(document.getElementById('mode').selectedIndex);
|
|
189
483
|
let oh;
|
|
190
484
|
let it;
|
|
485
|
+
|
|
191
486
|
try {
|
|
192
487
|
oh = new opening_hours(value, nominatim, {
|
|
193
488
|
'mode': mode,
|
|
@@ -197,204 +492,96 @@ function Evaluate (offset, reset) {
|
|
|
197
492
|
it = oh.getIterator(date);
|
|
198
493
|
} catch (err) {
|
|
199
494
|
crashed = err;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
show_results.innerHTML = '';
|
|
495
|
+
showWarningsOrErrors.innerHTML =
|
|
496
|
+
`<div class="error">${i18next.t('texts.filter.error')}` +
|
|
497
|
+
`<div class="warning_error_message">${crashed}</div></div>`;
|
|
498
|
+
showTimeTable.innerHTML = '';
|
|
499
|
+
showResults.innerHTML = '';
|
|
206
500
|
}
|
|
207
501
|
|
|
208
|
-
|
|
209
|
-
|
|
502
|
+
// Populate action links
|
|
503
|
+
actionJosm.innerHTML = generateJosmHTML(value);
|
|
504
|
+
actionYoHours.innerHTML = generateYoHoursHTML(value, crashed);
|
|
505
|
+
|
|
210
506
|
if (!crashed) {
|
|
211
507
|
const prettified = oh.prettifyValue({});
|
|
212
|
-
const
|
|
213
|
-
// conf: { locale: i18next.language },
|
|
508
|
+
const prettifiedValueArray = oh.prettifyValue({
|
|
214
509
|
get_internals: true,
|
|
215
510
|
});
|
|
216
|
-
// let prettified_newline_sep = oh.prettifyValue({ conf: { locale: i18next.language, rule_sep_string: '\n', print_semicolon: false } });
|
|
217
|
-
show_results.innerHTML = '<p><span class="hd">' + i18next.t('words.status') + ':</span>'
|
|
218
|
-
+ '<input class="nostyle" size="10" name="status" readonly="readonly" />'
|
|
219
|
-
+ '<input class="nostyle" size="60" name="comment" readonly="readonly" />'
|
|
220
|
-
+ '</p>' + '<p><span class="hd">'
|
|
221
|
-
+ i18next.t('texts.MatchingRule') + ':</span>'
|
|
222
|
-
+ '<input class="nostyle w100" name="MatchingRule" readonly="readonly" />'
|
|
223
|
-
+ '</p>';
|
|
224
|
-
const used_selectors = { };
|
|
225
|
-
let value_explanation =
|
|
226
|
-
i18next.t('texts.prettified value for displaying') + ':<br />'
|
|
227
|
-
+ '<p class="value_explanation">';
|
|
228
|
-
// console.log(JSON.stringify(prettified_value_array, null, ' '));
|
|
229
|
-
// console.log(JSON.stringify(prettified_value_array, null, ' '));
|
|
230
|
-
for (let nrule = 0; nrule < prettified_value_array[0].length; nrule++) {
|
|
231
|
-
if (nrule !== 0) {
|
|
232
|
-
const rule_separator = (
|
|
233
|
-
prettified_value_array[1][nrule][1]
|
|
234
|
-
? ' ||'
|
|
235
|
-
: (
|
|
236
|
-
prettified_value_array[1][nrule][0][0][1] === 'rule separator'
|
|
237
|
-
? ','
|
|
238
|
-
: ';'
|
|
239
|
-
)
|
|
240
|
-
);
|
|
241
|
-
value_explanation +=
|
|
242
|
-
'<span title="'
|
|
243
|
-
+ i18next.t('texts.rule separator ' + rule_separator) + '"'
|
|
244
|
-
+ ' class="rule_separator"><a target="_blank" class="specification" href="'
|
|
245
|
-
+ specification_url + '#section:rule_separators'
|
|
246
|
-
+ '">' + rule_separator + '</a></span><br>';
|
|
247
|
-
}
|
|
248
|
-
value_explanation += '<span class="one_rule">';
|
|
249
|
-
for (let nselector = 0, sl = prettified_value_array[0][nrule].length; nselector < sl; nselector++) {
|
|
250
|
-
const selector_type = prettified_value_array[0][nrule][nselector][0][2];
|
|
251
|
-
const selector_value = prettified_value_array[0][nrule][nselector][1];
|
|
252
|
-
let fragment_identifier;
|
|
253
|
-
switch(selector_type) {
|
|
254
|
-
case '24/7':
|
|
255
|
-
fragment_identifier = 'selector_sequence';
|
|
256
|
-
break;
|
|
257
|
-
case 'state':
|
|
258
|
-
fragment_identifier = 'section:rule_modifier';
|
|
259
|
-
break;
|
|
260
|
-
case 'comment':
|
|
261
|
-
fragment_identifier = 'comment';
|
|
262
|
-
break;
|
|
263
|
-
default:
|
|
264
|
-
fragment_identifier = 'selector:' + selector_type;
|
|
265
|
-
}
|
|
266
|
-
value_explanation += '<span title="'
|
|
267
|
-
+ i18next.t('words.' + (selector_type.match(/(?:state|comment)/) ? 'modifier' : 'selector'), { name: selector_type }) + '"'
|
|
268
|
-
+ ' class="' + selector_type + '"><a target="_blank" class="specification" href="'
|
|
269
|
-
+ specification_url + '#' + fragment_identifier
|
|
270
|
-
+ '">' + selector_value + '</a></span>';
|
|
271
|
-
if (nselector + 1 < sl)
|
|
272
|
-
value_explanation += ' ';
|
|
273
|
-
used_selectors[selector_type] = true;
|
|
274
|
-
}
|
|
275
|
-
// console.log(value_explanation);
|
|
276
|
-
value_explanation += '</span>';
|
|
277
|
-
}
|
|
278
|
-
value_explanation += '</p></div>';
|
|
279
|
-
if (YoHoursChecker.canRead(value)) {
|
|
280
|
-
value_explanation = i18next.t('texts.refer to yohours', { href: 'https://projets.pavie.info/yohours/?oh=' + value })
|
|
281
|
-
+ '<br>'
|
|
282
|
-
+ value_explanation;
|
|
283
|
-
}
|
|
284
511
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
try {
|
|
288
|
-
is_equal_to = oh.isEqualTo(new opening_hours(diff_value, nominatim, {
|
|
289
|
-
'mode': mode,
|
|
290
|
-
'warnings_severity': 7,
|
|
291
|
-
'locale': i18next.language
|
|
292
|
-
}));
|
|
293
|
-
} catch {
|
|
294
|
-
$('input#diff_value').css({'background-color' : evaluation_tool_colors.error})
|
|
295
|
-
}
|
|
296
|
-
if (typeof is_equal_to === 'object') {
|
|
297
|
-
if (is_equal_to[0]) {
|
|
298
|
-
$('input#diff_value').css({'background-color' : evaluation_tool_colors.ok})
|
|
299
|
-
} else {
|
|
300
|
-
$('input#diff_value').css({'background-color' : evaluation_tool_colors.warn})
|
|
301
|
-
const human_readable_not_equal_output = jQuery.extend(true, {}, is_equal_to[1])
|
|
302
|
-
if (typeof human_readable_not_equal_output.deviation_for_time === 'object') {
|
|
303
|
-
human_readable_not_equal_output.deviation_for_time = {};
|
|
304
|
-
for (const time_code in is_equal_to[1].deviation_for_time) {
|
|
305
|
-
console.log(time_code);
|
|
306
|
-
const time_string = new Date(parseInt(time_code)).toLocaleString();
|
|
307
|
-
human_readable_not_equal_output.deviation_for_time[time_string] =
|
|
308
|
-
is_equal_to[1].deviation_for_time[time_code];
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
value_explanation = JSON.stringify(human_readable_not_equal_output, null, ' ')
|
|
312
|
-
+ '<br>'
|
|
313
|
-
+ value_explanation;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
512
|
+
// Generate and display results
|
|
513
|
+
showResults.innerHTML = generateResultsHTML();
|
|
317
514
|
|
|
318
|
-
|
|
515
|
+
// Generate value explanation
|
|
516
|
+
const valueExplanation = generateValueExplanation(prettifiedValueArray);
|
|
319
517
|
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
// + '<textarea rows="' + prettified_newline_sep.split('\n').length
|
|
323
|
-
// + '" style="width: 100%" name="prettifiedValueNewlineSep" readonly="readonly">'
|
|
324
|
-
// + prettified_newline_sep + '</textarea></p>';
|
|
518
|
+
// Handle diff comparison
|
|
519
|
+
handleDiffComparison(oh, diffValue, mode, date);
|
|
325
520
|
|
|
521
|
+
// Display value explanation
|
|
522
|
+
showWarningsOrErrors.innerHTML = valueExplanation;
|
|
326
523
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
? i18next.t('words.none') : oh.prettifyValue({ 'rule_index': rule_index });
|
|
524
|
+
// Update matching rule
|
|
525
|
+
const ruleIndex = it.getMatchingRule();
|
|
526
|
+
const ruleDisplay = document.getElementById('matching-rule-display');
|
|
527
|
+
if (ruleDisplay) {
|
|
528
|
+
ruleDisplay.textContent = typeof ruleIndex === 'undefined' ? i18next.t('words.none') : oh.prettifyValue({ 'rule_index': ruleIndex });
|
|
529
|
+
}
|
|
334
530
|
|
|
531
|
+
// Show prettified value if different from input
|
|
335
532
|
if (prettified !== value) {
|
|
336
|
-
|
|
337
|
-
{ copyFunc: 'javascript:newValue(\'' + prettified.replace(/"/g, '"') + '\')' }) + ':<br />'
|
|
338
|
-
+ '<input style="width: 100%" onclick="javascript:newValue(\'' + prettified.replace(/"/g, '"') + '\')" id="prettifiedValue" name="prettifiedValue" value="' + prettified.replace(/"/g, '"') + '" /></p>';
|
|
533
|
+
showWarningsOrErrors.innerHTML = generatePrettifiedValueHTML(prettified);
|
|
339
534
|
}
|
|
340
535
|
|
|
536
|
+
// Append warnings if any
|
|
341
537
|
const warnings = oh.getWarnings();
|
|
342
|
-
|
|
343
|
-
show_warnings_or_errors.innerHTML += `
|
|
344
|
-
<div class="warning"> ${i18next.t('texts.filter.error')}
|
|
345
|
-
<div class="warning_error_message"> ${warnings.join('\n')} </div>
|
|
346
|
-
</div>`;
|
|
347
|
-
}
|
|
538
|
+
showWarningsOrErrors.innerHTML += generateWarningsHTML(warnings);
|
|
348
539
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
<div class="warning"> ${i18next.t('texts.filter.error')}
|
|
352
|
-
<div class="warning_error_message"> ${i18next.t('texts.value to long for osm',
|
|
353
|
-
{ pretLength: prettified.length, valLength: value.length, maxLength: 255 })} </div>
|
|
354
|
-
</div>`;
|
|
355
|
-
}
|
|
540
|
+
// Check value length
|
|
541
|
+
showWarningsOrErrors.innerHTML += generateValueTooLongHTML(prettified, value);
|
|
356
542
|
|
|
357
|
-
|
|
543
|
+
// Generate time table
|
|
544
|
+
showTimeTable.innerHTML = OpeningHoursTable.drawTableAndComments(oh, it, date);
|
|
358
545
|
}
|
|
546
|
+
|
|
547
|
+
updatePermalinkHref();
|
|
359
548
|
}
|
|
360
549
|
|
|
361
|
-
|
|
362
|
-
function EX (element) {
|
|
550
|
+
export function EX (element) {
|
|
363
551
|
newValue(element.innerHTML);
|
|
364
552
|
return false;
|
|
365
553
|
}
|
|
366
554
|
|
|
367
|
-
function newValue(value) {
|
|
368
|
-
if (typeof document.forms.check.elements['prettifiedValue'] === 'object') {
|
|
369
|
-
document.forms.check.elements['prettifiedValue'].focus();
|
|
370
|
-
document.forms.check.elements['prettifiedValue'].focus();
|
|
371
|
-
}
|
|
555
|
+
export function newValue(value) {
|
|
372
556
|
document.forms.check.elements['expression'].value = value;
|
|
373
557
|
Evaluate();
|
|
374
558
|
}
|
|
375
559
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
560
|
+
function updatePermalinkHref() {
|
|
561
|
+
const params = new URLSearchParams({
|
|
562
|
+
EXP: document.getElementById('expression').value,
|
|
563
|
+
lat: document.getElementById('lat').value,
|
|
564
|
+
lon: document.getElementById('lon').value,
|
|
565
|
+
mode: document.getElementById('mode').selectedIndex
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
const diffValue = document.getElementById('diff_value').value;
|
|
569
|
+
if (diffValue !== '') {
|
|
570
|
+
params.set('diff_value', diffValue);
|
|
571
|
+
}
|
|
383
572
|
|
|
384
|
-
|
|
573
|
+
const baseUrl = `${location.origin}${location.pathname}`;
|
|
385
574
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
permalink_url_query += '&diff_value='+encodeURIComponent(diff_value);
|
|
391
|
-
}
|
|
575
|
+
// Permalink with timestamp
|
|
576
|
+
const paramsWithTimestamp = new URLSearchParams(params);
|
|
577
|
+
paramsWithTimestamp.set('DATE', date.getTime());
|
|
578
|
+
document.getElementById('permalink-link-with-timestamp').href = `${baseUrl}?${paramsWithTimestamp}`;
|
|
392
579
|
|
|
393
|
-
|
|
580
|
+
// Permalink without timestamp
|
|
581
|
+
document.getElementById('permalink-link-without-timestamp').href = `${baseUrl}?${params}`;
|
|
394
582
|
}
|
|
395
583
|
|
|
396
|
-
|
|
397
|
-
function setCurrentPosition() {
|
|
584
|
+
export function setCurrentPosition() {
|
|
398
585
|
if(navigator.geolocation) {
|
|
399
586
|
navigator.geolocation.getCurrentPosition(onPositionUpdate);
|
|
400
587
|
}
|
|
@@ -408,72 +595,46 @@ function onPositionUpdate(position) {
|
|
|
408
595
|
Evaluate();
|
|
409
596
|
console.log('Current position: ' + lat + ' ' + lng);
|
|
410
597
|
}
|
|
598
|
+
|
|
411
599
|
window.onload = function () {
|
|
412
|
-
const
|
|
413
|
-
const
|
|
414
|
-
let customCoords = false;
|
|
600
|
+
const params = new URLSearchParams(location.search);
|
|
601
|
+
const customCoords = params.has('lat') || params.has('lon');
|
|
415
602
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
params[tmparr[0]] = tmparr[1];
|
|
419
|
-
}
|
|
420
|
-
if (typeof params['EXP'] !== 'undefined') {
|
|
421
|
-
document.forms.check.elements['expression'].value = decodeURIComponent(params['EXP']);
|
|
603
|
+
if (params.has('EXP')) {
|
|
604
|
+
document.forms.check.elements['expression'].value = params.get('EXP');
|
|
422
605
|
}
|
|
423
|
-
if (
|
|
424
|
-
document.forms.check.elements['diff_value'].value =
|
|
606
|
+
if (params.has('diff_value')) {
|
|
607
|
+
document.forms.check.elements['diff_value'].value = params.get('diff_value');
|
|
425
608
|
}
|
|
426
|
-
if (
|
|
427
|
-
document.forms.check.elements['lat'].value =
|
|
428
|
-
customCoords = true;
|
|
609
|
+
if (params.has('lat')) {
|
|
610
|
+
document.forms.check.elements['lat'].value = params.get('lat');
|
|
429
611
|
}
|
|
430
|
-
if (
|
|
431
|
-
document.forms.check.elements['lon'].value =
|
|
432
|
-
customCoords = true;
|
|
612
|
+
if (params.has('lon')) {
|
|
613
|
+
document.forms.check.elements['lon'].value = params.get('lon');
|
|
433
614
|
}
|
|
434
|
-
if (
|
|
435
|
-
document.forms.check.elements['mode'].value =
|
|
615
|
+
if (params.has('mode')) {
|
|
616
|
+
document.forms.check.elements['mode'].value = params.get('mode');
|
|
436
617
|
}
|
|
437
|
-
if (
|
|
438
|
-
let crashed = true;
|
|
618
|
+
if (params.has('DATE')) {
|
|
439
619
|
try {
|
|
440
|
-
|
|
441
|
-
|
|
620
|
+
const loadedDate = new Date(parseInt(params.get('DATE')));
|
|
621
|
+
currentDateTime = {
|
|
622
|
+
year: loadedDate.getFullYear(),
|
|
623
|
+
month: loadedDate.getMonth(),
|
|
624
|
+
day: loadedDate.getDate(),
|
|
625
|
+
hour: loadedDate.getHours(),
|
|
626
|
+
minute: loadedDate.getMinutes()
|
|
627
|
+
};
|
|
628
|
+
Evaluate(0, false);
|
|
442
629
|
} catch (err) {
|
|
443
630
|
console.error(err);
|
|
631
|
+
Evaluate(0, true);
|
|
444
632
|
}
|
|
445
|
-
if (!crashed) {
|
|
446
|
-
document.forms.check.elements['yyyy'].value = date.getFullYear();
|
|
447
|
-
document.forms.check.elements['mm'].selectedIndex = date.getMonth();
|
|
448
|
-
document.forms.check.elements['dd'].value = date.getDate();
|
|
449
|
-
document.forms.check.elements['HH'].value = date.getHours();
|
|
450
|
-
document.forms.check.elements['MM'].value = date.getMinutes();
|
|
451
|
-
}
|
|
452
|
-
Evaluate(0, false);
|
|
453
633
|
} else {
|
|
454
634
|
Evaluate(0, true);
|
|
455
635
|
}
|
|
456
636
|
if (navigator.geolocation && !customCoords) {
|
|
457
637
|
navigator.geolocation.getCurrentPosition(onPositionUpdate);
|
|
458
|
-
}
|
|
638
|
+
}
|
|
459
639
|
};
|
|
460
640
|
/* }}} */
|
|
461
|
-
|
|
462
|
-
$(document).ready(function () {
|
|
463
|
-
const permalink = document.getElementById('permalink');
|
|
464
|
-
if (permalink) {
|
|
465
|
-
const checkbox = document.createElement('input');
|
|
466
|
-
checkbox.type = 'checkbox';
|
|
467
|
-
checkbox.name = 'name';
|
|
468
|
-
checkbox.value = 'value';
|
|
469
|
-
checkbox.id = 'permalink-include-timestamp';
|
|
470
|
-
checkbox.checked = true;
|
|
471
|
-
|
|
472
|
-
const label = document.createElement('label')
|
|
473
|
-
label.htmlFor = 'permalink-include-timestamp';
|
|
474
|
-
label.appendChild(document.createTextNode(i18next.t('texts.include timestamp?')));
|
|
475
|
-
|
|
476
|
-
permalink.appendChild(label);
|
|
477
|
-
permalink.appendChild(checkbox);
|
|
478
|
-
}
|
|
479
|
-
});
|