-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update `application.mjs` to support multiple cookie banners on a page. Create new Embed Card component. If require cookie not set (or script fails to execute) placeholder image that links to YouTube video will be created. If cookie is set then placeholder will be replaced with a YT embed. Add `lazyEmbedObserver` in `application.mjs`. Embed Card component will only be initialized when the placeholder is in the viewport. This means for a page with lots of embeds, the page the performance hit will be limited if the user doesn't scroll the entire page. Add tests for new Embed Card component.
- Loading branch information
1 parent
b4f7de8
commit f00aa8d
Showing
7 changed files
with
223 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const { ports } = require('../config') | ||
|
||
const { goTo } = require('./helpers/puppeteer.js') | ||
|
||
const cookieParam = { | ||
name: 'design_system_cookies_policy', | ||
value: JSON.stringify({ analytics: null, campaign: null, version: 2 }), | ||
url: `http://localhost:${ports.preview}` | ||
} | ||
|
||
describe('Embed Card', () => { | ||
beforeEach(async () => { | ||
await page.deleteCookie({ | ||
name: cookieParam.name, | ||
url: cookieParam.url | ||
}) | ||
|
||
await page.setJavaScriptEnabled(true) | ||
|
||
await goTo(page, '/community/design-system-day-2024-day-1/') | ||
}) | ||
|
||
it('will render placeholder if cookies not accepted', async () => { | ||
await expect(page.$('.app-embed-card__placeholder')).resolves.not.toBe(null) | ||
}) | ||
|
||
it('will render placeholder if cookies rejected', async () => { | ||
const buttonReject = await page.$( | ||
'div[data-cookie-category="campaign"] .js-cookie-banner-reject' | ||
) | ||
await buttonReject.click() | ||
await expect(page.$('.app-embed-card__placeholder')).resolves.not.toBe(null) | ||
}) | ||
|
||
it('will not render placeholder if cookies accepted', async () => { | ||
const buttonAccept = await page.$( | ||
'div[data-cookie-category="campaign"] .js-cookie-banner-accept' | ||
) | ||
await buttonAccept.click() | ||
|
||
await new Promise((resolve) => setTimeout(resolve, 3000)) | ||
|
||
await expect(page.$('.app-embed-card__placeholder')).resolves.toBe(null) | ||
}) | ||
}) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { getConsentCookie } from './cookie-functions.mjs' | ||
|
||
/** | ||
* Embed Card Youtube functionality | ||
*/ | ||
class EmbedCard { | ||
/** | ||
* @param {Element} $module - HTML element | ||
*/ | ||
constructor($module) { | ||
if ( | ||
!($module instanceof HTMLElement) || | ||
!document.body.classList.contains('govuk-frontend-supported') | ||
) { | ||
return this | ||
} | ||
|
||
this.$module = $module | ||
|
||
this.replacePlaceholder() | ||
} | ||
|
||
/** | ||
* Replace placeholder | ||
* | ||
* Replaces the placeholder with the iframe if cookies are set. | ||
*/ | ||
replacePlaceholder() { | ||
if (this.$module.querySelector('iframe')) { | ||
return | ||
} | ||
|
||
const consentCookie = getConsentCookie() | ||
|
||
if (consentCookie && consentCookie.campaign) { | ||
const placeholder = this.$module.querySelector( | ||
'.app-embed-card__placeholder' | ||
) | ||
const placeholderText = this.$module.querySelector( | ||
'.app-embed-card__placeholder-text' | ||
) | ||
|
||
const title = placeholderText ? placeholderText.textContent : '' | ||
|
||
const ytHref = placeholder.getAttribute('href') | ||
const ytId = ytHref.match( | ||
/(youtu\.be\/|youtube\.com\/(watch\?(.*&)?v=|(embed|v)\/))([^?&"'>]+)/ | ||
)[5] | ||
|
||
const iframe = this.createIframe(ytId, title) | ||
|
||
placeholder.remove() | ||
|
||
const iframeContainer = this.$module.querySelector( | ||
'.app-embed-card__placeholder-iframe-container' | ||
) | ||
iframeContainer.appendChild(iframe) | ||
} | ||
} | ||
|
||
/** | ||
* Create the iframe | ||
* | ||
* Create the iframe for YouTube embed | ||
* | ||
* @param {string} ytId - YouTube ID | ||
* @param {string} title - Title for iFrame (for screen readers) | ||
*/ | ||
createIframe(ytId, title) { | ||
const iframe = document.createElement('IFRAME') | ||
|
||
iframe.setAttribute('src', `https://www.youtube-nocookie.com/embed/${ytId}`) | ||
iframe.setAttribute('width', '560') | ||
iframe.setAttribute('height', '315') | ||
iframe.setAttribute('title', title) | ||
iframe.setAttribute( | ||
'allow', | ||
'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share;' | ||
) | ||
iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin') | ||
iframe.setAttribute('allowfullscreen', 'true') | ||
iframe.setAttribute('frameborder', '0') | ||
|
||
return iframe | ||
} | ||
} | ||
|
||
export default EmbedCard |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.app-embed-card__placeholder-thumb-container { | ||
position: relative; | ||
} | ||
|
||
.app-embed-card__placeholder-thumb-container::before { | ||
content: ""; | ||
position: absolute; | ||
z-index: 1; | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
height: 100%; | ||
background: | ||
url("/images/yt.svg") 50% center / 75px no-repeat, | ||
linear-gradient(transparent, transparent); | ||
background-position: 50% center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{% macro embedCard(params) %} | ||
<div class="govuk-grid-row" data-module="app-embed-card"> | ||
<div class="govuk-grid-column-two-thirds-from-desktop"> | ||
{{- caller() if caller else params.content | safe -}} | ||
<a class="app-embed-card__placeholder" href="https://www.youtube.com/watch?v={{ params.ytId }}"> | ||
<div class="app-embed-card__placeholder-thumb-container"> | ||
<img class="app-image--no-border app-embed-card__placeholder-thumb-image" alt="placeholder for {{ params.title }} youtube embed" src="https://img.youtube.com/vi/{{ params.ytId }}/hqdefault.jpg"> | ||
<span class="app-embed-card__placeholder-text govuk-visually-hidden"> | ||
{{ params.title }} | ||
</span> | ||
</div> | ||
</a> | ||
<div class="app-embed-card__placeholder-iframe-container"></div> | ||
<p> | ||
<a href="{{ params.transcriptHref }}">Read the full transcript</a> | ||
</p> | ||
</div> | ||
<div class="govuk-grid-column-one-third-from-desktop"> | ||
<img class="app-image--no-border" src="{{ params.authorImgSrc }}" alt="{{ params.authorImgAlt }}" role="presentation"> | ||
</div> | ||
</div> | ||
{% endmacro %} |