j1-template 2024.2.0 → 2024.2.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/assets/data/gemini-ui.html +2 -2
  3. data/assets/themes/j1/adapter/js/advertising.js +2 -10
  4. data/assets/themes/j1/adapter/js/analytics.js +1 -5
  5. data/assets/themes/j1/adapter/js/bmd.js +195 -195
  6. data/assets/themes/j1/adapter/js/carousel.js +786 -786
  7. data/assets/themes/j1/adapter/js/clipboard.js +1 -0
  8. data/assets/themes/j1/adapter/js/comments.js +1 -0
  9. data/assets/themes/j1/adapter/js/cookieConsent.js +460 -466
  10. data/assets/themes/j1/adapter/js/customModule.js +5 -4
  11. data/assets/themes/j1/adapter/js/docsearch.js +1 -0
  12. data/assets/themes/j1/adapter/js/dropdowns.js +1 -0
  13. data/assets/themes/j1/adapter/js/fab.js +1 -0
  14. data/assets/themes/j1/adapter/js/gallery.js +495 -494
  15. data/assets/themes/j1/adapter/js/gemini.js +154 -128
  16. data/assets/themes/j1/adapter/js/iconPicker.js +257 -255
  17. data/assets/themes/j1/adapter/js/iconPickerPage.js +279 -279
  18. data/assets/themes/j1/adapter/js/iframer.js +3 -2
  19. data/assets/themes/j1/adapter/js/j1.js +3285 -3285
  20. data/assets/themes/j1/adapter/js/lazyLoader.js +241 -241
  21. data/assets/themes/j1/adapter/js/lightbox.js +242 -241
  22. data/assets/themes/j1/adapter/js/logger.js +1 -0
  23. data/assets/themes/j1/adapter/js/lunr.js +6 -10
  24. data/assets/themes/j1/adapter/js/masonry.js +427 -426
  25. data/assets/themes/j1/adapter/js/masterslider.js +526 -526
  26. data/assets/themes/j1/adapter/js/mmenu.js +1 -0
  27. data/assets/themes/j1/adapter/js/navigator.js +2 -2
  28. data/assets/themes/j1/adapter/js/particles.js +1 -0
  29. data/assets/themes/j1/adapter/js/rangeSlider.js +1 -0
  30. data/assets/themes/j1/adapter/js/rouge.js +288 -287
  31. data/assets/themes/j1/adapter/js/rtable.js +309 -309
  32. data/assets/themes/j1/adapter/js/slick.js +487 -487
  33. data/assets/themes/j1/adapter/js/slimSelect.js +3 -5
  34. data/assets/themes/j1/adapter/js/themeToggler.js +281 -280
  35. data/assets/themes/j1/adapter/js/themes.js +0 -1
  36. data/assets/themes/j1/adapter/js/toccer.js +1 -0
  37. data/assets/themes/j1/adapter/js/translator.js +1 -0
  38. data/assets/themes/j1/adapter/js/waves.js +1 -0
  39. data/assets/themes/j1/modules/cookieConsent/js/cookieConsent.js +23 -17
  40. data/assets/themes/j1/modules/js-cookies/js/js.cookie.js +147 -0
  41. data/assets/themes/j1/modules/js-cookies/js/js.cookie.min.js +2 -0
  42. data/lib/j1/version.rb +1 -1
  43. data/lib/starter_web/README.md +5 -5
  44. data/lib/starter_web/_config.yml +1 -1
  45. data/lib/starter_web/_data/modules/defaults/themes.yml +171 -171
  46. data/lib/starter_web/_data/resources.yml +26 -0
  47. data/lib/starter_web/_data/templates/feed.xml +1 -1
  48. data/lib/starter_web/_plugins/index/lunr.rb +1 -1
  49. data/lib/starter_web/package.json +1 -1
  50. data/lib/starter_web/pages/public/learn/roundtrip/present_images.adoc +500 -500
  51. metadata +4 -2
@@ -1,466 +1,460 @@
1
- ---
2
- regenerate: true
3
- ---
4
-
5
- {% capture cache %}
6
-
7
- {% comment %}
8
- # -----------------------------------------------------------------------------
9
- # ~/assets/themes/j1/adapter/js/cookieConsent.js
10
- # Liquid template to create the Template Adapter for J1 CookieConsent
11
- #
12
- # Product/Info:
13
- # http://jekyll.one
14
- #
15
- # Copyright (C) 2023, 2024 Juergen Adams
16
- #
17
- # J1 Template is licensed under the MIT License.
18
- # For details, see: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE.md
19
- # -----------------------------------------------------------------------------
20
- # Test data:
21
- # {{ liquid_var | debug }}
22
- # cookie_options: {{ cookie_options | debug }}
23
- # -----------------------------------------------------------------------------
24
- {% endcomment %}
25
-
26
- {% comment %} Liquid var initialization
27
- -------------------------------------------------------------------------------- {% endcomment %}
28
-
29
- {% comment %} Set config files
30
- -------------------------------------------------------------------------------- {% endcomment %}
31
- {% assign environment = site.environment %}
32
- {% assign blocks = site.data.blocks %}
33
- {% assign modules = site.data.modules %}
34
- {% assign template_config = site.data.j1_config %}
35
-
36
- {% comment %} Set config data
37
- -------------------------------------------------------------------------------- {% endcomment %}
38
- {% assign cookie_defaults = modules.defaults.cookies.defaults %}
39
- {% assign cookie_settings = modules.cookies.settings %}
40
- {% assign consent_defaults = modules.defaults.cookieconsent.defaults %}
41
- {% assign consent_settings = modules.cookieconsent.settings %}
42
- {% assign analytics_defaults = modules.defaults.analytics.defaults %}
43
- {% assign analytics_settings = modules.analytics.settings %}
44
-
45
- {% comment %} Set config options
46
- -------------------------------------------------------------------------------- {% endcomment %}
47
- {% assign consent_options = consent_defaults | merge: consent_settings %}
48
- {% assign cookie_options = cookie_defaults | merge: cookie_settings %}
49
- {% assign analytics_options = analytics_defaults | merge: analytics_settings %}
50
-
51
- {% comment %} Set variables
52
- -------------------------------------------------------------------------------- {% endcomment %}
53
- {% assign tracking_enabled = analytics_options.enabled %}
54
- {% assign tracking_id = analytics_options.google.trackingID %}
55
-
56
- {% comment %} Detect prod mode
57
- -------------------------------------------------------------------------------- {% endcomment %}
58
- {% assign production = false %}
59
- {% if environment == 'prod' or environment == 'production' %}
60
- {% assign production = true %}
61
- {% endif %}
62
-
63
- /*
64
- # -----------------------------------------------------------------------------
65
- # ~/assets/themes/j1/adapter/js/cookieConsent.js
66
- # JS Adapter for J1 CookieConsent
67
- #
68
- # Product/Info:
69
- # http://jekyll.one
70
- #
71
- # Copyright (C) 2023, 2024 Juergen Adams
72
- #
73
- # J1 Theme is licensed under MIT License.
74
- # See: https://github.com/jekyll-one/J1 Theme/blob/master/LICENSE
75
- # -----------------------------------------------------------------------------
76
- # Adapter generated: {{site.time}}
77
- # -----------------------------------------------------------------------------
78
- */
79
-
80
- // -----------------------------------------------------------------------------
81
- // ESLint shimming
82
- // -----------------------------------------------------------------------------
83
- /* eslint indent: "off" */
84
- /* eslint quotes: "off" */
85
- // -----------------------------------------------------------------------------
86
- 'use strict';
87
- j1.adapter.cookieConsent = ((j1, window) => {
88
- var environment = '{{environment}}';
89
- var tracking_enabled = ('{{tracking_enabled}}' === 'true') ? true: false;
90
- var tracking_id = '{{tracking_id}}';
91
- var tracking_id_valid = (tracking_id.includes('tracking-id')) ? false : true;
92
- var stringifiedAttributes = '';
93
- var state = 'not_started';
94
-
95
- var expireCookiesOnRequiredOnly;
96
-
97
- var cookieDefaults;
98
- var cookieSettings;
99
- var cookieOptions;
100
-
101
- var cookieConsentDefaults;
102
- var cookieConsentSettings;
103
- var cookieConsentOptions;
104
-
105
- var $modal;
106
- var cookie_names;
107
- var user_cookie;
108
- var url;
109
- var baseUrl;
110
- var hostname;
111
- var auto_domain;
112
- var check_cookie_option_domain;
113
- var cookie_domain;
114
- var secure;
115
- var cookie_written;
116
- var contentLanguage;
117
- var navigatorLanguage;
118
- var domainAttribute;
119
-
120
- var logger;
121
- var logText;
122
- var _this;
123
-
124
- // date|time
125
- var startTime;
126
- var endTime;
127
- var startTimeModule;
128
- var endTimeModule;
129
- var timeSeconds;
130
-
131
- // ---------------------------------------------------------------------------
132
- // helper functions
133
- // ---------------------------------------------------------------------------
134
- // NOTE: RegEx for tracking_id: ^(G|UA|YT|MO)-[a-zA-Z0-9-]+$
135
- // See: https://stackoverflow.com/questions/20411767/how-to-validate-google-analytics-tracking-id-using-a-javascript-function/20412153
136
-
137
- // ---------------------------------------------------------------------------
138
- // main
139
- // ---------------------------------------------------------------------------
140
- return {
141
-
142
- // -------------------------------------------------------------------------
143
- // adapter initializer
144
- // -------------------------------------------------------------------------
145
- init: (options) => {
146
-
147
- // -----------------------------------------------------------------------
148
- // default module settings
149
- // -----------------------------------------------------------------------
150
- var settings = $.extend({
151
- module_name: 'j1.adapter.cookieConsent',
152
- generated: '{{site.time}}'
153
- }, options);
154
-
155
- // -----------------------------------------------------------------------
156
- // global variable settings
157
- // -----------------------------------------------------------------------
158
- _this = j1.adapter.cookieConsent;
159
- logger = log4javascript.getLogger('j1.adapter.cookieConsent');
160
- cookie_names = j1.getCookieNames();
161
- url = new liteURL(window.location.href);
162
- baseUrl = url.origin;
163
- hostname = url.hostname;
164
- auto_domain = hostname.substring(hostname.lastIndexOf('.', hostname.lastIndexOf('.') - 1) + 1);
165
- secure = (url.protocol.includes('https')) ? true : false;
166
- contentLanguage = '{{site.language}}';
167
- navigatorLanguage = navigator.language || navigator.userLanguage;
168
-
169
- // Load cookie DEFAULTS|CONFIG
170
- cookieDefaults = $.extend({}, {{cookie_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
171
- cookieSettings = $.extend({}, {{cookie_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
172
- cookieOptions = $.extend(true, {}, cookieDefaults, cookieSettings);
173
-
174
- // Load module DEFAULTS|CONFIG
175
- cookieConsentDefaults = $.extend({}, {{consent_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
176
- cookieConsentSettings = $.extend({}, {{consent_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
177
- cookieConsentOptions = $.extend(true, {}, cookieConsentDefaults, cookieConsentSettings);
178
-
179
- if (navigatorLanguage.indexOf("-") !== -1) {
180
- navigatorLanguage = navigatorLanguage.split("-")[0];
181
- }
182
-
183
- if (cookieConsentOptions.dialogLanguage === 'auto') {
184
- cookieConsentOptions.dialogLanguage = navigatorLanguage;
185
- } else if (cookieConsentOptions.dialogLanguage === 'content') {
186
- cookieConsentOptions.dialogLanguage = contentLanguage;
187
- } else {
188
- cookieConsentOptions.dialogLanguage = navigatorLanguage;
189
- }
190
-
191
- check_cookie_option_domain = (cookieOptions.domain === 'false') ? false : true;
192
- expireCookiesOnRequiredOnly = (cookieOptions.expireCookiesOnRequiredOnly === 'true') ? true: false;
193
-
194
- // -----------------------------------------------------------------------
195
- // module initializer
196
- // -----------------------------------------------------------------------
197
- var dependencies_met_page_ready = setInterval((options) => {
198
- var pageState = $('#content').css("display");
199
- var pageVisible = (pageState === 'block') ? true : false;
200
- var j1CoreFinished = (j1.getState() === 'finished') ? true : false;
201
-
202
- if (j1CoreFinished) {
203
- var same_site = cookieOptions.same_site;
204
- var expires;
205
-
206
- startTimeModule = Date.now();
207
-
208
- _this.setState('started');
209
- logger.debug('\n' + 'set module state to: ' + _this.getState());
210
- logger.info('\n' + 'initializing module: started');
211
-
212
- if (cookieConsentOptions.enabled) {
213
- expires = cookieOptions.expires;
214
- } else {
215
- // expire permanent cookies to session
216
- j1.expireCookie({ name: cookie_names.user_state });
217
- j1.expireCookie({ name: cookie_names.user_consent });
218
- j1.expireCookie({ name: cookie_names.user_translate });
219
-
220
- // disable the themes menus
221
- $('#themes_menu').css('display', 'none');
222
- $('#themes_mmenu').css('display', 'none');
223
- logger.warn('\n' + 'disable module: Themes');
224
-
225
- // disable the quick link for (Google) Translation
226
- $('#quickLinksTranslateButton').css('display', 'none');
227
- logger.warn('\n' + 'disable module: Trranslator');
228
- }
229
-
230
- // set domain used by cookies
231
- if (check_cookie_option_domain) {
232
- if (cookieOptions.domain === 'auto') {
233
- domainAttribute = auto_domain;
234
- stringifiedAttributes += '; ' + 'Domain=' + domainAttribute;
235
- } else {
236
- domainAttribute = cookieOptions.domain;
237
- stringifiedAttributes += '; ' + 'Domain=' + domainAttribute;
238
- }
239
- } else {
240
- domainAttribute = cookieOptions.domain;
241
- }
242
-
243
- // failsafe: if 'None' is given for samesite in non-secure
244
- // environments open access to cookies to subdomains
245
- // ---------------------------------------------------------------------
246
- if (same_site === 'None' && !secure) {
247
- same_site = 'Lax';
248
- }
249
-
250
- // -------------------------------------------------------------------
251
- // NOTE: Click events moved to Navigator (core)
252
- // -------------------------------------------------------------------
253
-
254
- if (cookieConsentOptions.enabled) {
255
- logger.info('\n' + 'initialize core module');
256
-
257
- j1.cookieConsent = new CookieConsent ({
258
- contentURL: cookieConsentOptions.contentURL, // dialog content (modals) for all supported languages
259
- cookieName: cookie_names.user_consent, // name of the consent cookie
260
- cookieStorageDays: expires, // lifetime of a cookie [0..365], 0: session cookie
261
- cookieSameSite: same_site, // restrict consent cookie
262
- cookieSecure: secure, // only sent to the server with an encrypted request over HTTPS
263
- cookieDomain: domainAttribute, // set domain (hostname|domain)
264
- dialogLanguage: cookieConsentOptions.dialogLanguage, // language for the dialog (modal)
265
- whitelisted: cookieConsentOptions.whitelisted, // pages NO cookie dialog is shown
266
- reloadPageOnChange: cookieConsentOptions.reloadPageOnChange, // reload if setzings has changed
267
- dialogContainerID: cookieConsentOptions.dialogContainerID, // container, the dialog modal is (dynamically) loaded
268
- xhrDataElement: cookieConsentOptions.xhrDataElement, // container for all language-specific dialogs (modals)
269
- postSelectionCallback: cookieConsentOptions.postSelectionCallback, // callback function, called after the user has made his selection
270
- });
271
- } else {
272
- logger.warn('\n' + 'module is disabled');
273
- } // END if cookieConsentOptions enabled
274
-
275
- _this.setState('finished');
276
- logger.debug('\n' + 'state: ' + _this.getState());
277
- logger.info('\n' + 'module initialized successfully');
278
-
279
- endTimeModule = Date.now();
280
- logger.info('\n' + 'module initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
281
-
282
- clearInterval(dependencies_met_page_ready);
283
- } // END j1CoreFinished
284
- }, 10); // END dependencies_met_page_ready
285
- }, // END init
286
-
287
- // -------------------------------------------------------------------------
288
- // cbCookie()
289
- // callback for CookieConsent module after the user has
290
- // made his selection
291
- // -------------------------------------------------------------------------
292
- cbCookie: () => {
293
- var url = new liteURL(window.location.href);
294
- var hostname = url.hostname;
295
- var gaCookies = j1.findCookie('_ga');
296
- var gasCookies = j1.findCookie('__ga');
297
- var j1Cookies = j1.findCookie('j1');
298
- var cookie_names = j1.getCookieNames();
299
- var user_state = j1.readCookie(cookie_names.user_state);
300
- var user_consent = j1.readCookie(cookie_names.user_consent);
301
- var user_translate = j1.readCookie(cookie_names.user_translate);
302
- var json = JSON.stringify(user_consent);
303
- var user_agent = platform.ua;
304
- var cookie_written;
305
-
306
- logger.info('\n' + 'entered post selection callback from CookieConsent');
307
- logger.info('\n' + 'current values from CookieConsent: ' + json);
308
-
309
- // enable cookie button if not visible
310
- if ($('#quickLinksCookieButton').css('display') === 'none') {
311
- $('#quickLinksCookieButton').css('display', 'block');
312
- }
313
-
314
- // manage Google Analytics OptIn/Out
315
- // See: https://github.com/luciomartinez/gtag-opt-in/wiki
316
- if (tracking_enabled && tracking_id_valid) {
317
- // Managing cookie life-time
318
- // ---------------------------------------------------------------------
319
- // If cookie settings allows only "required" cookies, all "persistent"
320
- // cookies (Comments|Ads|Translation) get expired to "session" for
321
- // better GDPR compliance. The GDPR regulations does NOT require
322
- // any consent on session-only cookies.
323
- //
324
- if (!user_consent.analysis || !user_consent.personalization) {
325
-
326
- // overload cookie consent settings
327
- user_translate.analysis = user_consent.analysis;
328
- user_translate.personalization = user_consent.personalization;
329
- // disable translation service
330
- user_translate.translationEnabled = false;
331
-
332
- cookie_written = j1.writeCookie({
333
- name: cookie_names.user_translate,
334
- data: user_translate,
335
- secure: secure
336
- });
337
-
338
- // expire permanent cookies to session
339
- // -------------------------------------------------------------------
340
- j1.expireCookie({ name: cookie_names.user_state });
341
- j1.expireCookie({ name: cookie_names.user_consent });
342
- j1.expireCookie({ name: cookie_names.user_translate });
343
- }
344
- if (cookieConsentOptions.reloadPageOnChange) {
345
- // reload current page (skip cache)
346
- location.reload(true);
347
- }
348
- } else {
349
- // failsafe: Make (really) sure the all GA|GAS cookies removed
350
- // left from a previous session/page view for better privacy compliance
351
- // ---------------------------------------------------------------------
352
-
353
- // remove cookies on invalid GA config or left from a previous
354
- // session/page view if they exists
355
- // ---------------------------------------------------------------------
356
- gaCookies.forEach((item) => {
357
- logger.warn('\n' + 'delete GA cookie: ' + item);
358
- if (hostname === 'localhost') {
359
- j1.removeCookie({ name: item, domain: false, secure: false });
360
- } else {
361
- j1.removeCookie({ name: item, domain: '.' + hostname, secure: false });
362
- }
363
- });
364
-
365
- // remove cookies on invalid GAS config or left from a previous
366
- // session/page view if they exists
367
- // ---------------------------------------------------------------------
368
- gasCookies.forEach((item) => {
369
- // Remove cookies from Google Ads
370
- logger.warn('\n' + 'delete GAS cookie: ' + item);
371
- if (hostname === 'localhost') {
372
- j1.removeCookie({ name: item, domain: false, secure: false });
373
- } else {
374
- j1.removeCookie({ name: item, domain: '.' + hostname, secure: false });
375
- }
376
- });
377
-
378
- // managing cookie life-time. If cookie settings allows only
379
- // "required" cookies, all "persistent" cookies (Comments|Ads|Translation)
380
- // get expired to "session" for better GDPR compliance. The GDPR
381
- // regulations|privacy does NOT require any consent on using cookies
382
- // for session-only cookies.
383
- // ---------------------------------------------------------------------
384
- if (!user_consent.analysis || !user_consent.personalization) {
385
- // overload cookie consent settings
386
- user_translate.analysis = user_consent.analysis;
387
- user_translate.personalization = user_consent.personalization;
388
- // disable translation service
389
- user_translate.translationEnabled = false;
390
-
391
- cookie_written = j1.writeCookie({
392
- name: cookie_names.user_translate,
393
- data: user_translate,
394
- secure: secure
395
- });
396
-
397
- if (expireCookiesOnRequiredOnly) {
398
- // expire permanent cookies to session
399
- j1.expireCookie({ name: cookie_names.user_state });
400
- j1.expireCookie({ name: cookie_names.user_consent });
401
- j1.expireCookie({ name: cookie_names.user_translate });
402
- }
403
- }
404
-
405
- if (cookieConsentOptions.reloadPageOnChange) {
406
- // reload current page (skip cache)
407
- location.reload(true);
408
- }
409
- } // END if tracking_enabled
410
- }, // END cbCookie
411
-
412
- // -------------------------------------------------------------------------
413
- // messageHandler()
414
- // manage messages send from other J1 modules
415
- // -------------------------------------------------------------------------
416
- messageHandler: (sender, message) => {
417
- var json_message = JSON.stringify(message, undefined, 2);
418
-
419
- logText = '\n' + 'received message from ' + sender + ': ' + json_message;
420
- logger.debug(logText);
421
-
422
- // -----------------------------------------------------------------------
423
- // process commands|actions
424
- // -----------------------------------------------------------------------
425
- if (message.type === 'command' && message.action === 'module_initialized') {
426
-
427
- //
428
- // place handling of command|action here
429
- //
430
-
431
- logger.info('\n' + message.text);
432
- }
433
-
434
- //
435
- // place handling of other command|action here
436
- //
437
-
438
- return true;
439
- }, // END messageHandler
440
-
441
- // -------------------------------------------------------------------------
442
- // setState()
443
- // sets the current (processing) state of the module
444
- // -------------------------------------------------------------------------
445
- setState: (stat) => {
446
- _this.state = stat;
447
- }, // END setState
448
-
449
- // -------------------------------------------------------------------------
450
- // getState()
451
- // Returns the current (processing) state of the module
452
- // -------------------------------------------------------------------------
453
- getState: () => {
454
- return _this.state;
455
- } // END getState
456
-
457
- }; // END main (return)
458
- })(j1, window);
459
-
460
- {% endcapture %}
461
- {% if production %}
462
- {{ cache | minifyJS }}
463
- {% else %}
464
- {{ cache | strip_empty_lines }}
465
- {% endif %}
466
- {% assign cache = nil %}
1
+ ---
2
+ regenerate: true
3
+ ---
4
+
5
+ {% capture cache %}
6
+
7
+ {% comment %}
8
+ # -----------------------------------------------------------------------------
9
+ # ~/assets/themes/j1/adapter/js/cookieConsent.js
10
+ # Liquid template to create the Template Adapter for J1 CookieConsent
11
+ #
12
+ # Product/Info:
13
+ # http://jekyll.one
14
+ #
15
+ # Copyright (C) 2023, 2024 Juergen Adams
16
+ #
17
+ # J1 Template is licensed under the MIT License.
18
+ # For details, see: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE.md
19
+ # -----------------------------------------------------------------------------
20
+ # Test data:
21
+ # {{ liquid_var | debug }}
22
+ # cookie_options: {{ cookie_options | debug }}
23
+ # -----------------------------------------------------------------------------
24
+ {% endcomment %}
25
+
26
+ {% comment %} Liquid var initialization
27
+ -------------------------------------------------------------------------------- {% endcomment %}
28
+
29
+ {% comment %} Set config files
30
+ -------------------------------------------------------------------------------- {% endcomment %}
31
+ {% assign environment = site.environment %}
32
+ {% assign blocks = site.data.blocks %}
33
+ {% assign modules = site.data.modules %}
34
+ {% assign template_config = site.data.j1_config %}
35
+
36
+ {% comment %} Set config data
37
+ -------------------------------------------------------------------------------- {% endcomment %}
38
+ {% assign cookie_defaults = modules.defaults.cookies.defaults %}
39
+ {% assign cookie_settings = modules.cookies.settings %}
40
+ {% assign consent_defaults = modules.defaults.cookieconsent.defaults %}
41
+ {% assign consent_settings = modules.cookieconsent.settings %}
42
+ {% assign analytics_defaults = modules.defaults.analytics.defaults %}
43
+ {% assign analytics_settings = modules.analytics.settings %}
44
+
45
+ {% comment %} Set config options
46
+ -------------------------------------------------------------------------------- {% endcomment %}
47
+ {% assign consent_options = consent_defaults | merge: consent_settings %}
48
+ {% assign cookie_options = cookie_defaults | merge: cookie_settings %}
49
+ {% assign analytics_options = analytics_defaults | merge: analytics_settings %}
50
+
51
+ {% comment %} Set variables
52
+ -------------------------------------------------------------------------------- {% endcomment %}
53
+ {% assign tracking_enabled = analytics_options.enabled %}
54
+ {% assign tracking_id = analytics_options.google.trackingID %}
55
+
56
+ {% comment %} Detect prod mode
57
+ -------------------------------------------------------------------------------- {% endcomment %}
58
+ {% assign production = false %}
59
+ {% if environment == 'prod' or environment == 'production' %}
60
+ {% assign production = true %}
61
+ {% endif %}
62
+
63
+ /*
64
+ # -----------------------------------------------------------------------------
65
+ # ~/assets/themes/j1/adapter/js/cookieConsent.js
66
+ # JS Adapter for J1 CookieConsent
67
+ #
68
+ # Product/Info:
69
+ # http://jekyll.one
70
+ #
71
+ # Copyright (C) 2023, 2024 Juergen Adams
72
+ #
73
+ # J1 Theme is licensed under MIT License.
74
+ # See: https://github.com/jekyll-one/J1 Theme/blob/master/LICENSE
75
+ # -----------------------------------------------------------------------------
76
+ # Adapter generated: {{site.time}}
77
+ # -----------------------------------------------------------------------------
78
+ */
79
+
80
+ // -----------------------------------------------------------------------------
81
+ // ESLint shimming
82
+ // -----------------------------------------------------------------------------
83
+ /* eslint indent: "off" */
84
+ /* eslint quotes: "off" */
85
+ // -----------------------------------------------------------------------------
86
+ 'use strict';
87
+ j1.adapter.cookieConsent = ((j1, window) => {
88
+ var environment = '{{environment}}';
89
+ var tracking_enabled = ('{{tracking_enabled}}' === 'true') ? true: false;
90
+ var tracking_id = '{{tracking_id}}';
91
+ var tracking_id_valid = (tracking_id.includes('tracking-id')) ? false : true;
92
+ var stringifiedAttributes = '';
93
+ var state = 'not_started';
94
+
95
+ var expireCookiesOnRequiredOnly;
96
+
97
+ var cookieDefaults;
98
+ var cookieSettings;
99
+ var cookieOptions;
100
+
101
+ var cookieConsentDefaults;
102
+ var cookieConsentSettings;
103
+ var cookieConsentOptions;
104
+
105
+ var $modal;
106
+ var cookie_names;
107
+ var user_cookie;
108
+ var url;
109
+ var baseUrl;
110
+ var hostname;
111
+ var auto_domain;
112
+ var check_cookie_option_domain;
113
+ var cookie_domain;
114
+ var secure;
115
+ var cookie_written;
116
+ var contentLanguage;
117
+ var navigatorLanguage;
118
+ var domainAttribute;
119
+
120
+ var logger;
121
+ var logText;
122
+ var _this;
123
+
124
+ // date|time
125
+ var startTime;
126
+ var endTime;
127
+ var startTimeModule;
128
+ var endTimeModule;
129
+ var timeSeconds;
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // helper functions
133
+ // ---------------------------------------------------------------------------
134
+ // NOTE: RegEx for tracking_id: ^(G|UA|YT|MO)-[a-zA-Z0-9-]+$
135
+ // See: https://stackoverflow.com/questions/20411767/how-to-validate-google-analytics-tracking-id-using-a-javascript-function/20412153
136
+
137
+ // ---------------------------------------------------------------------------
138
+ // main
139
+ // ---------------------------------------------------------------------------
140
+ return {
141
+
142
+ // -------------------------------------------------------------------------
143
+ // adapter initializer
144
+ // -------------------------------------------------------------------------
145
+ init: (options) => {
146
+
147
+ // -----------------------------------------------------------------------
148
+ // default module settings
149
+ // -----------------------------------------------------------------------
150
+ var settings = $.extend({
151
+ module_name: 'j1.adapter.cookieConsent',
152
+ generated: '{{site.time}}'
153
+ }, options);
154
+
155
+ // -----------------------------------------------------------------------
156
+ // global variable settings
157
+ // -----------------------------------------------------------------------
158
+ _this = j1.adapter.cookieConsent;
159
+ logger = log4javascript.getLogger('j1.adapter.cookieConsent');
160
+ cookie_names = j1.getCookieNames();
161
+ url = new liteURL(window.location.href);
162
+ baseUrl = url.origin;
163
+ hostname = url.hostname;
164
+ auto_domain = hostname.substring(hostname.lastIndexOf('.', hostname.lastIndexOf('.') - 1) + 1);
165
+ secure = (url.protocol.includes('https')) ? true : false;
166
+ contentLanguage = '{{site.language}}';
167
+ navigatorLanguage = navigator.language || navigator.userLanguage;
168
+
169
+ // Load cookie DEFAULTS|CONFIG
170
+ cookieDefaults = $.extend({}, {{cookie_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
171
+ cookieSettings = $.extend({}, {{cookie_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
172
+ cookieOptions = $.extend(true, {}, cookieDefaults, cookieSettings);
173
+
174
+ // Load module DEFAULTS|CONFIG
175
+ cookieConsentDefaults = $.extend({}, {{consent_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
176
+ cookieConsentSettings = $.extend({}, {{consent_settings | replace: 'nil', 'null' | replace: '=>', ':' }});
177
+ cookieConsentOptions = $.extend(true, {}, cookieConsentDefaults, cookieConsentSettings);
178
+
179
+ if (navigatorLanguage.indexOf("-") !== -1) {
180
+ navigatorLanguage = navigatorLanguage.split("-")[0];
181
+ }
182
+
183
+ if (cookieConsentOptions.dialogLanguage === 'auto') {
184
+ cookieConsentOptions.dialogLanguage = navigatorLanguage;
185
+ } else if (cookieConsentOptions.dialogLanguage === 'content') {
186
+ cookieConsentOptions.dialogLanguage = contentLanguage;
187
+ } else {
188
+ cookieConsentOptions.dialogLanguage = navigatorLanguage;
189
+ }
190
+
191
+ check_cookie_option_domain = (cookieOptions.domain === 'false') ? false : true;
192
+ expireCookiesOnRequiredOnly = (cookieOptions.expireCookiesOnRequiredOnly === 'true') ? true: false;
193
+
194
+ // -----------------------------------------------------------------------
195
+ // module initializer
196
+ // -----------------------------------------------------------------------
197
+ var dependencies_met_page_ready = setInterval((options) => {
198
+ var pageState = $('#content').css("display");
199
+ var pageVisible = (pageState === 'block') ? true : false;
200
+ var j1CoreFinished = (j1.getState() === 'finished') ? true : false;
201
+
202
+ if (j1CoreFinished) {
203
+ var same_site = cookieOptions.same_site;
204
+ var expires;
205
+
206
+ startTimeModule = Date.now();
207
+
208
+ _this.setState('started');
209
+ logger.debug('\n' + 'set module state to: ' + _this.getState());
210
+ logger.info('\n' + 'initializing module: started');
211
+
212
+ if (cookieConsentOptions.enabled) {
213
+ expires = cookieOptions.expires;
214
+ } else {
215
+ // expire permanent cookies to session
216
+ j1.expireCookie({ name: cookie_names.user_state });
217
+ j1.expireCookie({ name: cookie_names.user_consent });
218
+ j1.expireCookie({ name: cookie_names.user_translate });
219
+
220
+ // disable the themes menus
221
+ $('#themes_menu').css('display', 'none');
222
+ $('#themes_mmenu').css('display', 'none');
223
+ logger.warn('\n' + 'disable module: Themes');
224
+
225
+ // disable the quick link for (Google) Translation
226
+ $('#quickLinksTranslateButton').css('display', 'none');
227
+ logger.warn('\n' + 'disable module: Trranslator');
228
+ }
229
+
230
+ // set domain used by cookies
231
+ if (check_cookie_option_domain) {
232
+ if (cookieOptions.domain === 'auto') {
233
+ domainAttribute = auto_domain;
234
+ stringifiedAttributes += '; ' + 'Domain=' + domainAttribute;
235
+ } else {
236
+ domainAttribute = cookieOptions.domain;
237
+ stringifiedAttributes += '; ' + 'Domain=' + domainAttribute;
238
+ }
239
+ } else {
240
+ domainAttribute = cookieOptions.domain;
241
+ }
242
+
243
+ // failsafe: if 'None' is given for samesite in non-secure
244
+ // environments open access to cookies to subdomains
245
+ // ---------------------------------------------------------------------
246
+ if (same_site === 'None' && !secure) {
247
+ same_site = 'Lax';
248
+ }
249
+
250
+ // -------------------------------------------------------------------
251
+ // NOTE: Click events moved to Navigator (core)
252
+ // -------------------------------------------------------------------
253
+
254
+ if (cookieConsentOptions.enabled) {
255
+ logger.info('\n' + 'initialize core module');
256
+
257
+ j1.cookieConsent = new CookieConsent ({
258
+ contentURL: cookieConsentOptions.contentURL, // dialog content (modals) for all supported languages
259
+ cookieName: cookie_names.user_consent, // name of the consent cookie
260
+ cookieStorageDays: expires, // lifetime of a cookie [0..365], 0: session cookie
261
+ cookieSameSite: same_site, // restrict consent cookie
262
+ cookieSecure: secure, // only sent to the server with an encrypted request over HTTPS
263
+ cookieDomain: domainAttribute, // set domain (hostname|domain)
264
+ dialogLanguage: cookieConsentOptions.dialogLanguage, // language for the dialog (modal)
265
+ whitelisted: cookieConsentOptions.whitelisted, // pages NO cookie dialog is shown
266
+ reloadPageOnChange: cookieConsentOptions.reloadPageOnChange, // reload if setzings has changed
267
+ dialogContainerID: cookieConsentOptions.dialogContainerID, // container, the dialog modal is (dynamically) loaded
268
+ xhrDataElement: cookieConsentOptions.xhrDataElement, // container for all language-specific dialogs (modals)
269
+ postSelectionCallback: cookieConsentOptions.postSelectionCallback, // callback function, called after the user has made his selection
270
+ });
271
+ } else {
272
+ logger.warn('\n' + 'module is disabled');
273
+ } // END if cookieConsentOptions enabled
274
+
275
+ _this.setState('finished');
276
+ logger.debug('\n' + 'state: ' + _this.getState());
277
+ logger.info('\n' + 'module initialized successfully');
278
+
279
+ endTimeModule = Date.now();
280
+ logger.info('\n' + 'module initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
281
+
282
+ clearInterval(dependencies_met_page_ready);
283
+ } // END j1CoreFinished
284
+ }, 10); // END dependencies_met_page_ready
285
+ }, // END init
286
+
287
+ // -------------------------------------------------------------------------
288
+ // cbCookie()
289
+ // callback for CookieConsent module after the user has
290
+ // made his selection
291
+ // -------------------------------------------------------------------------
292
+ cbCookie: () => {
293
+ var url = new liteURL(window.location.href);
294
+ var hostname = url.hostname;
295
+ var gaCookies = j1.findCookie('_ga');
296
+ var gasCookies = j1.findCookie('__ga');
297
+ var j1Cookies = j1.findCookie('j1');
298
+ var cookie_names = j1.getCookieNames();
299
+ var user_state = j1.readCookie(cookie_names.user_state);
300
+ var user_consent = j1.readCookie(cookie_names.user_consent);
301
+ var user_translate = j1.readCookie(cookie_names.user_translate);
302
+ var json = JSON.stringify(user_consent);
303
+ var user_agent = platform.ua;
304
+ var cookie_written;
305
+
306
+ logger.info('\n' + 'entered post selection callback from CookieConsent');
307
+ logger.info('\n' + 'current values from CookieConsent: ' + json);
308
+
309
+ // enable cookie button if not visible
310
+ if ($('#quickLinksCookieButton').css('display') === 'none') {
311
+ $('#quickLinksCookieButton').css('display', 'block');
312
+ }
313
+
314
+ // manage Google Analytics OptIn/Out
315
+ // See: https://github.com/luciomartinez/gtag-opt-in/wiki
316
+ if (tracking_enabled && tracking_id_valid) {
317
+ // Managing cookie life-time
318
+ // ---------------------------------------------------------------------
319
+ // If cookie settings allows only "required" cookies, all "persistent"
320
+ // cookies (Comments|Ads|Translation) get expired to "session" for
321
+ // better GDPR compliance. The GDPR regulations does NOT require
322
+ // any consent on session-only cookies.
323
+ //
324
+ if (!user_consent.analysis || !user_consent.personalization) {
325
+
326
+ // overload cookie consent settings
327
+ user_translate.analysis = user_consent.analysis;
328
+ user_translate.personalization = user_consent.personalization;
329
+ // disable translation service
330
+ user_translate.translationEnabled = false;
331
+
332
+ cookie_written = j1.writeCookie({
333
+ name: cookie_names.user_translate,
334
+ data: user_translate,
335
+ secure: secure
336
+ });
337
+
338
+ // expire permanent cookies to session
339
+ // -------------------------------------------------------------------
340
+ j1.expireCookie({ name: cookie_names.user_state });
341
+ j1.expireCookie({ name: cookie_names.user_consent });
342
+ j1.expireCookie({ name: cookie_names.user_translate });
343
+ }
344
+ if (cookieConsentOptions.reloadPageOnChange) {
345
+ // reload current page (skip cache)
346
+ location.reload(true);
347
+ }
348
+ } else {
349
+ // failsafe: Make (really) sure the all GA|GAS cookies removed
350
+ // left from a previous session/page view for better privacy compliance
351
+ // ---------------------------------------------------------------------
352
+
353
+ // remove cookies on invalid GA config or left from a previous
354
+ // session/page view if they exists
355
+ // ---------------------------------------------------------------------
356
+ gaCookies.forEach((item) => {
357
+ logger.warn('\n' + 'delete GA cookie: ' + item);
358
+ j1.removeCookie({ name: item });
359
+ });
360
+
361
+ // remove cookies on invalid GAS config or left from a previous
362
+ // session/page view if they exists
363
+ // ---------------------------------------------------------------------
364
+ gasCookies.forEach((item) => {
365
+ // Remove cookies from Google Ads
366
+ logger.warn('\n' + 'delete GAS cookie: ' + item);
367
+ j1.removeCookie({
368
+ name: item
369
+ });
370
+ });
371
+
372
+ // managing cookie life-time. If cookie settings allows only
373
+ // "required" cookies, all "persistent" cookies (Comments|Ads|Translation)
374
+ // get expired to "session" for better GDPR compliance. The GDPR
375
+ // regulations|privacy does NOT require any consent on using cookies
376
+ // for session-only cookies.
377
+ // ---------------------------------------------------------------------
378
+ if (!user_consent.analysis || !user_consent.personalization) {
379
+ // overload cookie consent settings
380
+ user_translate.analysis = user_consent.analysis;
381
+ user_translate.personalization = user_consent.personalization;
382
+ // disable translation service
383
+ user_translate.translationEnabled = false;
384
+
385
+ cookie_written = j1.writeCookie({
386
+ name: cookie_names.user_translate,
387
+ data: user_translate,
388
+ secure: secure
389
+ });
390
+
391
+ if (expireCookiesOnRequiredOnly) {
392
+ // expire permanent cookies to session
393
+ j1.expireCookie({ name: cookie_names.user_state });
394
+ j1.expireCookie({ name: cookie_names.user_consent });
395
+ j1.expireCookie({ name: cookie_names.user_translate });
396
+ }
397
+ }
398
+
399
+ if (cookieConsentOptions.reloadPageOnChange) {
400
+ // reload current page (skip cache)
401
+ location.reload(true);
402
+ }
403
+ } // END if tracking_enabled
404
+ }, // END cbCookie
405
+
406
+ // -------------------------------------------------------------------------
407
+ // messageHandler()
408
+ // manage messages send from other J1 modules
409
+ // -------------------------------------------------------------------------
410
+ messageHandler: (sender, message) => {
411
+ var json_message = JSON.stringify(message, undefined, 2);
412
+
413
+ logText = '\n' + 'received message from ' + sender + ': ' + json_message;
414
+ logger.debug(logText);
415
+
416
+ // -----------------------------------------------------------------------
417
+ // process commands|actions
418
+ // -----------------------------------------------------------------------
419
+ if (message.type === 'command' && message.action === 'module_initialized') {
420
+
421
+ //
422
+ // place handling of command|action here
423
+ //
424
+
425
+ logger.info('\n' + message.text);
426
+ }
427
+
428
+ //
429
+ // place handling of other command|action here
430
+ //
431
+
432
+ return true;
433
+ }, // END messageHandler
434
+
435
+ // -------------------------------------------------------------------------
436
+ // setState()
437
+ // sets the current (processing) state of the module
438
+ // -------------------------------------------------------------------------
439
+ setState: (stat) => {
440
+ _this.state = stat;
441
+ }, // END setState
442
+
443
+ // -------------------------------------------------------------------------
444
+ // getState()
445
+ // Returns the current (processing) state of the module
446
+ // -------------------------------------------------------------------------
447
+ getState: () => {
448
+ return _this.state;
449
+ } // END getState
450
+
451
+ }; // END main (return)
452
+ })(j1, window);
453
+
454
+ {% endcapture %}
455
+ {% if production %}
456
+ {{ cache | minifyJS }}
457
+ {% else %}
458
+ {{ cache | strip_empty_lines }}
459
+ {% endif %}
460
+ {% assign cache = nil %}