|
2993 | 2993 | const entities = [];
|
2994 | 2994 | const entityData = {};
|
2995 | 2995 |
|
| 2996 | + let readyResolver; |
| 2997 | + const ready = new Promise(resolve => { readyResolver = resolve; }); |
| 2998 | + |
2996 | 2999 | /*********************************************************
|
2997 | 3000 | * Widget Replacement logic
|
2998 | 3001 | *********************************************************/
|
|
3337 | 3340 | }
|
3338 | 3341 | }
|
3339 | 3342 |
|
3340 |
| - /** |
3341 |
| - * Initialise the Click to Load feature, once the necessary details have been |
3342 |
| - * returned by the platform. |
3343 |
| - * @returns {Promise} |
3344 |
| - */ |
3345 |
| - async function initCTL () { |
3346 |
| - await replaceClickToLoadElements(); |
3347 |
| - |
3348 |
| - window.addEventListener('ddg-ctp-replace-element', ({ target }) => { |
3349 |
| - replaceClickToLoadElements(target); |
3350 |
| - }, { capture: true }); |
3351 |
| - |
3352 |
| - // Inform surrogate scripts that CTP is ready |
3353 |
| - originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready')); |
3354 |
| - } |
3355 |
| - |
3356 | 3343 | function replaceTrackingElement (widget, trackingElement, placeholderElement, hideTrackingElement = false, currentPlaceholder = null) {
|
3357 | 3344 | widget.dispatchEvent(trackingElement, 'ddg-ctp-tracking-element');
|
3358 | 3345 |
|
|
3465 | 3452 | }
|
3466 | 3453 |
|
3467 | 3454 | // Show YouTube Preview for embedded video
|
| 3455 | + // TODO: Fix the hideTrackingElement option and reenable, or remove it. It's |
| 3456 | + // disabled for YouTube videos so far since it caused multiple |
| 3457 | + // placeholders to be displayed on the page. |
3468 | 3458 | if (isYoutubePreviewsEnabled === true) {
|
3469 | 3459 | const { youTubePreview, shadowRoot } = await createYouTubePreview(trackingElement, widget);
|
3470 | 3460 | const currentPlaceholder = togglePlaceholder ? document.getElementById(`yt-ctl-dialog-${widget.widgetID}`) : null;
|
3471 | 3461 | replaceTrackingElement(
|
3472 |
| - widget, trackingElement, youTubePreview, /* hideTrackingElement= */ true, currentPlaceholder |
| 3462 | + widget, trackingElement, youTubePreview, /* hideTrackingElement= */ false, currentPlaceholder |
3473 | 3463 | );
|
3474 | 3464 | showExtraUnblockIfShortPlaceholder(shadowRoot, youTubePreview);
|
3475 | 3465 |
|
|
3479 | 3469 | const { blockingDialog, shadowRoot } = await createYouTubeBlockingDialog(trackingElement, widget);
|
3480 | 3470 | const currentPlaceholder = togglePlaceholder ? document.getElementById(`yt-ctl-preview-${widget.widgetID}`) : null;
|
3481 | 3471 | replaceTrackingElement(
|
3482 |
| - widget, trackingElement, blockingDialog, /* hideTrackingElement= */ true, currentPlaceholder |
| 3472 | + widget, trackingElement, blockingDialog, /* hideTrackingElement= */ false, currentPlaceholder |
3483 | 3473 | );
|
3484 | 3474 | showExtraUnblockIfShortPlaceholder(shadowRoot, blockingDialog);
|
3485 | 3475 | }
|
|
3510 | 3500 | * in the document will be replaced instead.
|
3511 | 3501 | */
|
3512 | 3502 | async function replaceClickToLoadElements (targetElement) {
|
| 3503 | + await ready; |
| 3504 | + |
3513 | 3505 | for (const entity of Object.keys(config)) {
|
3514 | 3506 | for (const widgetData of Object.values(config[entity].elementData)) {
|
3515 | 3507 | const selector = widgetData.selectors.join();
|
|
4285 | 4277 | // Convention is that each function should be named the same as the sendMessage
|
4286 | 4278 | // method we are calling into eg. calling `sendMessage('getClickToLoadState')`
|
4287 | 4279 | // will result in a response routed to `updateHandlers.getClickToLoadState()`.
|
4288 |
| - const updateHandlers = { |
| 4280 | + const messageResponseHandlers = { |
4289 | 4281 | getClickToLoadState (response) {
|
4290 | 4282 | devMode = response.devMode;
|
4291 | 4283 | isYoutubePreviewsEnabled = response.youtubePreviewsEnabled;
|
|
4295 | 4287 | // first.
|
4296 | 4288 |
|
4297 | 4289 | // Start Click to Load
|
4298 |
| - if (document.readyState === 'complete') { |
4299 |
| - initCTL(); |
4300 |
| - } else { |
4301 |
| - // Content script loaded before page content, so wait for load. |
4302 |
| - window.addEventListener('load', (event) => { |
4303 |
| - initCTL(); |
4304 |
| - }); |
4305 |
| - } |
| 4290 | + window.addEventListener('ddg-ctp-replace-element', ({ target }) => { |
| 4291 | + replaceClickToLoadElements(target); |
| 4292 | + }, { capture: true }); |
| 4293 | + |
| 4294 | + // Inform surrogate scripts that CTP is ready |
| 4295 | + originalWindowDispatchEvent(createCustomEvent('ddg-ctp-ready')); |
| 4296 | + |
| 4297 | + // Mark the feature as ready, to allow placeholder replacements. |
| 4298 | + readyResolver(); |
4306 | 4299 | },
|
4307 | 4300 | setYoutubePreviewsEnabled: function (resp) {
|
4308 | 4301 | if (resp?.messageType && typeof resp?.value === 'boolean') {
|
|
4319 | 4312 | }
|
4320 | 4313 | };
|
4321 | 4314 |
|
| 4315 | + const knownMessageResponseType = Object.prototype.hasOwnProperty.bind(messageResponseHandlers); |
| 4316 | + |
4322 | 4317 | function init$f (args) {
|
4323 | 4318 | const websiteOwner = args?.site?.parentEntity;
|
4324 | 4319 | const settings = args?.featureSettings?.clickToPlay || {};
|
|
4384 | 4379 | });
|
4385 | 4380 |
|
4386 | 4381 | // Request the current state of Click to Load from the platform.
|
4387 |
| - // Note: When the response is received, initCTL() is then called by the |
4388 |
| - // response handler to finish starting up the feature. |
| 4382 | + // Note: When the response is received, the response handler finishes |
| 4383 | + // starting up the feature. |
4389 | 4384 | sendMessage('getClickToLoadState');
|
4390 | 4385 | }
|
4391 | 4386 |
|
4392 |
| - function update$1 (args) { |
4393 |
| - const detail = args && args.detail; |
4394 |
| - if (!(detail && detail.func)) { return } |
| 4387 | + function update$1 (message) { |
| 4388 | + // TODO: Once all Click to Load messages include the feature property, drop |
| 4389 | + // messages that don't include the feature property too. |
| 4390 | + if (message?.feature && message?.feature !== 'clickToLoad') return |
4395 | 4391 |
|
4396 |
| - const fn = updateHandlers[detail.func]; |
4397 |
| - if (typeof fn !== 'function') { return } |
| 4392 | + const messageType = message?.messageType; |
| 4393 | + if (!messageType) return |
4398 | 4394 |
|
4399 |
| - fn(detail.response); |
| 4395 | + // Message responses. |
| 4396 | + if (messageType === 'response') { |
| 4397 | + const messageResponseType = message?.responseMessageType; |
| 4398 | + if (messageResponseType && knownMessageResponseType(messageResponseType)) { |
| 4399 | + return messageResponseHandlers[messageResponseType](message.response) |
| 4400 | + } |
| 4401 | + } |
| 4402 | + |
| 4403 | + // Other known update messages. |
| 4404 | + if (messageType === 'displayClickToLoadPlaceholders') { |
| 4405 | + // TODO: Pass `message.options.ruleAction` through, that way only |
| 4406 | + // content corresponding to the entity for that ruleAction need to |
| 4407 | + // be replaced with a placeholder. |
| 4408 | + return replaceClickToLoadElements() |
| 4409 | + } |
4400 | 4410 | }
|
4401 | 4411 |
|
4402 | 4412 | var clickToPlay = /*#__PURE__*/Object.freeze({
|
|
0 commit comments