hr-design-system-handlebars 1.60.0 → 1.60.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.
@@ -0,0 +1,492 @@
1
+ import SettingsCookie from './globalSettingsCookie.subfeature'
2
+ import {
3
+ fireEvent,
4
+ hr$,
5
+ listen,
6
+ loadScript,
7
+ removeScript,
8
+ replaceAnimated,
9
+ requestTimeout,
10
+ getJSONCookie,
11
+ deleteCookie,
12
+ } from 'hrQuery'
13
+
14
+ const ExternalService = function (context) {
15
+ const { options } = context,
16
+ { element: rootElement } = context,
17
+ rootParent = rootElement.parentNode
18
+ let dataPolicyBox = hr$('.js-datapolicy', rootElement)[0]
19
+ const dataPolicyBoxHTML = typeof dataPolicyBox !== 'undefined' ? dataPolicyBox.outerHTML : '',
20
+ contentSettingsButton = hr$('.js-content-settings-button', rootParent)[0],
21
+ embedType = options.embedType,
22
+ dataPolicyCheck = options.dataPolicyCheck || false,
23
+ id = options.id,
24
+ iFrameConfig = options.iFrameConfig,
25
+ isWebview = window.parent.document.documentElement.classList.contains('webview'),
26
+ button = hr$('.js-dataPolicyTeaser__button', rootElement)[0]
27
+
28
+ let acceptButton,
29
+ acceptAlwaysCheckbox = hr$('.js-dataPolicy-acceptPermanentely', rootElement)[0],
30
+ dataPolicySettingsButton = hr$('.js-data-policy-settings-button', rootParent)[0],
31
+ embedCode = options.embedCode,
32
+ iframe,
33
+ settingsCookie,
34
+ isExternalServiceLoaded = false
35
+
36
+ const syncAppOptionsToSettingsCookie = function () {
37
+ if (getJSONCookie('datapolicy')) {
38
+ let dataPolicyCookie = getJSONCookie('datapolicy') || {}
39
+ let objArray = Object.entries(dataPolicyCookie)
40
+ objArray.forEach(([key, value]) => {
41
+ settingsCookie.setCookieForOptions(key, value)
42
+ })
43
+ }
44
+ }
45
+
46
+ const setWhitelistServicesForInitialApp = function () {
47
+ let whitelist = ['ard_mediathek', 'arte_concert', 'arte_concert_new', 'datawrapper_cdn']
48
+ for (let i = 0; i < whitelist.length; ++i) {
49
+ settingsCookie.setCookieForDataPolicy(whitelist[i], true)
50
+ }
51
+ }
52
+
53
+ const embedExternalService = function (callback) {
54
+ $.ajax({
55
+ type: 'GET',
56
+ dataType: 'jsonp',
57
+ url: embedCode,
58
+ headers: { 'Access-Control-Allow-Origin': '*' },
59
+ timeout: 90 * 1000,
60
+ cache: false,
61
+ beforeSend: function () {
62
+ return true
63
+ },
64
+ })
65
+ //Add handlers to be called when the Deferred object is resolved.
66
+ .done(function (data, status, xhr) {
67
+ console.log('Done')
68
+ if (undefined !== callback) {
69
+ replaceAnimated(rootElement, data.html, false, callback)
70
+ alert('boing')
71
+ } else {
72
+ replaceAnimated(rootElement, data.html, false)
73
+ alert('boing, boing')
74
+ }
75
+ })
76
+ //Add handlers to be called when the Deferred object is rejected.
77
+ .fail(function (xhr, errorType, error) {
78
+ //anzeige irgendetwas hat nicht geklappt
79
+ console.log('Fail:' + errorType)
80
+ })
81
+ .always(function () {
82
+ //aufräumen wenn bedarf besteht.
83
+ console.log('Always')
84
+ })
85
+ }
86
+
87
+ const handleDatapolicy = function (event) {
88
+ if (acceptAlwaysCheckbox.checked == true) {
89
+ fireEvent('hr:externalService-activate-' + id)
90
+ settingsCookie.setCookieForOptions(id)
91
+ if (isWebview) {
92
+ settingsCookie.setCookieForDataPolicy(id)
93
+ }
94
+ } else {
95
+ loadServiceWithDataPolicyButton()
96
+ console.log('External Service once loaded - ' + id)
97
+ }
98
+ event.stopPropagation()
99
+ }
100
+ const loadServiceWithDataPolicyButton = function () {
101
+ if (rootElement.children[0].classList.contains('js-datapolicy')) {
102
+ insertExternalService()
103
+ isExternalServiceLoaded = true
104
+ toggleContentSettingsButton()
105
+ }
106
+ }
107
+ const toggleContentSettingsButton = function () {
108
+ if (isExternalServiceLoaded) {
109
+ contentSettingsButton.classList.remove('hideExtButton')
110
+ } else {
111
+ contentSettingsButton.classList.add('hideExtButton')
112
+ }
113
+ console.log('Toggle den Einstellungsbutton außerhalb weil ' + isExternalServiceLoaded)
114
+ }
115
+
116
+ const removeDatapolicyBox = function () {
117
+ rootElement.innerHTML = ''
118
+ rootElement.classList.remove('c-dataPolicy')
119
+ }
120
+
121
+ const initDataPolicy = function () {
122
+ if (dataPolicyCheck) {
123
+ settingsCookie = new SettingsCookie()
124
+ acceptButton = hr$('.js-dataPolicy-accept', rootElement)[0]
125
+ listen('click', handleDatapolicy, acceptButton)
126
+ if (isWebview) {
127
+ if (settingsCookie.isDataPolicyCookieAccepted(id)) {
128
+ loadServiceWithDataPolicyButton()
129
+ } else {
130
+ dataPolicyBox.style.visibility = 'visible'
131
+ }
132
+ } else {
133
+ if (settingsCookie.isSettingsCookieAccepted(id)) {
134
+ loadServiceWithDataPolicyButton()
135
+ } else {
136
+ dataPolicyBox.style.visibility = 'visible'
137
+ }
138
+ }
139
+ listen('hr:externalService-activate-' + id, loadServiceWithDataPolicyButton)
140
+ listen('hr:externalService-deactivate-' + id, removeExternalService)
141
+ } else {
142
+ insertExternalService()
143
+ }
144
+ }
145
+
146
+ const insertExternalService = function () {
147
+ switch (embedType) {
148
+ case 'js':
149
+ switch (id) {
150
+ case 'facebook-post':
151
+ createFacebookEmbed()
152
+ break
153
+ case 'instagram':
154
+ createInstagramEmbed()
155
+ break
156
+ case 'twitter':
157
+ createTwitterEmbed()
158
+ break
159
+ case 'twitter-post':
160
+ createTwitterPostEmbed()
161
+ break
162
+ case 'datawrapper_cdn':
163
+ createDataWrapperEmbed()
164
+ break
165
+ case 'wahlmonitor':
166
+ createWahlEmbed()
167
+ break
168
+ case 'wahlkreiskarte':
169
+ createWahlEmbed()
170
+ break
171
+ default:
172
+ console.error('No JS Config for external service ' + id)
173
+ break
174
+ }
175
+ break
176
+ default:
177
+ loadIframe()
178
+ }
179
+ }
180
+
181
+ const createWahlEmbed = function () {
182
+ let script = document.createElement('script')
183
+ let cleanUrl
184
+ const parts = embedCode.split('*')
185
+ if (parts.length === 2) {
186
+ const params = parts[1].split(' ')
187
+ cleanUrl = parts[0].trim()
188
+ const queryParams = {}
189
+ for (const param of params) {
190
+ const [key, value] = param.split('=')
191
+ queryParams[key] = value
192
+ script.setAttribute(key, queryParams[key])
193
+ }
194
+ }
195
+ script.src = cleanUrl
196
+ script.type = 'text/javascript'
197
+ rootElement.appendChild(script)
198
+ }
199
+
200
+ const createDataWrapperUniqueID = function () {
201
+ return Math.random()
202
+ .toString(36)
203
+ .replace(/[^a-z]+/g, '')
204
+ .substr(2, 10)
205
+ }
206
+ const createDataWrapperEmbed = function () {
207
+ removeDatapolicyBox()
208
+ var uniqueID = createDataWrapperUniqueID()
209
+ if (iFrameConfig.noResponsiveIframe == 'true') {
210
+ var parentDiv = document.createElement('div')
211
+ parentDiv.className = 'copytext__scrollWrapper'
212
+ var div = document.createElement('div')
213
+ if (iFrameConfig.aspectRatio === undefined) {
214
+ div.className = 'noaspect_datawrapper_cdn'
215
+ div.style.height = iFrameConfig.fixedHeight + 'px'
216
+ div.style.width = '100%'
217
+ } else {
218
+ div.className = 'ar--' + iFrameConfig.aspectRatio + ' datawrapper_cdn'
219
+ }
220
+ var iframe = document.createElement('iframe')
221
+ iframe.className = 'ar_iframe datawrapper_cdn'
222
+ iframe.setAttribute('id', 'i_frame')
223
+ iframe.setAttribute('data-isloaded', '0')
224
+ iframe.setAttribute('webkitallowfullscreen', '')
225
+ iframe.setAttribute('mozallowfullscreen', '')
226
+ iframe.setAttribute('allowfullscreen', '')
227
+ iframe.setAttribute('scrolling', 'no')
228
+ iframe.setAttribute('frameborder', '0')
229
+ iframe.src = embedCode
230
+
231
+ div.appendChild(iframe)
232
+ parentDiv.appendChild(div)
233
+ rootElement.appendChild(parentDiv)
234
+ } else {
235
+ var iframe = document.createElement('iframe')
236
+ iframe.className = 'dataWrapper-embed'
237
+ iframe.style.width = '0'
238
+ iframe.style.minWidth = '100% !important'
239
+ iframe.style.border = 'none'
240
+ iframe.setAttribute('webkitallowfullscreen', '')
241
+ iframe.setAttribute('mozallowfullscreen', '')
242
+ iframe.setAttribute('allowfullscreen', '')
243
+ iframe.setAttribute('scrolling', 'no')
244
+ iframe.setAttribute('frameborder', '0')
245
+ iframe.src = embedCode
246
+ iframe.id = 'datawrapper-chart-' + uniqueID
247
+ rootElement.insertBefore(iframe, null)
248
+
249
+ loadScript(
250
+ 'datawrapper-js',
251
+ 'https://static.hr.de/hessenschau/datawrapper/responsiveIframe.js',
252
+ true
253
+ )
254
+ if (iFrameConfig.refreshContent == 'true') {
255
+ var remainingTime
256
+ var timer
257
+ var iframeRefresh = document.getElementById('datawrapper-chart-' + uniqueID)
258
+ var divCounter = document.createElement('div')
259
+ var divOverlay = document.createElement('div')
260
+ var divTextOverlay = document.createElement('div')
261
+ divOverlay.id = 'overlay' + uniqueID
262
+ divOverlay.style.position = 'absolute'
263
+ divOverlay.style.top = '0'
264
+ divOverlay.style.display = 'none'
265
+ divOverlay.style.alignItems = 'center'
266
+ divOverlay.style.justifyContent = 'center'
267
+ divOverlay.style.backgroundColor = '#fff'
268
+ divOverlay.style.width = '100%'
269
+ divOverlay.style.height = 'calc(100% - 36px)'
270
+ divOverlay.style.backgroundColor = '#d8e9f6'
271
+ divTextOverlay.innerHTML = 'Lade Inhalt neu...'
272
+ divTextOverlay.style.backgroundColor = '#005293'
273
+ divTextOverlay.style.padding = '8px'
274
+ divTextOverlay.style.color = '#fff'
275
+ divTextOverlay.style.fontWeight = '800'
276
+ divTextOverlay.style.fontFamily = 'RobotoSlab'
277
+ divTextOverlay.style.borderRadius = '6px 6px 6px 6px'
278
+ divOverlay.appendChild(divTextOverlay)
279
+ divCounter.id = 'counter' + uniqueID
280
+ divCounter.style.backgroundColor = '#006dc1'
281
+ divCounter.style.color = '#fff'
282
+ divCounter.style.fontSize = '12px'
283
+ divCounter.style.padding = '8px'
284
+ divCounter.style.borderRadius = '0 0 4px 4px'
285
+ rootElement.style.position = 'relative'
286
+ rootElement.appendChild(divCounter)
287
+ rootElement.appendChild(divOverlay)
288
+
289
+ const refreshIframe = function () {
290
+ console.log('Reload')
291
+ iframeRefresh.style.opacity = '0'
292
+ iframeRefresh.src =
293
+ iframeRefresh.src.split('?')[0] + '?_=' + new Date().getTime()
294
+ clearInterval(timer)
295
+ }
296
+ const startCountdown = function () {
297
+ remainingTime = Number(iFrameConfig.refreshIntervall)
298
+ setTimeout(function () {
299
+ iframeRefresh.style.opacity = '1'
300
+ document.getElementById('overlay' + uniqueID).style.display = 'none'
301
+ }, 1000)
302
+ timer = setInterval(function () {
303
+ checkTimer()
304
+ }, 1000)
305
+ }
306
+ const checkTimer = function () {
307
+ if (remainingTime >= 0) {
308
+ document.getElementById('counter' + uniqueID).innerHTML =
309
+ 'Dieser Inhalt wird automatisch aktualisiert in ' +
310
+ secondsToTimeString(remainingTime) +
311
+ ' Min.'
312
+ remainingTime -= 1
313
+ if (remainingTime == -1) {
314
+ document.getElementById('overlay' + uniqueID).style.display = 'flex'
315
+ document.getElementById('counter' + uniqueID).innerHTML =
316
+ 'Zeitintervall wird neu gestartet...'
317
+ }
318
+ } else {
319
+ refreshIframe()
320
+ startCountdown()
321
+ }
322
+ }
323
+ const secondsToTimeString = function (seconds) {
324
+ return new Date(seconds * 1000).toISOString().substr(14, 5)
325
+ }
326
+ startCountdown()
327
+ }
328
+ }
329
+ }
330
+
331
+ const createFacebookEmbed = function () {
332
+ loadScript(
333
+ 'facebook-js',
334
+ 'https://connect.facebook.net/de_DE/sdk.js#xfbml=1&version=v3.2',
335
+ true
336
+ )
337
+ var width =
338
+ undefined != rootParent.clientWidth
339
+ ? rootParent.clientWidth > 350
340
+ ? rootParent.clientWidth
341
+ : 'auto'
342
+ : 'auto'
343
+ var div =
344
+ "<div class='fb-post' data-lazy='true' data-width='" +
345
+ width +
346
+ "' data-href='" +
347
+ embedCode +
348
+ "'></div>"
349
+
350
+ replaceAnimated(rootElement, div, false, reloadFacebookEmbed)
351
+ }
352
+
353
+ const reloadFacebookEmbed = function () {
354
+ requestTimeout(function () {
355
+ if (typeof FB != 'undefined') {
356
+ FB.init({
357
+ status: true,
358
+ xfbml: true,
359
+ version: 'v10.0',
360
+ })
361
+ } else {
362
+ reloadFacebookEmbed()
363
+ }
364
+ }, 125)
365
+ }
366
+
367
+ const createInstagramEmbed = function () {
368
+ loadScript('instagram-js', '//www.instagram.com/embed.js', true)
369
+ embedCode = options.embedCode
370
+ var instagramEmbedCode =
371
+ "<blockquote class='instagram-media' data-instgrm-captioned " +
372
+ "data-instgrm-permalink='" +
373
+ embedCode +
374
+ "?utm_source=ig_embed&amp;utm_campaign=loading'" +
375
+ "data-instgrm-version='14'" +
376
+ "style='background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:660px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);' >" +
377
+ '</blockquote>'
378
+ replaceAnimated(rootElement, instagramEmbedCode, false, reloadInstagramEmbed)
379
+ }
380
+
381
+ const reloadInstagramEmbed = function () {
382
+ requestTimeout(function () {
383
+ if (typeof instgrm != 'undefined') {
384
+ instgrm.Embeds.process(rootElement)
385
+ } else {
386
+ reloadInstagramEmbed()
387
+ }
388
+ }, 250)
389
+ }
390
+
391
+ const createTwitterEmbed = function () {
392
+ loadScript('twitter-js', '//platform.twitter.com/widgets.js', true)
393
+ embedExternalService(reloadTwitterWidget)
394
+ }
395
+
396
+ const createTwitterPostEmbed = function () {
397
+ loadScript('twitterpost-js', '//platform.twitter.com/widgets.js', true)
398
+ embedCode = options.embedCode
399
+ var twitterEmbedCode =
400
+ "<blockquote class='twitter-tweet tw-align-center'>" +
401
+ "<a href='" +
402
+ embedCode +
403
+ "'></a>" +
404
+ '</blockquote>'
405
+ replaceAnimated(rootElement, twitterEmbedCode, false, reloadTwitterWidget)
406
+ }
407
+
408
+ const reloadTwitterWidget = function () {
409
+ requestTimeout(function () {
410
+ if (typeof twttr != 'undefined') {
411
+ twttr.widgets.load(rootElement)
412
+ } else {
413
+ reloadTwitterWidget()
414
+ }
415
+ }, 250)
416
+ }
417
+
418
+ const loadIframe = function () {
419
+ console.log('load iframe ' + id)
420
+ iframe =
421
+ "<iframe id='i_frame' data-isloaded='0' src='" +
422
+ embedCode +
423
+ "' frameborder='0' class='" +
424
+ iFrameConfig.heightClass +
425
+ "' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>"
426
+ if (iFrameConfig.aspectRatio) {
427
+ iframe =
428
+ "<div class='copytext__scrollWrapper'><div class='ar--" +
429
+ iFrameConfig.aspectRatio +
430
+ ' ' +
431
+ id +
432
+ "'><iframe id='i_frame' data-isloaded='0' src='" +
433
+ embedCode +
434
+ "' frameborder='0' class='" +
435
+ iFrameConfig.heightClass +
436
+ ' ' +
437
+ id +
438
+ "' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div></div>"
439
+ //TODO Weiche Animation der Inhalte
440
+ } else {
441
+ if (iFrameConfig.fixedHeight) {
442
+ iframe =
443
+ "<div class='copytext__scrollWrapper -fixedHeight' style='height:" +
444
+ iFrameConfig.fixedHeight +
445
+ "px'><iframe data-isloaded='0' src='" +
446
+ embedCode +
447
+ "' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>"
448
+ } else {
449
+ iframe =
450
+ "<div class='copytext__scrollWrapper " +
451
+ id +
452
+ "'><iframe data-isloaded='0' src='" +
453
+ embedCode +
454
+ "' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>"
455
+ }
456
+ }
457
+
458
+ replaceAnimated(rootElement, iframe, false)
459
+ }
460
+
461
+ const removeExternalService = function () {
462
+ replaceAnimated(rootElement, dataPolicyBoxHTML, true, reinitiateDataPolicyBox)
463
+ }
464
+
465
+ const reinitiateDataPolicyBox = function () {
466
+ removeScript('scrbbl-js')
467
+ removeScript('js-wahlergebnis')
468
+ dataPolicyBox = hr$('.js-datapolicy', rootElement)[0]
469
+ dataPolicyBox.style.visibility = 'visible'
470
+ isExternalServiceLoaded = false
471
+ initDataPolicy()
472
+ toggleContentSettingsButton()
473
+ }
474
+ const resetCheckboxForPermanentService = function () {
475
+ /*Die Autocompletion des Browsers merkt sich die Zustände von Formularelementen nach einem Refresh, das wird hier hart zurückgesetzt*/
476
+ var clist = document.getElementsByClassName('js-dataPolicy-acceptPermanentely')
477
+ for (var i = 0; i < clist.length; ++i) {
478
+ clist[i].checked = false
479
+ }
480
+ }
481
+ initDataPolicy()
482
+ resetCheckboxForPermanentService()
483
+ if (isWebview) {
484
+ /*Für die App werden Cookie-Daten des neuen Cookies wieder mit dem alten Cookie synchronisiert */
485
+ syncAppOptionsToSettingsCookie()
486
+ if (!getJSONCookie('datapolicy') || !getJSONCookie('hrSettings')) {
487
+ setWhitelistServicesForInitialApp()
488
+ }
489
+ }
490
+ }
491
+
492
+ export default ExternalService
@@ -0,0 +1,38 @@
1
+ {{!#if this.externalServiceConfig.makeConfigurable}}
2
+
3
+ <!--External-Service-Dummy-->
4
+
5
+ {{!else}}
6
+
7
+ {{#if this.serviceUrl}}
8
+ <div class="clear-both mt-10">
9
+ <span class="sr-only">{{loca "story_externalservice_intro_sr" }}</span>
10
+ {{#if this.externalServiceConfig.embedAsIFrame}}
11
+
12
+ <div class="{{#if this.fixedHeight}}overflow-y-hidden{{else}}overflow-hidden{{/if}}" {{#if this.fixedHeight}}style="height:{{this.fixedHeight}}px;"{{/if}}>
13
+ {{#unless this.fixedHeight}}<div class="ar-{{defaultIfEmpty this.aspectRatio "16x9"}}-DS">{{/unless}}
14
+ <iframe frameborder="0" width="100%" height="100%"
15
+ src="{{{this.serviceUrl}}}" webkitallowfullscreen mozallowfullscreen
16
+ allowfullscreen scrolling='no'>
17
+ </iframe>
18
+ {{#unless this.fixedHeight}}</div>{{/unless}}
19
+ </div>
20
+
21
+ {{else}}
22
+
23
+ <div class="c-externalService__{{this.externalServiceConfig.externalServiceId}} js-load"
24
+ data-hr-external-service='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}", "embedType": "{{this.externalServiceConfig.externalServiceEmbedType}}", "dataPolicyCheck": false, "iFrameConfig":{}}'>
25
+ </div>
26
+
27
+ {{/if}}
28
+
29
+ {{#with this.externalServiceCaption}}
30
+ <div class="py-2.5">
31
+ <span class="text-sm font-copy dark:text-text-dark">{{this}}</span>
32
+ </div>
33
+ {{/with}}
34
+ <span class="sr-only">{{loca "story_externalservice_outro_sr" }}</span>
35
+ </div>
36
+ {{/if}}
37
+
38
+ {{!/if}}