j1-template 2021.1.8 → 2021.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/layout_metadata_generator.html +4 -4
  3. data/_includes/themes/j1/modules/connectors/ads +18 -7
  4. data/_includes/themes/j1/modules/connectors/analytic/google-analytics.html +6 -6
  5. data/_includes/themes/j1/modules/connectors/analytics +17 -3
  6. data/_includes/themes/j1/modules/connectors/comments +22 -8
  7. data/_includes/themes/j1/modules/connectors/translator +20 -6
  8. data/_includes/themes/j1/procedures/global/select_location.proc +3 -3
  9. data/assets/error_pages/HTTP204.html +33 -10
  10. data/assets/error_pages/HTTP400.html +32 -8
  11. data/assets/error_pages/HTTP401.html +32 -9
  12. data/assets/error_pages/HTTP403.html +32 -8
  13. data/assets/error_pages/HTTP404.html +32 -8
  14. data/assets/error_pages/HTTP500.html +32 -8
  15. data/assets/error_pages/HTTP501.html +32 -8
  16. data/assets/error_pages/HTTP502.html +32 -8
  17. data/assets/error_pages/HTTP503.html +33 -8
  18. data/assets/themes/j1/adapter/js/cookieConsent.js +64 -59
  19. data/assets/themes/j1/adapter/js/fam.js +2 -1
  20. data/assets/themes/j1/adapter/js/j1.js +315 -128
  21. data/assets/themes/j1/adapter/js/navigator.js +5 -2
  22. data/assets/themes/j1/adapter/js/themer.js +137 -90
  23. data/assets/themes/j1/core/js/template.js +24 -4
  24. data/assets/themes/j1/core/js/template.js.map +1 -1
  25. data/assets/themes/j1/core/js/template.min.js +24 -4
  26. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  27. data/assets/themes/j1/modules/cookieConsent/js/cookieConsent.js +36 -16
  28. data/assets/themes/j1/modules/cookieConsent/js/cookieConsent.min.js +2 -3
  29. data/assets/themes/j1/modules/themeSwitcher/js/switcher.js +1 -2
  30. data/lib/j1/version.rb +1 -1
  31. data/lib/starter_web/Gemfile +1 -1
  32. data/lib/starter_web/_config.yml +18 -10
  33. data/lib/starter_web/_data/_defaults/private.default.yml +119 -0
  34. data/lib/starter_web/_data/j1_config.yml +1 -1
  35. data/lib/starter_web/_data/modules/cookieconsent.yml +1 -0
  36. data/lib/starter_web/_data/modules/defaults/cookieconsent.yml +11 -9
  37. data/lib/starter_web/_data/resources.yml +0 -4
  38. data/lib/starter_web/_includes/attributes.asciidoc +1 -1
  39. data/lib/starter_web/_plugins/lunr_index.rb +1 -1
  40. data/lib/starter_web/dot.gitignore +1 -1
  41. data/lib/starter_web/index.html +3 -3
  42. data/lib/starter_web/package.json +2 -2
  43. data/lib/starter_web/pages/public/blog/navigator/archive.html +2 -1
  44. data/lib/starter_web/pages/public/blog/navigator/archive/dateview.html +3 -2
  45. data/lib/starter_web/pages/public/blog/navigator/archive/tagview.html +20 -3
  46. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +9 -6
  47. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  48. data/lib/starter_web/utilsrv/package.json +1 -1
  49. metadata +3 -65
  50. data/assets/error_pages/HTTP520.html +0 -68
  51. data/assets/error_pages/HTTP521.html +0 -68
  52. data/assets/error_pages/HTTP533.html +0 -68
  53. data/assets/themes/j1/adapter/js/navigator.1.js +0 -896
  54. data/assets/themes/j1/adapter/js/navigator.2.js +0 -928
  55. data/assets/themes/j1/adapter/js/themer.1.js +0 -326
  56. data/assets/themes/j1/modules/_lightGallery/css/core/lg-fb-comment-box.css +0 -58
  57. data/assets/themes/j1/modules/_lightGallery/css/core/lg-fb-comment-box.min.css +0 -5
  58. data/assets/themes/j1/modules/_lightGallery/css/core/lg-transitions.css +0 -778
  59. data/assets/themes/j1/modules/_lightGallery/css/core/lg-transitions.min.css +0 -5
  60. data/assets/themes/j1/modules/_lightGallery/css/core/lightgallery.css +0 -981
  61. data/assets/themes/j1/modules/_lightGallery/css/core/lightgallery.min.css +0 -5
  62. data/assets/themes/j1/modules/_lightGallery/css/fonts/lg.eot +0 -0
  63. data/assets/themes/j1/modules/_lightGallery/css/fonts/lg.svg +0 -47
  64. data/assets/themes/j1/modules/_lightGallery/css/fonts/lg.ttf +0 -0
  65. data/assets/themes/j1/modules/_lightGallery/css/fonts/lg.woff +0 -0
  66. data/assets/themes/j1/modules/_lightGallery/css/img/loading.gif +0 -0
  67. data/assets/themes/j1/modules/_lightGallery/css/img/video-play.png +0 -0
  68. data/assets/themes/j1/modules/_lightGallery/css/img/vimeo-play.png +0 -0
  69. data/assets/themes/j1/modules/_lightGallery/css/img/youtube-play.png +0 -0
  70. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/animation-w.png +0 -0
  71. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/customize-w.png +0 -0
  72. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/dynamic-w.png +0 -0
  73. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/facebook-icon.svg +0 -10
  74. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/googleplus-icon.svg +0 -30
  75. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/html5-w.png +0 -0
  76. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/linked-in.png +0 -0
  77. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/module-w.png +0 -0
  78. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/play-button.png +0 -0
  79. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/responsive-w.png +0 -0
  80. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/thumb-w.png +0 -0
  81. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/touch-w.png +0 -0
  82. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/twitter-icon.svg +0 -15
  83. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/twitter.png +0 -0
  84. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/video1-w.png +0 -0
  85. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/zoom-w.png +0 -0
  86. data/assets/themes/j1/modules/_lightGallery/css/themes/icons/zoom.png +0 -0
  87. data/assets/themes/j1/modules/_lightGallery/css/themes/uno.css +0 -262
  88. data/assets/themes/j1/modules/_lightGallery/css/themes/uno.min.css +0 -15
  89. data/assets/themes/j1/modules/_lightGallery/js/core/lightgallery.js +0 -1362
  90. data/assets/themes/j1/modules/_lightGallery/js/core/lightgallery.min.js +0 -4
  91. data/assets/themes/j1/modules/_lightGallery/js/modules/j1/j1-video.js +0 -402
  92. data/assets/themes/j1/modules/_lightGallery/js/modules/j1/j1-video.min.js +0 -8
  93. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-autoplay.js +0 -206
  94. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-autoplay.min.js +0 -5
  95. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-fullscreen.js +0 -126
  96. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-fullscreen.min.js +0 -5
  97. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-hash.js +0 -101
  98. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-hash.min.js +0 -5
  99. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-pager.js +0 -105
  100. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-pager.min.js +0 -5
  101. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-share.js +0 -107
  102. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-share.min.js +0 -5
  103. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-thumbnail.js +0 -478
  104. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-thumbnail.min.js +0 -5
  105. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-video.js +0 -342
  106. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-video.min.js +0 -5
  107. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-zoom.js +0 -527
  108. data/assets/themes/j1/modules/_lightGallery/js/modules/lg-zoom.min.js +0 -5
  109. data/assets/themes/j1/modules/util/js/js.cookie.js +0 -163
  110. data/assets/themes/j1/modules/util/js/lite-url.js +0 -203
  111. data/assets/themes/j1/modules/util/js/lite-url.min.js +0 -7
  112. data/assets/themes/j1/modules/util/js/platform.js +0 -1260
@@ -28,14 +28,16 @@ regenerate: true
28
28
  {% comment %} Set config files
29
29
  -------------------------------------------------------------------------------- {% endcomment %}
30
30
  {% assign environment = site.environment %}
31
+ {% assign blocks = site.data.blocks %}
31
32
  {% assign modules = site.data.modules %}
33
+ {% assign template_config = site.data.j1_config %}
32
34
 
33
35
  {% comment %} Set config data
34
36
  -------------------------------------------------------------------------------- {% endcomment %}
35
37
  {% assign consent_defaults = modules.defaults.cookieconsent.defaults %}
36
38
  {% assign consent_settings = modules.cookieconsent.settings %}
37
- {% assign tracking_enabled = site.data.j1_config.analytics.enabled %}
38
- {% assign tracking_id = site.data.j1_config.analytics.google.tracking_id %}
39
+ {% assign tracking_enabled = template_config.analytics.enabled %}
40
+ {% assign tracking_id = template_config.analytics.google.tracking_id %}
39
41
 
40
42
  {% comment %} Set config options
41
43
  -------------------------------------------------------------------------------- {% endcomment %}
@@ -89,6 +91,7 @@ j1.adapter['cookieConsent'] = (function (j1, window) {
89
91
  var user_cookie;
90
92
  var logger;
91
93
  var logText;
94
+ var cookie_written;
92
95
 
93
96
  // NOTE: RegEx for tracking_id: ^(G|UA|YT|MO)-[a-zA-Z0-9-]+$
94
97
  // See: https://stackoverflow.com/questions/20411767/how-to-validate-google-analytics-tracking-id-using-a-javascript-function/20412153
@@ -138,31 +141,29 @@ j1.adapter['cookieConsent'] = (function (j1, window) {
138
141
  // -----------------------------------------------------------------------
139
142
  // initializer
140
143
  // -----------------------------------------------------------------------
141
- _this.setState('started');
142
- logger.info('state: ' + _this.getState());
143
- logger.info('module is being initialized');
144
-
145
- j1.cookieConsent = new BootstrapCookieConsent({
146
- contentURL: moduleOptions.contentURL,
147
- cookieName: moduleOptions.cookieName,
148
- language: moduleOptions.language,
149
- whitelisted: moduleOptions.whitelisted,
150
- reloadPageOnChange: moduleOptions.reloadCurrentPage,
151
- xhr_data_element: moduleOptions.xhr_data_element + '-' + moduleOptions.language,
152
- postSelectionCallback: function () {
153
- j1.adapter.cookieConsent.cbCookie()
154
- }
155
- });
156
-
157
144
  var dependencies_met_page_ready = setInterval (function (options) {
158
- if ( j1.cookieConsent && j1.getState() === 'finished' ) {
145
+ if ( j1.getState() === 'finished' ) {
146
+ _this.setState('started');
147
+ logger.info('state: ' + _this.getState());
148
+ logger.info('module is being initialized');
149
+
150
+ j1.cookieConsent = new BootstrapCookieConsent({
151
+ contentURL: moduleOptions.contentURL,
152
+ cookieName: moduleOptions.cookieName,
153
+ language: moduleOptions.language,
154
+ whitelisted: moduleOptions.whitelisted,
155
+ reloadPageOnChange: moduleOptions.reloadPageOnChange,
156
+ xhr_data_element: moduleOptions.xhr_data_element + '-' + moduleOptions.language,
157
+ sameSite: moduleOptions.sameSite,
158
+ postSelectionCallback: function () {j1.adapter.cookieConsent.cbCookie()}
159
+ });
160
+
159
161
  _this.setState('finished');
160
162
  logger.info('state: ' + _this.getState());
161
163
  logger.debug('module initialized successfully');
162
164
  clearInterval(dependencies_met_page_ready);
163
165
  }
164
166
  });
165
-
166
167
  }, // END init
167
168
 
168
169
  // -------------------------------------------------------------------------
@@ -214,23 +215,42 @@ j1.adapter['cookieConsent'] = (function (j1, window) {
214
215
  // made his selection (callback)
215
216
  // -------------------------------------------------------------------------
216
217
  cbCookie: function () {
217
- var gaCookies = j1.findCookie('_ga');
218
- var user_state = j1.readCookie('j1.user.state');
219
- var user_consent = j1.readCookie('j1.user.consent');
220
- var json = JSON.stringify(user_consent);
218
+ var gaCookies = j1.findCookie('_ga');
219
+ var j1Cookies = j1.findCookie('j1');
220
+ var cookie_names = j1.getCookieNames();
221
+ var user_state = j1.readCookie(cookie_names.user_state);
222
+ var user_consent = j1.readCookie(cookie_names.user_consent);
223
+ var json = JSON.stringify(user_consent);
224
+ var user_agent = platform.ua;
221
225
 
222
226
  logger.info('Entered post selection callback from CookieConsent');
223
227
  logger.info('Current values from CookieConsent: ' + json);
224
228
 
229
+ // enable cookie button if not visible
230
+ if ($('#quickLinksCookieButton').css('display') === 'none') {
231
+ $('#quickLinksCookieButton').css('display', 'block');
232
+ }
233
+
234
+ // jadams, 2021-07-11: moved to j1 adapter (displayPage)
225
235
  // NOTE: Warning needs to be moved to another module
226
236
  // because page is reloaded after selection
227
237
  //
228
- if (tracking_enabled && !tracking_id_valid) {
229
- logger.warn('tracking enabled, but invalid tracking id found: ' + tracking_id);
238
+ // if (tracking_enabled && !tracking_id_valid) {
239
+ // logger.error('tracking enabled, but invalid tracking id found: ' + tracking_id);
240
+ // } else {
241
+ // logger.warn('tracking enabled, tracking id found: ' + tracking_id);
242
+ // }
243
+
244
+ // for development only
245
+ if (environment === 'development') {
246
+ gaCookies.forEach(item => console.log('cookieConsent: ' + item));
247
+ j1Cookies.forEach(item => console.log('cookieConsent: ' + item));
230
248
  }
231
249
 
232
- // for debugging
233
- // gaCookies.forEach(item => console.log('cookieConsent: ' + item));
250
+ if (user_agent.includes('iPad')) {
251
+ logger.warn('Product detected : ' + platform.product);
252
+ logger.warn('Skip deleting (unwanted) cookies for this platform');
253
+ }
234
254
 
235
255
  // Manage Google Analytics OptIn/Out
236
256
  // See: https://github.com/luciomartinez/gtag-opt-in/wiki
@@ -242,40 +262,25 @@ j1.adapter['cookieConsent'] = (function (j1, window) {
242
262
  } else {
243
263
  logger.warn('Disable: GA');
244
264
  GTagOptIn.optOut();
245
- var gaCookies = j1.findCookie('_ga');
246
- gaCookies.forEach(function (item) {
247
- logger.warn('Delete GA cookie: ' + item);
248
- j1.removeCookie({
249
- name: item,
250
- path: '/'
265
+
266
+ if (!user_agent.includes('iPad')) {
267
+ gaCookies.forEach(function (item) {
268
+ logger.warn('Delete GA cookie: ' + item);
269
+ j1.removeCookie(item);
251
270
  });
252
- });
271
+ }
272
+ }
273
+ if (!user_consent.analyses || !user_consent.personalization) {
274
+ // expire consent|state cookies to session
275
+ j1.expireCookie({ name: cookie_names.user_state });
276
+ j1.expireCookie({ name: cookie_names.user_consent });
277
+ }
278
+ if (moduleOptions.reloadPageOnChange) {
279
+ // reload current page (skip cache)
280
+ location.reload(true);
253
281
  }
254
- }
255
-
256
-
257
- // enable cookie button if not visible
258
- if ($('#quickLinksCookieButton').css('display') === 'none') {
259
- $('#quickLinksCookieButton').css('display', 'block');
260
- }
261
-
262
- if (!user_consent.analyses || !user_consent.personalization) {
263
- // expire consent|state cookies to session
264
- j1.writeCookie({
265
- name: 'j1.user.state',
266
- data: user_state,
267
- samesite: 'Strict'
268
- });
269
- j1.writeCookie({
270
- name: 'j1.user.consent',
271
- data: user_consent,
272
- samesite: 'Strict'
273
- });
274
- }
275
-
276
- // reload page after selection
277
- location.reload();
278
282
 
283
+ } // END if tracking_enabled
279
284
  } // END cbCookie
280
285
 
281
286
  }; // END return
@@ -393,7 +393,8 @@ j1.adapter['fam'] = (function (j1, window) {
393
393
  // reload page
394
394
  // -------------------------------------------------------------------------
395
395
  reload_page: function () {
396
- location.reload();
396
+ // reload current page (skip cache)
397
+ location.reload(true);
397
398
  }, // END reload_page
398
399
 
399
400
  // -------------------------------------------------------------------------
@@ -41,9 +41,9 @@ regenerate: true
41
41
 
42
42
  {% comment %} Set config files
43
43
  -------------------------------------------------------------------------------- {% endcomment %}
44
- {% assign template_config = site.data.j1_config %}
45
44
  {% assign blocks = site.data.blocks %}
46
45
  {% assign modules = site.data.modules %}
46
+ {% assign template_config = site.data.j1_config %}
47
47
 
48
48
  {% comment %} Set config data
49
49
  -------------------------------------------------------------------------------- {% endcomment %}
@@ -56,6 +56,8 @@ regenerate: true
56
56
  {% assign toccer_settings = modules.toccer.settings %}
57
57
  {% assign themer_defaults = modules.defaults.themer.defaults %}
58
58
  {% assign themer_settings = modules.themer.settings %}
59
+ {% assign tracking_enabled = template_config.analytics.enabled %}
60
+ {% assign tracking_id = template_config.analytics.google.tracking_id %}
59
61
 
60
62
  {% assign authentication_defaults = modules.defaults.authentication.defaults %}
61
63
  {% assign authentication_settings = modules.authentication.settings %}
@@ -122,6 +124,11 @@ var j1 = (function () {
122
124
  var state = 'not_started';
123
125
  var mode = 'not_detected';
124
126
 
127
+ // Tracking information (GA)
128
+ var tracking_enabled = ('{{tracking_enabled}}' === 'true') ? true: false;
129
+ var tracking_id = '{{tracking_id}}';
130
+ var tracking_id_valid = (tracking_id.includes('tracking-id')) ? false : true;
131
+
125
132
  var current_user_data;
126
133
  var current_page;
127
134
  var previous_page;
@@ -129,6 +136,7 @@ var j1 = (function () {
129
136
  var last_pager_url;
130
137
  var app_detected;
131
138
  var user_session_detected;
139
+ var cookie_written;
132
140
 
133
141
  // Translatior settings (currently NOT supported)
134
142
  // var translation_enabled = {{template_config.translation.enabled}};
@@ -157,17 +165,16 @@ var j1 = (function () {
157
165
  var baseUrl;
158
166
  var referrer;
159
167
 
168
+ // initial cookie values
160
169
  var cookie_names = {
161
170
  'app_session': '{{template_config.cookies.app_session}}',
162
171
  'user_session': '{{template_config.cookies.user_session}}',
163
172
  'user_state': '{{template_config.cookies.user_state}}',
164
173
  'user_consent': '{{template_config.cookies.user_consent}}'
165
174
  };
166
-
167
- // user SESSION cookie (initial values)
168
175
  var user_session = {
169
176
  'mode': 'web',
170
- 'writer': 'web',
177
+ 'writer': 'j1.adapter',
171
178
  'locale': navigator.language || navigator.userLanguage,
172
179
  'user_name': '{{template_config.user.user_name}}',
173
180
  'provider': '{{template_config.user.provider}}',
@@ -182,17 +189,17 @@ var j1 = (function () {
182
189
  'previous_page': 'na',
183
190
  'last_pager': '/pages/public/blog/navigator/'
184
191
  };
185
-
186
192
  var user_state = {
193
+ 'writer': 'j1.adapter',
194
+ 'theme_css': '',
187
195
  'theme_css': '',
188
196
  'theme_name': '',
189
197
  'theme_author': '',
190
- 'theme_version': '{{site.version}}',
198
+ 'theme_version': '{{template_version}}',
191
199
  'session_active': false,
192
200
  'last_session_ts': ''
193
201
  };
194
-
195
- var user_consent;
202
+ var user_consent = {};
196
203
 
197
204
  // ---------------------------------------------------------------------------
198
205
  // helper functions
@@ -223,12 +230,12 @@ var j1 = (function () {
223
230
  // -----------------------------------------------------------------------
224
231
  // global var (function)
225
232
  // -----------------------------------------------------------------------
226
- var logger = log4javascript.getLogger('j1.init');
227
- var url = new liteURL(window.location.href);
228
- var baseUrl = url.origin;
229
- var date = new Date();
230
- var timestamp_now = date.toISOString();
231
- var curr_state = 'started';
233
+ var logger = log4javascript.getLogger('j1.init');
234
+ var url = new liteURL(window.location.href);
235
+ var baseUrl = url.origin;
236
+ var date = new Date();
237
+ var timestamp_now = date.toISOString();
238
+ var curr_state = 'started';
232
239
 
233
240
  // -----------------------------------------------------------------------
234
241
  // options loader
@@ -262,30 +269,46 @@ var j1 = (function () {
262
269
  var url;
263
270
  var baseUrl;
264
271
 
265
- user_state.session_active = false;
266
- user_state.last_session_ts = timestamp_now;
267
-
268
- if (!user_consent.analyses || !user_consent.personalization) {
269
- // expire consent|state cookies to session
270
- j1.writeCookie({
271
- name: cookie_names.user_consent,
272
- data: user_state,
273
- samesite: 'Strict'
274
- });
275
- j1.writeCookie({
276
- name: cookie_names.user_state,
277
- data: user_state,
278
- samesite: 'Strict'
279
- });
272
+ // final update of the user state cookie before browser page|tab
273
+ // get closed
274
+ if (user_state) {
275
+ user_state.session_active = false;
276
+ user_state.last_session_ts = timestamp_now;
277
+
278
+ if (!user_consent.analyses || !user_consent.personalization) {
279
+ // expire consent|state cookies to session
280
+ cookie_written = j1.writeCookie({
281
+ name: cookie_names.user_consent,
282
+ data: user_consent,
283
+ samesite: 'Strict'
284
+ });
285
+ if (!cookie_written) {
286
+ logger.error('failed to write cookie: ' + cookie_names.user_consent);
287
+ }
288
+ cookie_written = j1.writeCookie({
289
+ name: cookie_names.user_state,
290
+ data: user_state,
291
+ samesite: 'Strict'
292
+ });
293
+ if (!cookie_written) {
294
+ logger.error('failed to write cookie: ' + cookie_names.user_consent);
295
+ }
296
+ } else {
297
+ cookie_written = j1.writeCookie({
298
+ name: cookie_names.user_state,
299
+ data: user_state,
300
+ samesite: 'Strict',
301
+ expires: 365
302
+ });
303
+ if (!cookie_written) {
304
+ logger.error('failed to write cookie: ' + cookie_names.user_state);
305
+ }
306
+ }
280
307
  } else {
281
- j1.writeCookie({
282
- name: cookie_names.user_state,
283
- data: user_state,
284
- samesite: 'Strict',
285
- expires: 365
286
- });
308
+ // jadams, 2021-07-11: on beforeunload, a vaild state cookie
309
+ // is expected
310
+ logger.fatal('missing cookie detected: ' + cookie_names.user_state);
287
311
  }
288
-
289
312
  }); // END beforeunload
290
313
 
291
314
  // -----------------------------------------------------------------------
@@ -297,37 +320,57 @@ var j1 = (function () {
297
320
  user_consent = j1.readCookie(cookie_names.user_consent);
298
321
  user_session = j1.existsCookie(cookie_names.user_session)
299
322
  ? j1.readCookie(cookie_names.user_session)
300
- : j1.writeCookie({
323
+ : cookie_written = j1.writeCookie({
301
324
  name: cookie_names.user_session,
302
325
  data: user_session,
303
326
  samesite: 'Strict'
304
327
  });
328
+ if (!cookie_written) {
329
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
330
+ }
305
331
 
306
332
  user_state = j1.existsCookie(cookie_names.user_state)
307
333
  ? j1.readCookie(cookie_names.user_state)
308
- : j1.writeCookie({
334
+ : cookie_written = j1.writeCookie({
309
335
  name: cookie_names.user_state,
310
336
  data: user_state,
311
337
  samesite: 'Strict',
312
338
  expires: 365
313
339
  });
340
+ if (!cookie_written) {
341
+ logger.error('failed to write cookie: ' + cookie_names.user_state);
342
+ }
314
343
 
315
- user_state.session_active = true;
344
+ // jadams, 2021-07-11: Found situation that user_state NOT initialized
345
+ // correctly (user_state == false).
346
+ // TODO: Check if/why user state (cookie NOT created?) NOT initialized
347
+ // for what reason.
348
+ if (!user_state) {
349
+ logger.error('cookie not found: ' + cookie_names.user_state);
350
+ user_state = j1.readCookie(cookie_names.user_state);
351
+ user_state.session_active = true;
352
+ }
316
353
 
317
354
  if (!user_consent.analyses || !user_consent.personalization) {
318
355
  // expire consent|state cookies to session
319
- j1.writeCookie({
356
+ cookie_written = j1.writeCookie({
320
357
  name: cookie_names.user_state,
321
358
  data: user_state,
322
359
  samesite: 'Strict'
323
360
  });
361
+ if (!cookie_written) {
362
+ logger.error('failed to write cookie: ' + cookie_names.user_state);
363
+ }
324
364
  } else {
325
- j1.writeCookie({
365
+ cookie_written = j1.writeCookie({
326
366
  name: cookie_names.user_state,
327
367
  data: user_state,
328
368
  samesite: 'Strict',
329
369
  expires: 365
330
370
  });
371
+ if (!cookie_written) {
372
+ logger.error('failed to write cookie: ' + cookie_names.user_state);
373
+ }
331
374
  }
332
375
 
333
376
  // detect middleware (mode 'app') and update user session cookie
@@ -354,11 +397,16 @@ var j1 = (function () {
354
397
 
355
398
  logger.info(logText);
356
399
  logger.info('update user session cookie');
357
- j1.writeCookie({
400
+ cookie_written = j1.writeCookie({
358
401
  name: cookie_names.user_session,
359
402
  data: user_session,
360
403
  samesite: 'Strict'
361
404
  });
405
+
406
+ if (!cookie_written) {
407
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
408
+ }
409
+
362
410
  j1.setState(curr_state);
363
411
  logger.info('state: ' + j1.getState());
364
412
 
@@ -395,16 +443,20 @@ var j1 = (function () {
395
443
  logText = 'mode detected: ' + user_session.mode;
396
444
 
397
445
  logger.info(logText);
398
- j1.writeCookie({
446
+ cookie_written = j1.writeCookie({
399
447
  name: cookie_names.user_session,
400
448
  data: user_session,
401
449
  samesite: 'Strict'
402
450
  });
451
+ if (!cookie_written) {
452
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
453
+ }
454
+
403
455
  j1.setState(curr_state);
404
456
  logger.info('state: ' + j1.getState());
405
457
  }, detectTimeout);
406
458
  });
407
- } else { // app mode
459
+ } else { // web mode
408
460
  state = 'started';
409
461
  logger.info('state: ' + state);
410
462
  logger.info('page is being initialized');
@@ -450,12 +502,16 @@ var j1 = (function () {
450
502
  }
451
503
 
452
504
  logger.info('update user session cookie');
453
- j1.writeCookie({
505
+ cookie_written = j1.writeCookie({
454
506
  name: cookie_names.user_session,
455
507
  data: user_session,
456
508
  samesite: 'Strict'
457
509
  });
458
510
 
511
+ if (!cookie_written) {
512
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
513
+ }
514
+
459
515
  // NOTE: asynchronous calls should be rewitten to xhrData
460
516
  // initialize page resources for blocks
461
517
  j1.initBanner(settings);
@@ -467,11 +523,14 @@ var j1 = (function () {
467
523
  logger.info(logText);
468
524
 
469
525
  user_session.timestamp = timestamp_now;
470
- j1.writeCookie({
526
+ cookie_written = j1.writeCookie({
471
527
  name: cookie_names.user_session,
472
528
  data: user_session,
473
529
  samesite: 'Strict'
474
530
  });
531
+ if (!cookie_written) {
532
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
533
+ }
475
534
 
476
535
  // -----------------------------------------------------------------------
477
536
  // additional BS helpers from j1.core
@@ -788,11 +847,14 @@ var j1 = (function () {
788
847
  user_session = j1.mergeData(user_session, data);
789
848
 
790
849
  user_session.current_page = current_url.pathname;
791
- j1.writeCookie({
850
+ cookie_written = j1.writeCookie({
792
851
  name: cookie_names.user_session,
793
852
  data: user_session,
794
853
  samesite: 'Strict'
795
854
  });
855
+ if (!cookie_written) {
856
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
857
+ }
796
858
 
797
859
  providerPermissions = user_session.provider_permissions;
798
860
  categoryAllowed = providerPermissions.includes(user_session.page_permission);
@@ -821,6 +883,15 @@ var j1 = (function () {
821
883
  // display page
822
884
  $('#no_flicker').css('display', 'block');
823
885
 
886
+ // NOTE: Placed tracking warning/info here because page may reloaded
887
+ // after cookie consent selection
888
+ //
889
+ if (tracking_enabled && !tracking_id_valid) {
890
+ logger.error('tracking enabled, but invalid tracking id found: ' + tracking_id);
891
+ } else {
892
+ logger.warn('tracking enabled, tracking id found: ' + tracking_id);
893
+ }
894
+
824
895
  // show|hide cookie icon (should MOVED to Cookiebar ???)
825
896
  if (j1.existsCookie(cookie_names.user_consent)) {
826
897
  // Display cookie icon
@@ -898,16 +969,28 @@ var j1 = (function () {
898
969
  // display page
899
970
  $('#no_flicker').css('display', 'block');
900
971
 
972
+ // NOTE: Placed tracking warning/info here because page may reloaded
973
+ // after cookie consent selection
974
+ //
975
+ if (tracking_enabled && !tracking_id_valid) {
976
+ logger.error('tracking enabled, but invalid tracking id found: ' + tracking_id);
977
+ } else {
978
+ logger.warn('tracking enabled, tracking id found: ' + tracking_id);
979
+ }
980
+
901
981
  logger.info('mode detected: web');
902
982
  logger.info('hide signin icon');
903
983
  $('#quickLinksSignInOutButton').css('display', 'none');
904
984
 
905
985
  user_session.current_page = current_url.pathname;
906
- j1.writeCookie({
986
+ cookie_written = j1.writeCookie({
907
987
  name: cookie_names.user_session,
908
988
  data: user_session,
909
989
  samesite: 'Strict'
910
990
  });
991
+ if (!cookie_written) {
992
+ logger.error('failed to write cookie: ' + cookie_names.user_session);
993
+ }
911
994
 
912
995
  // show|hide translator icon (currently NOT supported)
913
996
  // if (translation_enabled) {
@@ -1209,7 +1292,7 @@ var j1 = (function () {
1209
1292
  }, // END xhrData
1210
1293
 
1211
1294
  // -------------------------------------------------------------------------
1212
- // readCookie()
1295
+ // readCookie (Vanilla JS)
1213
1296
  // -------------------------------------------------------------------------
1214
1297
  readCookie: function (name) {
1215
1298
  var data;
@@ -1231,20 +1314,7 @@ var j1 = (function () {
1231
1314
  }, // END readCookie
1232
1315
 
1233
1316
  // -------------------------------------------------------------------------
1234
- // findCookie()
1235
- // Search for cookies (names) in the page header that matches
1236
- // a given regex string. Returns all names found as an array.
1237
- // -------------------------------------------------------------------------
1238
- // See: https://stackoverflow.com/questions/52287989/javascript-cookie-remove-or-delete-with-regex-regular-expression
1239
- // -------------------------------------------------------------------------
1240
- findCookie: function (regex) {
1241
- var r=[];
1242
- document.cookie.replace(new RegExp(regex + "[^= ]*", "g"), function(a){ r.push(a.trim()); });
1243
- return r;
1244
- }, // END findCookie
1245
-
1246
- // -------------------------------------------------------------------------
1247
- // writeCookie()
1317
+ // writeCookie (Cookie lib)
1248
1318
  // Write 'data' to a cookie 'name'. If not exists, the cookie gets
1249
1319
  // created. Returns 'true' if cookie was written, otherwise 'false'.
1250
1320
  // -------------------------------------------------------------------------
@@ -1270,57 +1340,121 @@ var j1 = (function () {
1270
1340
  // context/HTTPS).
1271
1341
  // -------------------------------------------------------------------------
1272
1342
  //
1343
+ // writeCookie: function (options /*name, data, [path, expires, samesite, http_only, secure]*/) {
1344
+ // var defaults = {
1345
+ // data: {},
1346
+ // name: '',
1347
+ // path: '/',
1348
+ // expires: 0,
1349
+ // samesite: 'Lax',
1350
+ // http_only: false,
1351
+ // secure: false
1352
+ // };
1353
+ // var settings = $.extend(defaults, options);
1354
+ // var date = new Date();
1355
+ // var timestamp_now = date.toISOString();
1356
+ // var cookie_data = {};
1357
+ // var data_json;
1358
+ // var data_encoded;
1359
+ //
1360
+ // if (j1.existsCookie(settings.name)) {
1361
+ // cookie_data = j1.readCookie(settings.name);
1362
+ // cookie_data.timestamp = timestamp_now;
1363
+ // cookie_data = j1.mergeData(cookie_data, settings.data);
1364
+ // data_json = JSON.stringify( cookie_data );
1365
+ // data_encoded = window.btoa(data_json);
1366
+ //
1367
+ // if (settings.expires > 0) {
1368
+ // Cookies.set(settings.name, data_encoded, {
1369
+ // expires: settings.expires,
1370
+ // SameSite: settings.samesite
1371
+ // });
1372
+ // } else {
1373
+ // Cookies.set(settings.name, data_encoded, {
1374
+ // SameSite: settings.samesite
1375
+ // });
1376
+ // }
1377
+ // } else {
1378
+ // cookie_data = settings.data;
1379
+ // data_json = JSON.stringify(settings.data);
1380
+ // data_encoded = window.btoa(data_json);
1381
+ //
1382
+ // if (settings.expires > 0) {
1383
+ // Cookies.set(settings.name, data_encoded, {
1384
+ // expires: settings.expires,
1385
+ // SameSite: settings.samesite
1386
+ // });
1387
+ // } else {
1388
+ // Cookies.set(settings.name, data_encoded, {
1389
+ // SameSite: settings.samesite
1390
+ // });
1391
+ // }
1392
+ // }
1393
+ //
1394
+ // if (j1.existsCookie(settings.name)) {
1395
+ // return cookie_data;
1396
+ // } else {
1397
+ // return false;
1398
+ // }
1399
+ //
1400
+ // }, // END writeCookie
1401
+
1402
+
1273
1403
  writeCookie: function (options /*name, data, [path, expires, samesite, http_only, secure]*/) {
1274
1404
  var defaults = {
1275
1405
  data: {},
1276
1406
  name: '',
1277
1407
  path: '/',
1278
1408
  expires: 0,
1279
- samesite: 'Lax',
1409
+ samesite: 'Strict',
1280
1410
  http_only: false,
1281
1411
  secure: false
1282
1412
  };
1283
1413
  var settings = $.extend(defaults, options);
1414
+
1284
1415
  var date = new Date();
1285
1416
  var timestamp_now = date.toISOString();
1286
1417
  var cookie_data = {};
1287
1418
  var data_json;
1288
1419
  var data_encoded;
1420
+ var expires;
1421
+ var stringifiedAttributes = '';
1422
+
1423
+ cookie_data.timestamp = timestamp_now;
1289
1424
 
1290
1425
  if (j1.existsCookie(settings.name)) {
1291
- cookie_data = j1.readCookie(settings.name);
1292
- cookie_data.timestamp = timestamp_now;
1293
- cookie_data = j1.mergeData(cookie_data, settings.data);
1294
- data_json = JSON.stringify( cookie_data );
1295
- data_encoded = window.btoa(data_json);
1296
-
1297
- if (settings.expires > 0) {
1298
- Cookies.set(settings.name, data_encoded, {
1299
- expires: settings.expires,
1300
- SameSite: settings.samesite
1301
- });
1302
- } else {
1303
- Cookies.set(settings.name, data_encoded, {
1304
- SameSite: settings.samesite
1305
- });
1306
- }
1426
+ cookie_data = j1.readCookie(settings.name);
1427
+ cookie_data = j1.mergeData(cookie_data, settings.data);
1428
+ data_json = JSON.stringify( cookie_data );
1429
+ data_encoded = window.btoa(data_json);
1307
1430
  } else {
1308
1431
  cookie_data = settings.data;
1309
1432
  data_json = JSON.stringify(settings.data);
1310
1433
  data_encoded = window.btoa(data_json);
1434
+ }
1311
1435
 
1312
- if (settings.expires > 0) {
1313
- Cookies.set(settings.name, data_encoded, {
1314
- expires: settings.expires,
1315
- SameSite: settings.samesite
1316
- });
1317
- } else {
1318
- Cookies.set(settings.name, data_encoded, {
1319
- SameSite: settings.samesite
1320
- });
1321
- }
1436
+ // if (settings.path !== '/') {
1437
+ stringifiedAttributes += '; ' + 'path=' + settings.path;
1438
+ // }
1439
+
1440
+ if (settings.expires > 0) {
1441
+ settings.expires = new Date(new Date() * 1 + settings.expires * 864e+5);
1442
+ stringifiedAttributes += '; ' + 'expires=' + settings.expires;
1443
+ }
1444
+
1445
+ // if (settings.samesite !== 'Strict') {
1446
+ stringifiedAttributes += '; ' + 'SameSite=' + settings.samesite;
1447
+ // }
1448
+
1449
+ // stringify cookie attributes
1450
+ if (settings.secure) {
1451
+ stringifiedAttributes += '; ' + 'secure=' + settings.secure;
1452
+ // document.cookie = settings.name + '=' + content +'; path=' + settings.path + '; ' + 'SameSite=' + settings.samesite + '; secure';
1322
1453
  }
1323
1454
 
1455
+ // write the cookie
1456
+ document.cookie = settings.name + '=' + data_encoded + stringifiedAttributes;
1457
+
1324
1458
  if (j1.existsCookie(settings.name)) {
1325
1459
  return cookie_data;
1326
1460
  } else {
@@ -1330,63 +1464,116 @@ var j1 = (function () {
1330
1464
  }, // END writeCookie
1331
1465
 
1332
1466
  // -------------------------------------------------------------------------
1333
- // Clears all given cookies by name (except cookies set to httpOnly).
1334
- // For all cookies the expire date is set in the past, those cookies
1335
- // are 'session' cookies. All session cookies are deleted (automatically)
1336
- // by the browser if the last session (browser window) is closed.
1337
- // See: https://stackoverflow.com/questions/179355/clearing-all-cookies-with-javascript
1467
+ // findCookie (Vanilla JS)
1468
+ // Search for cookies (names) in the page header that matches a given
1469
+ // name. Cookie name can be give as full name, like 'j1.user.state', or
1470
+ // as a partial like 'j1'
1471
+ // Returns all names found as an array.
1338
1472
  // -------------------------------------------------------------------------
1339
- removeCookie: function (options /*name [, path]*/) {
1340
- var cookieExists;
1341
- var defaults = {
1342
- name: '',
1343
- path: '/'
1344
- };
1345
- var settings = $.extend(defaults, options);
1473
+ // See: https://stackoverflow.com/questions/52287989/javascript-cookie-remove-or-delete-with-regex-regular-expression
1474
+ // -------------------------------------------------------------------------
1475
+ findCookie: function (name) {
1476
+ var rCookie=[];
1477
+ document.cookie.replace(new RegExp(name + '[^= ]*', 'g'), function(a){ rCookie.push(a.trim()); });
1346
1478
 
1347
- Cookies.remove(settings.name, { path: settings.path });
1479
+ return rCookie;
1480
+ }, // END findCookie
1348
1481
 
1482
+ // -------------------------------------------------------------------------
1483
+ // removeCookie (Vanilla JS)
1484
+ // -------------------------------------------------------------------------
1485
+ // removeCookie: function (options /*name [, path]*/) {
1486
+ // var cookieExists;
1487
+ // var defaults = {
1488
+ // name: '',
1489
+ // path: '/'
1490
+ // };
1491
+ // var settings = $.extend(defaults, options);
1492
+ //
1493
+ // Cookies.remove(settings.name, { path: settings.path });
1494
+ //
1495
+ // }, // END removeCookie
1496
+ removeCookie: function (name) {
1497
+ if (j1.findCookie(name)) {
1498
+ // clear cookie content and set expiry date in the past
1499
+ document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
1500
+ return true;
1501
+ } else {
1502
+ return false;
1503
+ }
1349
1504
  }, // END removeCookie
1350
1505
 
1351
1506
  // -------------------------------------------------------------------------
1352
- // Clears all given cookies by name (except cookies set to httpOnly).
1353
- // For all cookies the expire date is set in the past, those cookies
1354
- // are 'session' cookies. All session cookies are deleted (automatically)
1355
- // by the browser if the last session (browser window) is closed.
1507
+ // expireCookie (Vanilla JS)
1508
+ // Expires given cookies by name except cookies set to httpOnly. For all
1509
+ // cookies the expiry date is REMOVED. This results in cookies are set
1510
+ // to 'session' for the expiry date. All session cookies are deleted
1511
+ // automatically by the browser if the last session (browser tab|window)
1512
+ // is closed.
1513
+ // -------------------------------------------------------------------------
1514
+ // expireCookie() returns 'true' if cookie is set successfully,
1515
+ // otherwise 'false' (e.g NOT found)
1516
+ // -------------------------------------------------------------------------
1517
+ // NOTE:
1356
1518
  // See: https://stackoverflow.com/questions/179355/clearing-all-cookies-with-javascript
1519
+ // NOTE:
1520
+ // There is NO way you could get a trace of Path, Domain and other
1521
+ // attributes of cookies as they are only read by browsers and NOT shown
1522
+ // to JavaScript. For that reason, attributes needs to be set explicitly.
1357
1523
  // -------------------------------------------------------------------------
1358
- deleteCookie: function (name) {
1359
- var all_cookies = document.cookie.split('; ');
1360
-
1361
- if ( name === 'all' ) {
1362
- for (var c = 0; c < all_cookies.length; c++) {
1363
- var d = window.location.hostname.split('.');
1364
- while (d.length > 0) {
1365
- var cookieBase = encodeURIComponent(all_cookies[c].split(';')[0].split('=')[0]) + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain=' + d.join('.') + ' ;path=';
1366
- var p = location.pathname.split('/');
1367
- document.cookie = cookieBase + '/';
1368
- while (p.length > 0) {
1369
- document.cookie = cookieBase + p.join('/');
1370
- p.pop();
1371
- };
1372
- d.shift();
1373
- }
1374
- }
1524
+ expireCookie: function (options /*name [,path, samesite, secure]*/) {
1525
+ var defaults = {
1526
+ path: '/',
1527
+ samesite: 'Strict',
1528
+ secure: false
1529
+ };
1530
+ var settings = $.extend(defaults, options);
1531
+
1532
+ var dc = document.cookie; // all cookies in page
1533
+ var end = dc.length; // default to end of the string
1534
+ var prefix = settings.name + '='; // search string for the cookie name given
1535
+ var begin = dc.indexOf('; ' + prefix);
1536
+ var content = '';
1537
+
1538
+ // collect the cookie content
1539
+ //
1540
+ // found, and not in the first position
1541
+ if (begin !== -1) {
1542
+ // exclude the "; "
1543
+ begin += 2;
1544
+ } else {
1545
+ // see if cookie is in first position
1546
+ begin = dc.indexOf(prefix);
1547
+ // not found at all or found as a portion of another cookie name
1548
+ if (begin === -1 || begin !== 0 ) return false;
1549
+ }
1550
+
1551
+ // if ";" is found somewhere after the prefix position then "end" is
1552
+ // that position, otherwise it defaults to the end of the string
1553
+ if (dc.indexOf(';', begin) !== -1) {
1554
+ end = dc.indexOf(';', begin);
1555
+ }
1556
+
1557
+ // expire cookie to session
1558
+ content = decodeURI(dc.substring(begin + prefix.length, end) ).replace(/"/g, '');
1559
+ if (settings.secure) {
1560
+ document.cookie = settings.name + '=' + content +'; path=' + settings.path + '; ' + 'SameSite=' + settings.samesite + '; secure';
1375
1561
  } else {
1376
- document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
1562
+ document.cookie = settings.name + '=' + content +'; path=' + settings.path + '; ' + 'SameSite=' + settings.samesite;
1377
1563
  }
1378
1564
 
1379
1565
  return true;
1380
- }, // END deleteCookie
1566
+ }, // END expireCookie
1381
1567
 
1382
1568
  // -------------------------------------------------------------------------
1383
- // returns true if a given cookie exists
1569
+ // existsCookie (Vanilla JS)
1570
+ // returns true if a given cookie exists
1384
1571
  // -------------------------------------------------------------------------
1385
1572
  existsCookie: function (name) {
1386
1573
  var dc = document.cookie;
1387
1574
  var prefix = name + '=';
1388
1575
  var begin = dc.indexOf('; ' + prefix);
1389
- var end = dc.length; // default to end of the string
1576
+ var end = dc.length; // default to end of the string
1390
1577
  var cookieExists = false;
1391
1578
  var cookieContent = '';
1392
1579