|
1428 | 1428 | // eslint-disable-next-line no-global-assign
|
1429 | 1429 | let globalObj = typeof window === 'undefined' ? globalThis : window;
|
1430 | 1430 | let Error$1 = globalObj.Error;
|
| 1431 | + let messageSecret; |
| 1432 | + |
| 1433 | + // save a reference to original CustomEvent amd dispatchEvent so they can't be overriden to forge messages |
| 1434 | + const OriginalCustomEvent = typeof CustomEvent === 'undefined' ? null : CustomEvent; |
| 1435 | + const originalWindowDispatchEvent = typeof window === 'undefined' ? null : window.dispatchEvent; |
| 1436 | + function registerMessageSecret (secret) { |
| 1437 | + messageSecret = secret; |
| 1438 | + } |
1431 | 1439 |
|
1432 | 1440 | function getDataKeySync (sessionKey, domainKey, inputData) {
|
1433 | 1441 | // eslint-disable-next-line new-cap
|
|
1813 | 1821 |
|
1814 | 1822 | function createCustomEvent (eventName, eventDetail) {
|
1815 | 1823 |
|
1816 |
| - return new CustomEvent(eventName, eventDetail) |
| 1824 | + return new OriginalCustomEvent(eventName, eventDetail) |
1817 | 1825 | }
|
1818 | 1826 |
|
1819 | 1827 | function sendMessage (messageType, options) {
|
1820 | 1828 | // FF & Chrome
|
1821 |
| - return window.dispatchEvent(createCustomEvent('sendMessage', { detail: { messageType, options } })) |
| 1829 | + return originalWindowDispatchEvent(createCustomEvent('sendMessageProxy' + messageSecret, { detail: { messageType, options } })) |
1822 | 1830 | // TBD other platforms
|
1823 | 1831 | }
|
1824 | 1832 |
|
|
1899 | 1907 | if (!shouldRun()) {
|
1900 | 1908 | return
|
1901 | 1909 | }
|
| 1910 | + registerMessageSecret(args.messageSecret); |
1902 | 1911 | initStringExemptionLists(args);
|
1903 | 1912 | const resolvedFeatures = await Promise.all(features);
|
1904 | 1913 | resolvedFeatures.forEach(({ init, featureName }) => {
|
|
3106 | 3115 | * @returns {Function?} onError
|
3107 | 3116 | * Function to be called if the video fails to load.
|
3108 | 3117 | */
|
3109 |
| - async adjustYouTubeVideoElement (videoElement) { |
| 3118 | + adjustYouTubeVideoElement (videoElement) { |
3110 | 3119 | let onError = null;
|
3111 | 3120 |
|
3112 | 3121 | if (!videoElement.src) {
|
@@ -3185,100 +3194,103 @@
|
3185 | 3194 | this.isUnblocked = true;
|
3186 | 3195 | clicked = true;
|
3187 | 3196 | let isLogin = false;
|
| 3197 | + const clickElement = e.srcElement; // Object.assign({}, e) |
3188 | 3198 | if (this.replaceSettings.type === 'loginButton') {
|
3189 | 3199 | isLogin = true;
|
3190 | 3200 | }
|
3191 |
| - enableSocialTracker({ entity: this.entity, action: 'block-ctl-fb', isLogin }); |
3192 |
| - const parent = replacementElement.parentNode; |
3193 |
| - |
3194 |
| - // If we allow everything when this element is clicked, |
3195 |
| - // notify surrogate to enable SDK and replace original element. |
3196 |
| - if (this.clickAction.type === 'allowFull') { |
3197 |
| - parent.replaceChild(originalElement, replacementElement); |
3198 |
| - this.dispatchEvent(window, 'ddg-ctp-load-sdk'); |
3199 |
| - return |
3200 |
| - } |
3201 |
| - // Create a container for the new FB element |
3202 |
| - const fbContainer = document.createElement('div'); |
3203 |
| - fbContainer.style.cssText = styles.wrapperDiv; |
3204 |
| - const fadeIn = document.createElement('div'); |
3205 |
| - fadeIn.style.cssText = 'display: none; opacity: 0;'; |
3206 |
| - |
3207 |
| - // Loading animation (FB can take some time to load) |
3208 |
| - const loadingImg = document.createElement('img'); |
3209 |
| - loadingImg.setAttribute('src', loadingImages[this.getMode()]); |
3210 |
| - loadingImg.setAttribute('height', '14px'); |
3211 |
| - loadingImg.style.cssText = styles.loadingImg; |
3212 |
| - |
3213 |
| - // Always add the animation to the button, regardless of click source |
3214 |
| - if (e.srcElement.nodeName === 'BUTTON') { |
3215 |
| - e.srcElement.firstElementChild.insertBefore(loadingImg, e.srcElement.firstElementChild.firstChild); |
3216 |
| - } else { |
3217 |
| - // try to find the button |
3218 |
| - let el = e.srcElement; |
3219 |
| - let button = null; |
3220 |
| - while (button === null && el !== null) { |
3221 |
| - button = el.querySelector('button'); |
3222 |
| - el = el.parentElement; |
| 3201 | + window.addEventListener('ddg-ctp-enableSocialTracker-complete', () => { |
| 3202 | + const parent = replacementElement.parentNode; |
| 3203 | + |
| 3204 | + // If we allow everything when this element is clicked, |
| 3205 | + // notify surrogate to enable SDK and replace original element. |
| 3206 | + if (this.clickAction.type === 'allowFull') { |
| 3207 | + parent.replaceChild(originalElement, replacementElement); |
| 3208 | + this.dispatchEvent(window, 'ddg-ctp-load-sdk'); |
| 3209 | + return |
3223 | 3210 | }
|
3224 |
| - if (button) { |
3225 |
| - button.firstElementChild.insertBefore(loadingImg, button.firstElementChild.firstChild); |
| 3211 | + // Create a container for the new FB element |
| 3212 | + const fbContainer = document.createElement('div'); |
| 3213 | + fbContainer.style.cssText = styles.wrapperDiv; |
| 3214 | + const fadeIn = document.createElement('div'); |
| 3215 | + fadeIn.style.cssText = 'display: none; opacity: 0;'; |
| 3216 | + |
| 3217 | + // Loading animation (FB can take some time to load) |
| 3218 | + const loadingImg = document.createElement('img'); |
| 3219 | + loadingImg.setAttribute('src', loadingImages[this.getMode()]); |
| 3220 | + loadingImg.setAttribute('height', '14px'); |
| 3221 | + loadingImg.style.cssText = styles.loadingImg; |
| 3222 | + |
| 3223 | + // Always add the animation to the button, regardless of click source |
| 3224 | + if (clickElement.nodeName === 'BUTTON') { |
| 3225 | + clickElement.firstElementChild.insertBefore(loadingImg, clickElement.firstElementChild.firstChild); |
| 3226 | + } else { |
| 3227 | + // try to find the button |
| 3228 | + let el = clickElement; |
| 3229 | + let button = null; |
| 3230 | + while (button === null && el !== null) { |
| 3231 | + button = el.querySelector('button'); |
| 3232 | + el = el.parentElement; |
| 3233 | + } |
| 3234 | + if (button) { |
| 3235 | + button.firstElementChild.insertBefore(loadingImg, button.firstElementChild.firstChild); |
| 3236 | + } |
3226 | 3237 | }
|
3227 |
| - } |
3228 | 3238 |
|
3229 |
| - fbContainer.appendChild(fadeIn); |
3230 |
| - |
3231 |
| - let fbElement; |
3232 |
| - let onError = null; |
3233 |
| - switch (this.clickAction.type) { |
3234 |
| - case 'iFrame': |
3235 |
| - fbElement = this.createFBIFrame(); |
3236 |
| - break |
3237 |
| - case 'youtube-video': |
3238 |
| - onError = await this.adjustYouTubeVideoElement(originalElement); |
3239 |
| - fbElement = originalElement; |
3240 |
| - break |
3241 |
| - default: |
3242 |
| - fbElement = originalElement; |
3243 |
| - break |
3244 |
| - } |
| 3239 | + fbContainer.appendChild(fadeIn); |
| 3240 | + |
| 3241 | + let fbElement; |
| 3242 | + let onError = null; |
| 3243 | + switch (this.clickAction.type) { |
| 3244 | + case 'iFrame': |
| 3245 | + fbElement = this.createFBIFrame(); |
| 3246 | + break |
| 3247 | + case 'youtube-video': |
| 3248 | + onError = this.adjustYouTubeVideoElement(originalElement); |
| 3249 | + fbElement = originalElement; |
| 3250 | + break |
| 3251 | + default: |
| 3252 | + fbElement = originalElement; |
| 3253 | + break |
| 3254 | + } |
3245 | 3255 |
|
3246 |
| - // If hidden, restore the tracking element's styles to make |
3247 |
| - // it visible again. |
3248 |
| - if (this.originalElementStyle) { |
3249 |
| - for (const key of ['display', 'visibility']) { |
3250 |
| - const { value, priority } = this.originalElementStyle[key]; |
3251 |
| - if (value) { |
3252 |
| - fbElement.style.setProperty(key, value, priority); |
3253 |
| - } else { |
3254 |
| - fbElement.style.removeProperty(key); |
| 3256 | + // If hidden, restore the tracking element's styles to make |
| 3257 | + // it visible again. |
| 3258 | + if (this.originalElementStyle) { |
| 3259 | + for (const key of ['display', 'visibility']) { |
| 3260 | + const { value, priority } = this.originalElementStyle[key]; |
| 3261 | + if (value) { |
| 3262 | + fbElement.style.setProperty(key, value, priority); |
| 3263 | + } else { |
| 3264 | + fbElement.style.removeProperty(key); |
| 3265 | + } |
3255 | 3266 | }
|
3256 | 3267 | }
|
3257 |
| - } |
3258 | 3268 |
|
3259 |
| - /* |
3260 |
| - * Modify the overlay to include a Facebook iFrame, which |
3261 |
| - * starts invisible. Once loaded, fade out and remove the overlay |
3262 |
| - * then fade in the Facebook content |
3263 |
| - */ |
3264 |
| - parent.replaceChild(fbContainer, replacementElement); |
3265 |
| - fbContainer.appendChild(replacementElement); |
3266 |
| - fadeIn.appendChild(fbElement); |
3267 |
| - fbElement.addEventListener('load', () => { |
3268 |
| - this.fadeOutElement(replacementElement) |
3269 |
| - .then(v => { |
3270 |
| - fbContainer.replaceWith(fbElement); |
3271 |
| - this.dispatchEvent(fbElement, 'ddg-ctp-placeholder-clicked'); |
3272 |
| - this.fadeInElement(fadeIn).then(() => { |
3273 |
| - fbElement.focus(); // focus on new element for screen readers |
| 3269 | + /* |
| 3270 | + * Modify the overlay to include a Facebook iFrame, which |
| 3271 | + * starts invisible. Once loaded, fade out and remove the overlay |
| 3272 | + * then fade in the Facebook content |
| 3273 | + */ |
| 3274 | + parent.replaceChild(fbContainer, replacementElement); |
| 3275 | + fbContainer.appendChild(replacementElement); |
| 3276 | + fadeIn.appendChild(fbElement); |
| 3277 | + fbElement.addEventListener('load', () => { |
| 3278 | + this.fadeOutElement(replacementElement) |
| 3279 | + .then(v => { |
| 3280 | + fbContainer.replaceWith(fbElement); |
| 3281 | + this.dispatchEvent(fbElement, 'ddg-ctp-placeholder-clicked'); |
| 3282 | + this.fadeInElement(fadeIn).then(() => { |
| 3283 | + fbElement.focus(); // focus on new element for screen readers |
| 3284 | + }); |
3274 | 3285 | });
|
3275 |
| - }); |
| 3286 | + }, { once: true }); |
| 3287 | + // Note: This event only fires on Firefox, on Chrome the frame's |
| 3288 | + // load event will always fire. |
| 3289 | + if (onError) { |
| 3290 | + fbElement.addEventListener('error', onError, { once: true }); |
| 3291 | + } |
3276 | 3292 | }, { once: true });
|
3277 |
| - // Note: This event only fires on Firefox, on Chrome the frame's |
3278 |
| - // load event will always fire. |
3279 |
| - if (onError) { |
3280 |
| - fbElement.addEventListener('error', onError, { once: true }); |
3281 |
| - } |
| 3293 | + enableSocialTracker({ entity: this.entity, action: 'block-ctl-fb', isLogin }); |
3282 | 3294 | }
|
3283 | 3295 | }.bind(this);
|
3284 | 3296 | // If this is a login button, show modal if needed
|
|
3319 | 3331 | }, { capture: true });
|
3320 | 3332 |
|
3321 | 3333 | // Inform surrogate scripts that CTP is ready
|
3322 |
| - window.dispatchEvent(createCustomEvent('ddg-ctp-ready')); |
| 3334 | + originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready')); |
3323 | 3335 | }
|
3324 | 3336 |
|
3325 | 3337 | function replaceTrackingElement (widget, trackingElement, placeholderElement, hideTrackingElement = false, currentPlaceholder = null) {
|
|
3512 | 3524 |
|
3513 | 3525 | function runLogin (entity) {
|
3514 | 3526 | enableSocialTracker(entity);
|
3515 |
| - window.dispatchEvent( |
| 3527 | + originalWindowDispatchEvent( |
3516 | 3528 | createCustomEvent('ddg-ctp-run-login', {
|
3517 | 3529 | detail: {
|
3518 | 3530 | entity
|
|
3522 | 3534 | }
|
3523 | 3535 |
|
3524 | 3536 | function cancelModal (entity) {
|
3525 |
| - window.dispatchEvent( |
| 3537 | + originalWindowDispatchEvent( |
3526 | 3538 | createCustomEvent('ddg-ctp-cancel-modal', {
|
3527 | 3539 | detail: {
|
3528 | 3540 | entity
|
|
4001 | 4013 | );
|
4002 | 4014 | previewToggle.addEventListener(
|
4003 | 4015 | 'click',
|
4004 |
| - () => makeModal(widget.entity, () => sendMessage('updateSetting', { |
4005 |
| - name: 'youtubePreviewsEnabled', |
4006 |
| - value: true |
4007 |
| - }), widget.entity) |
| 4016 | + () => makeModal(widget.entity, () => sendMessage('setYoutubePreviewsEnabled', true), widget.entity) |
4008 | 4017 | );
|
4009 | 4018 | bottomRow.appendChild(previewToggle);
|
4010 | 4019 |
|
|
4131 | 4140 | );
|
4132 | 4141 | previewToggle.addEventListener(
|
4133 | 4142 | 'click',
|
4134 |
| - () => sendMessage('updateSetting', { |
| 4143 | + () => sendMessage('setYoutubePreviewsEnabled', { |
4135 | 4144 | name: 'youtubePreviewsEnabled',
|
4136 | 4145 | value: false
|
4137 | 4146 | })
|
|
4194 | 4203 | getYoutubePreviewsEnabled: function (resp) {
|
4195 | 4204 | isYoutubePreviewsEnabled = resp;
|
4196 | 4205 | },
|
4197 |
| - updateSetting: function (resp) { |
| 4206 | + setYoutubePreviewsEnabled: function (resp) { |
4198 | 4207 | if (!resp.messageType || resp.value === undefined) { return }
|
4199 |
| - window.dispatchEvent(new CustomEvent(resp.messageType, { detail: resp.value })); |
| 4208 | + originalWindowDispatchEvent(new OriginalCustomEvent(resp.messageType, { detail: resp.value })); |
4200 | 4209 | },
|
4201 | 4210 | getYouTubeVideoDetails: function (resp) {
|
4202 | 4211 | if (!resp.status || !resp.videoURL) { return }
|
4203 |
| - window.dispatchEvent(new CustomEvent('ddg-ctp-youTubeVideoDetails', { detail: resp })); |
| 4212 | + originalWindowDispatchEvent(new OriginalCustomEvent('ddg-ctp-youTubeVideoDetails', { detail: resp })); |
| 4213 | + }, |
| 4214 | + enableSocialTracker: function (resp) { |
| 4215 | + originalWindowDispatchEvent(new OriginalCustomEvent('ddg-ctp-enableSocialTracker-complete', { detail: resp })); |
4204 | 4216 | }
|
4205 | 4217 | };
|
4206 | 4218 |
|
|
0 commit comments