Skip to content

Commit

Permalink
feat(aspect-ratio): add css custom prop for changing aspect ratio of …
Browse files Browse the repository at this point in the history
…container (#108)
  • Loading branch information
justinribeiro authored Nov 14, 2024
1 parent 0f8039b commit 60ed512
Show file tree
Hide file tree
Showing 5 changed files with 327 additions and 37 deletions.
51 changes: 51 additions & 0 deletions demo/aspect-ratio.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes"
/>
<title>lite-youtube demo</title>
<script type="module" src="../lite-youtube.js"></script>
<style>
* {
box-sizing: border-box;
}
div {

padding: 1rem;
}
body {
max-width: 800px;
margin: auto;
}
pre {
width: 100%;
padding: 1em;
overflow-x: scroll;
background-clip: z;
background-color: #eee;
}
.styleIt {
width: 400px;
}
#bigBlock {
height: 600px;
}
lite-youtube {
--lite-youtube-aspect-ratio: 2 / 3;
}
</style>
</head>
<body>
<div>
<h3>YouTube Short testing</h3>
<pre>
&lt;style&gt;&#10; lite-youtube {&#10; --lite-youtube-aspect-ratio: 2 / 3;&#10; }&#10;&lt;/style&gt;
&lt;lite-youtube videoid=&quot;vMImN9gghao&quot;&gt;&lt;/lite-youtube&gt;
</pre>
</div>
<lite-youtube videoid="vMImN9gghao"></lite-youtube>
</body>
</html>
6 changes: 4 additions & 2 deletions lite-youtube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,18 @@ export class LiteYTEmbed extends HTMLElement {
shadowDom.innerHTML = `
<style ${nonce}>
:host {
--aspect-ratio: var(--lite-youtube-aspect-ratio, 16 / 9);
--aspect-ratio-short: var(--lite-youtube-aspect-ratio-short, 9 / 16);
contain: content;
display: block;
position: relative;
width: 100%;
padding-bottom: calc(100% / (16 / 9));
aspect-ratio: var(--aspect-ratio);
}
@media (max-width: 40em) {
:host([short]) {
padding-bottom: calc(100% / (9 / 16));
aspect-ratio: var(--aspect-ratio-short);
}
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0",
"istanbul-badges-readme": "^1.9.0",
"mocha": "^10.8.2",
"prettier": "^3.3.3",
"typescript": "^5.6.3"
},
Expand Down
58 changes: 36 additions & 22 deletions test/lite-youtube.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable import/no-duplicates */
import { html, fixture, expect } from '@open-wc/testing';
import { fixtureCleanup } from '@open-wc/testing-helpers';

import { elementUpdated, fixtureCleanup } from '@open-wc/testing-helpers';
import { setViewport } from '@web/test-runner-commands';

import { LiteYTEmbed } from '../lite-youtube.js';
Expand All @@ -12,6 +11,12 @@ const baseTemplate = html`<lite-youtube
videoid="guJLfqTFfIw"
></lite-youtube>`;

const aspectRatioTemplate = html`<lite-youtube
style="--lite-youtube-aspect-ratio: 2 / 3;"
videoTitle="Test Me"
videoid="guJLfqTFfIw"
></lite-youtube>`;

describe('<lite-youtube>', () => {
afterEach(() => {
fixtureCleanup();
Expand Down Expand Up @@ -65,7 +70,7 @@ describe('<lite-youtube>', () => {
expect(el.shadowRoot.querySelector('iframe')).to.be.null;
el.click();
expect(el.shadowRoot.querySelector('iframe')).dom.to.equal(
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>'
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>',
);
});

Expand All @@ -74,13 +79,13 @@ describe('<lite-youtube>', () => {
expect(el.shadowRoot.querySelector('iframe')).to.be.null;
el.click();
expect(el.shadowRoot.querySelector('iframe')).dom.to.equal(
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>'
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>',
);
el.videoId = 'VZ9VSypxhEQ';
expect(el.shadowRoot.querySelector('iframe')).to.be.null;
el.click();
expect(el.shadowRoot.querySelector('iframe')).dom.to.equal(
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/VZ9VSypxhEQ?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>'
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/VZ9VSypxhEQ?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>',
);
});

Expand All @@ -89,19 +94,19 @@ describe('<lite-youtube>', () => {
expect(el.shadowRoot.querySelector('iframe')).to.be.null;
el.click();
expect(el.shadowRoot.querySelector('iframe')).dom.to.equal(
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>'
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>',
);
el.playlistId = 'PL-G5r6j4GptH5JTveoLTVqpp7w2oc27Q9';
expect(el.shadowRoot.querySelector('iframe')).to.be.null;
el.click();
expect(el.shadowRoot.querySelector('iframe')).dom.to.equal(
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/?listType=playlist&amp;list=PL-G5r6j4GptH5JTveoLTVqpp7w2oc27Q9&amp;autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>'
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube.com/embed/?listType=playlist&amp;list=PL-G5r6j4GptH5JTveoLTVqpp7w2oc27Q9&amp;autoplay=1&amp;start=0&amp;null" title="Test Me"></iframe>',
);
});

it('autoload should inject iframe and warm', async () => {
const el = await fixture<LiteYTEmbed>(
html`<lite-youtube videoid="guJLfqTFfIw" autoLoad></lite-youtube>`
html`<lite-youtube videoid="guJLfqTFfIw" autoLoad></lite-youtube>`,
);
// this is a cheeky test by counting the test runner + the warm injector
// TODO write a better observer
Expand All @@ -110,11 +115,11 @@ describe('<lite-youtube>', () => {

it('nocookie attr should change iframe url target', async () => {
const el = await fixture<LiteYTEmbed>(
html`<lite-youtube videoid="guJLfqTFfIw" nocookie></lite-youtube>`
html`<lite-youtube videoid="guJLfqTFfIw" nocookie></lite-youtube>`,
);
el.click();
expect(el.shadowRoot.querySelector('iframe')).dom.to.equal(
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube-nocookie.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Video"></iframe>'
'<iframe frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" src="https://www.youtube-nocookie.com/embed/guJLfqTFfIw?autoplay=1&amp;start=0&amp;null" title="Video"></iframe>',
);
});

Expand All @@ -123,12 +128,12 @@ describe('<lite-youtube>', () => {
html`<lite-youtube
videoid="guJLfqTFfIw"
posterQuality="mqdefault"
></lite-youtube>`
></lite-youtube>`,
);
expect(el.posterQuality).to.be.equal('mqdefault');

const fallback = el.shadowRoot?.querySelector<HTMLImageElement>(
'#fallbackPlaceholder'
'#fallbackPlaceholder',
);
const webp = el.shadowRoot?.querySelector('#webpPlaceholder');
const jpeg = el.shadowRoot?.querySelector('#jpegPlaceholder');
Expand All @@ -143,12 +148,12 @@ describe('<lite-youtube>', () => {
html`<lite-youtube
videoid="guJLfqTFfIw"
posterQuality="mqdefault"
></lite-youtube>`
></lite-youtube>`,
);
expect(el.posterLoading).to.be.equal('lazy');

const fallback = el.shadowRoot?.querySelector<HTMLImageElement>(
'#fallbackPlaceholder'
'#fallbackPlaceholder',
);

expect(fallback?.loading).to.be.equal('lazy');
Expand All @@ -160,28 +165,28 @@ describe('<lite-youtube>', () => {
videoid="guJLfqTFfIw"
posterQuality="mqdefault"
posterloading="eager"
></lite-youtube>`
></lite-youtube>`,
);
expect(el.posterLoading).to.be.equal('eager');

const fallback = el.shadowRoot?.querySelector<HTMLImageElement>(
'#fallbackPlaceholder'
'#fallbackPlaceholder',
);

expect(fallback?.loading).to.be.equal('eager');
});

it('YouTube Short desktop check', async () => {
const el = await fixture<LiteYTEmbed>(
html`<lite-youtube videoid="guJLfqTFfIw" short></lite-youtube>`
html`<lite-youtube videoid="guJLfqTFfIw" short></lite-youtube>`,
);
expect(el['isYouTubeShort']()).to.be.equal(false);
});

it('YouTube Short mobile check', async () => {
setViewport({ width: 360, height: 640 });
const el = await fixture<LiteYTEmbed>(
html`<lite-youtube videoid="guJLfqTFfIw" short></lite-youtube>`
html`<lite-youtube videoid="guJLfqTFfIw" short></lite-youtube>`,
);
el.click();
expect(el['isYouTubeShort']()).to.be.equal(true);
Expand All @@ -190,25 +195,34 @@ describe('<lite-youtube>', () => {
it('check for nonce injector', async () => {
window.liteYouTubeNonce = 'test-abcd1234';
const el = await fixture<LiteYTEmbed>(
html`<lite-youtube videoid="guJLfqTFfIw"></lite-youtube>`
html`<lite-youtube videoid="guJLfqTFfIw"></lite-youtube>`,
);
expect(
el.shadowRoot.querySelector('style')?.getAttribute('nonce')
el.shadowRoot.querySelector('style')?.getAttribute('nonce'),
).to.equal(window.liteYouTubeNonce);
});

it('check global preconnect state', async () => {
const el = await fixture<LiteYTEmbed>(
html`<lite-youtube videoid="guJLfqTFfIw"></lite-youtube>
<lite-youtube videoid="guJLfqTFfIw"></lite-youtube>
<lite-youtube videoid="guJLfqTFfIw"></lite-youtube>`
<lite-youtube videoid="guJLfqTFfIw"></lite-youtube>`,
);
expect(window.liteYouTubeIsPreconnected).to.be.true;
expect(
document.querySelectorAll('head > link[rel=preconnect]').length
document.querySelectorAll('head > link[rel=preconnect]').length,
).to.equal(6);
});

it('is correct aspect-ratio override', async () => {
const el = await fixture<LiteYTEmbed>(aspectRatioTemplate);
await elementUpdated(el);
const aspectRatio = getComputedStyle(el.shadowRoot.host)
.getPropertyValue('--aspect-ratio')
.trim();
await expect(aspectRatio).to.equal('2 / 3');
});

it('is valid A11y via aXe', async () => {
const el = await fixture<LiteYTEmbed>(baseTemplate);
await expect(el).shadowDom.to.be.accessible();
Expand Down
Loading

0 comments on commit 60ed512

Please sign in to comment.