Browse Source

Fix Youtube videos with strict-origin-when-cross-origin (#6739)

fix-6679-border-radius-props
Artur Arseniev 6 months ago
committed by GitHub
parent
commit
3678fe129e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 20
      packages/core/src/dom_components/model/ComponentVideo.ts
  2. 14
      packages/core/src/dom_components/view/ComponentVideoView.ts
  3. 45
      packages/core/test/specs/dom_components/view/ComponentVideoView.ts

20
packages/core/src/dom_components/model/ComponentVideo.ts

@ -9,6 +9,7 @@ const yt = 'yt';
const vi = 'vi';
const ytnc = 'ytnc';
const defProvider = 'so';
export const YT_REFERRER_POLICY = 'strict-origin-when-cross-origin';
const hasParam = (value: string) => value && value !== '0';
@ -65,6 +66,24 @@ export default class ComponentVideo extends ComponentImage {
}
}
updateProviderAttributes() {
const { provider, attributes = {} } = this.attributes;
const attrs = { ...attributes };
let hasChanges = false;
if (provider === yt || provider === ytnc) {
if (!isDef(attrs.referrerpolicy)) {
attrs.referrerpolicy = YT_REFERRER_POLICY;
hasChanges = true;
}
} else if (attrs.referrerpolicy === YT_REFERRER_POLICY) {
delete attrs.referrerpolicy;
hasChanges = true;
}
hasChanges && this.setAttributes(attrs);
}
/**
* Update traits by provider
* @private
@ -88,6 +107,7 @@ export default class ComponentVideo extends ComponentImage {
traits = this.getSourceTraits();
}
this.updateProviderAttributes();
this.set({ tagName }, { silent: true }); // avoid break in view
// @ts-ignore
this.set({ traits });

14
packages/core/src/dom_components/view/ComponentVideoView.ts

@ -1,4 +1,4 @@
import ComponentVideo from '../model/ComponentVideo';
import ComponentVideo, { YT_REFERRER_POLICY } from '../model/ComponentVideo';
import ComponentImageView from './ComponentImageView';
import ComponentView from './ComponentView';
@ -117,8 +117,7 @@ export default class ComponentVideoView extends ComponentImageView<ComponentVide
renderYoutube() {
const el = document.createElement('iframe');
el.src = this.model.getYoutubeSrc();
el.frameBorder = '0';
el.setAttribute('allowfullscreen', 'true');
this.updateYoutubeAttributes(el);
this.initVideoEl(el);
return el;
}
@ -126,8 +125,7 @@ export default class ComponentVideoView extends ComponentImageView<ComponentVide
renderYoutubeNoCookie() {
var el = document.createElement('iframe');
el.src = this.model.getYoutubeNoCookieSrc();
el.frameBorder = '0';
el.setAttribute('allowfullscreen', 'true');
this.updateYoutubeAttributes(el);
this.initVideoEl(el);
return el;
}
@ -141,6 +139,12 @@ export default class ComponentVideoView extends ComponentImageView<ComponentVide
return el;
}
updateYoutubeAttributes(el: HTMLIFrameElement) {
el.frameBorder = '0';
el.setAttribute('allowfullscreen', 'true');
el.setAttribute('referrerpolicy', YT_REFERRER_POLICY);
}
initVideoEl(el: HTMLElement) {
el.className = this.ppfx + 'no-pointer';
el.style.height = '100%';

45
packages/core/test/specs/dom_components/view/ComponentVideoView.ts

@ -0,0 +1,45 @@
import { setupTestEditor } from '../../../common';
import { YT_REFERRER_POLICY } from '../../../../src/dom_components/model/ComponentVideo';
describe('ComponentVideoView', () => {
const videoId = 'jNQXAC9IVRw';
let testEditor: ReturnType<typeof setupTestEditor>;
beforeEach(() => {
testEditor = setupTestEditor();
});
const appendVideo = (provider: 'yt' | 'ytnc') =>
testEditor.editor.getWrapper()!.append({
type: 'video',
provider,
videoId,
})[0];
afterEach(() => {
testEditor.editor.destroy();
});
describe('YouTube', () => {
test.each([
['yt', 'https://www.youtube.com/embed/'],
['ytnc', 'https://www.youtube-nocookie.com/embed/'],
] as const)('renders %s with the required referrer policy', (provider, srcPrefix) => {
const component = appendVideo(provider);
const iframe = component.getEl()?.querySelector('iframe');
expect(component.getAttributes().referrerpolicy).toEqual(YT_REFERRER_POLICY);
expect(component.toHTML()).toContain(`referrerpolicy="${YT_REFERRER_POLICY}"`);
expect(iframe?.getAttribute('referrerpolicy')).toEqual(YT_REFERRER_POLICY);
expect(iframe?.getAttribute('src')).toContain(srcPrefix);
});
test('removes the default referrer policy when switching away from YouTube', () => {
const component = appendVideo('yt');
component.set('provider', 'vi');
expect(component.getAttributes().referrerpolicy).toBeUndefined();
});
});
});
Loading…
Cancel
Save