Skip to content

Commit

Permalink
refactor amp/bento video extensions:
Browse files Browse the repository at this point in the history
* brightcove
* jwplayer
* video-iframe
* video
* vimeo
* youtube
  • Loading branch information
kvchari committed Dec 14, 2021
1 parent b8645c9 commit c67efab
Show file tree
Hide file tree
Showing 19 changed files with 437 additions and 223 deletions.
31 changes: 21 additions & 10 deletions extensions/amp-brightcove/1.0/amp-brightcove.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import {
getConsentPolicySharedData,
getConsentPolicyState,
} from '../../../src/consent';
import {BaseElement} from './base-element';
import {CSS} from '../../../build/amp-brightcove-1.0.css';
import {dict} from '#core/types/object';
import {isExperimentOn} from '#experiments';
import {userAssert} from '#utils/log';
import {Services} from '#service';
import {Component, layoutSizeDefined, props, usesShadowDom} from './element';
import {AmpVideoBaseElement} from '../../amp-video/1.0/video-base-element';

/** @const {string} */
const TAG = 'amp-brightcove';

class AmpBrightcove extends BaseElement {
class AmpBrightcove extends AmpVideoBaseElement {
/** @override @nocollapse */
static getPreconnects() {
return ['https://players.brightcove.net'];
Expand Down Expand Up @@ -62,6 +63,24 @@ class AmpBrightcove extends BaseElement {
}
}

/** @override */
AmpBrightcove['Component'] = Component;

/** @override */
AmpBrightcove['props'] = {
...props,
'referrer': {
attrs: ['data-referrer'],
parseAttrs: getReferrerFromElement,
},
};

/** @override */
AmpBrightcove['layoutSizeDefined'] = layoutSizeDefined;

/** @override */
AmpBrightcove['usesShadowDom'] = usesShadowDom;

AMP.extension(TAG, '1.0', (AMP) => {
AMP.registerElement(TAG, AmpBrightcove, CSS);
});
Expand All @@ -77,11 +96,3 @@ function getReferrerFromElement(element) {
)
: undefined;
}

AmpBrightcove['props'] = {
...BaseElement['props'],
'referrer': {
attrs: ['data-referrer'],
parseAttrs: getReferrerFromElement,
},
};
32 changes: 7 additions & 25 deletions extensions/amp-brightcove/1.0/base-element.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
import {BentoBrightcove} from './component';
import {VideoBaseElement} from '../../amp-video/1.0/video-base-element';
import {createParseAttrsWithPrefix} from '#preact/parse-props';
import {BaseElement as BentoVideoBaseElement} from '../../amp-video/1.0/base-element';
import {Component, layoutSizeDefined, props, usesShadowDom} from './element';

export class BaseElement extends VideoBaseElement {}
export class BaseElement extends BentoVideoBaseElement {}

/** @override */
BaseElement['Component'] = BentoBrightcove;
BaseElement['Component'] = Component;

/** @override */
BaseElement['props'] = {
'account': {attr: 'data-account'},
'autoplay': {attr: 'autoplay', type: 'boolean'},
'embed': {attr: 'data-embed', default: 'default'},
'player': {
attrs: ['data-player', 'data-player-id'],
parseAttrs(element) {
const {'player': player, 'playerId': playerId} = element.dataset;
return player || playerId || 'default';
},
},
'playlistId': {attr: 'data-playlist-id'},
'referrer': {attr: 'data-referrer'},
'urlParams': createParseAttrsWithPrefix('data-param-'),
'videoId': {attr: 'data-video-id'},
// TODO(wg-bento): These props have no internal implementation yet.
'dock': {attr: 'dock', media: true},
};
BaseElement['props'] = props;

/** @override */
BaseElement['layoutSizeDefined'] = true;
BaseElement['layoutSizeDefined'] = layoutSizeDefined;

/** @override */
BaseElement['usesShadowDom'] = true;
BaseElement['usesShadowDom'] = usesShadowDom;
25 changes: 25 additions & 0 deletions extensions/amp-brightcove/1.0/element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {createParseAttrsWithPrefix} from '#preact/parse-props';
export {BentoBrightcove as Component} from './component';

export const props = {
'account': {attr: 'data-account'},
'autoplay': {attr: 'autoplay', type: 'boolean'},
'embed': {attr: 'data-embed', default: 'default'},
'player': {
attrs: ['data-player', 'data-player-id'],
parseAttrs(element) {
const {'player': player, 'playerId': playerId} = element.dataset;
return player || playerId || 'default';
},
},
'playlistId': {attr: 'data-playlist-id'},
'referrer': {attr: 'data-referrer'},
'urlParams': createParseAttrsWithPrefix('data-param-'),
'videoId': {attr: 'data-video-id'},
// TODO(wg-bento): These props have no internal implementation yet.
'dock': {attr: 'dock', media: true},
};

export const layoutSizeDefined = true;

export const usesShadowDom = true;
31 changes: 28 additions & 3 deletions extensions/amp-jwplayer/1.0/amp-jwplayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,31 @@ import {isExperimentOn} from '#experiments';

import {userAssert} from '#utils/log';

import {BaseElement} from './base-element';
import {
Component,
getJwplayerProps,
layoutSizeDefined,
loadable,
props,
usesShadowDom,
} from './element';

import {
getConsentMetadata,
getConsentPolicyInfo,
getConsentPolicyState,
} from '../../../src/consent';
import {AmpVideoBaseElement} from '../../amp-video/1.0/video-base-element';

/** @const {string} */
const TAG = 'amp-jwplayer';

/** @implements {../../../src/video-interface.VideoInterface} */
class AmpJwplayer extends BaseElement {
class AmpJwplayer extends AmpVideoBaseElement {
/** @override */
init() {
super.init();

const consentPolicy = this.getConsentPolicy();
if (consentPolicy) {
this.getConsentInfo().then((consentInfo) => {
Expand All @@ -37,7 +47,7 @@ class AmpJwplayer extends BaseElement {
});
}

return super.init();
return getJwplayerProps(this.element);
}

/**
Expand All @@ -63,6 +73,21 @@ class AmpJwplayer extends BaseElement {
}
}

/** @override */
AmpJwplayer['Component'] = Component;

/** @override */
AmpJwplayer['props'] = props;

/** @override */
AmpJwplayer['layoutSizeDefined'] = layoutSizeDefined;

/** @override */
AmpJwplayer['usesShadowDom'] = usesShadowDom;

/** @override */
AmpJwplayer['loadable'] = loadable;

AMP.extension(TAG, '1.0', (AMP) => {
AMP.registerElement(TAG, AmpJwplayer);
});
97 changes: 18 additions & 79 deletions extensions/amp-jwplayer/1.0/base-element.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,32 @@
import {getDataParamsFromAttributes} from '#core/dom';
import {dict} from '#core/types/object';

import {createParseAttrsWithPrefix} from '#preact/parse-props';

import {BentoJwplayer} from './component';

import {VideoBaseElement} from '../../amp-video/1.0/video-base-element';

export class BaseElement extends VideoBaseElement {
import {
Component,
getJwplayerProps,
layoutSizeDefined,
loadable,
props,
usesShadowDom,
} from './element';

import {BaseElement as BentoVideoBaseElement} from '../../amp-video/1.0/base-element';

export class BaseElement extends BentoVideoBaseElement {
/** @override */
init() {
super.init();

return dict({
'queryParams': this.mergeQueryParams(
getDataParamsFromAttributes(this.element, null, /^playerParam(.+)/),
this.element.getAttribute('data-player-querystring')
),
'contentSearch': this.getContextualSearch(
this.element.getAttribute('data-content-search')
),
});
}

/**
* Gets contextual search value
* @param {string} searchVal
* @return {string} contextual search value
*/
getContextualSearch(searchVal) {
if (searchVal !== '__CONTEXTUAL__') {
return searchVal;
}

const {head, title} = this.element.ownerDocument;
const ogTitleElement = head.querySelector('meta[property="og:title"]');
const ogTitle = ogTitleElement
? ogTitleElement.getAttribute('content')
: null;
return ogTitle || title || '';
}

/**
* Merges query params from multiple sources into 1 string
* @param {Object} playerParams
* @param {string} playerQueryString
* @return {string}
*/
mergeQueryParams(playerParams, playerQueryString) {
const addEntries = (acc, entries) => {
for (const entry of entries) {
acc[entry[0]] = entry[1];
}
};
const p1 = new URLSearchParams(playerParams || '');
const p2 = new URLSearchParams(playerQueryString || '');
const params = {};
addEntries(params, p1.entries());
addEntries(params, p2.entries());
return params;
return getJwplayerProps(this.element);
}
}

/** @override */
BaseElement['Component'] = BentoJwplayer;
BaseElement['Component'] = Component;

/** @override */
BaseElement['props'] = {
'playerId': {attr: 'data-player-id'},
'mediaId': {attr: 'data-media-id'},
'playlistId': {attr: 'data-playlist-id'},
'contentRecency': {attr: 'data-content-recency'},
'contentBackfill': {attr: 'data-content-backfill', type: 'boolean'},
'adCustParams': {attr: 'data-ad-cust-params'},
'adMacros': createParseAttrsWithPrefix('data-ad-macro-'),
'config': createParseAttrsWithPrefix('data-config-'),
'autoplay': {attr: 'autoplay', type: 'boolean'},
// TODO(wg-components): Current behavior defaults to loading="auto".
// Refactor to make loading="lazy" as the default.
'loading': {attr: 'data-loading'},
// TODO(wg-bento): These props have no internal implementation yet.
'dock': {attr: 'dock', media: true},
};
BaseElement['props'] = props;

/** @override */
BaseElement['layoutSizeDefined'] = true;
BaseElement['layoutSizeDefined'] = layoutSizeDefined;

/** @override */
BaseElement['usesShadowDom'] = true;
BaseElement['usesShadowDom'] = usesShadowDom;

/** @override */
BaseElement['loadable'] = true;
BaseElement['loadable'] = loadable;
93 changes: 93 additions & 0 deletions extensions/amp-jwplayer/1.0/element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {getDataParamsFromAttributes} from '#core/dom';
import {dict} from '#core/types/object';

import {createParseAttrsWithPrefix} from '#preact/parse-props';
export {BentoJwplayer as Component} from './component';

export const props = {
'playerId': {attr: 'data-player-id'},
'mediaId': {attr: 'data-media-id'},
'playlistId': {attr: 'data-playlist-id'},
'contentRecency': {attr: 'data-content-recency'},
'contentBackfill': {attr: 'data-content-backfill', type: 'boolean'},
'adCustParams': {attr: 'data-ad-cust-params'},
'adMacros': createParseAttrsWithPrefix('data-ad-macro-'),
'config': createParseAttrsWithPrefix('data-config-'),
'autoplay': {attr: 'autoplay', type: 'boolean'},
// TODO(wg-components): Current behavior defaults to loading="auto".
// Refactor to make loading="lazy" as the default.
'loading': {attr: 'data-loading'},
// TODO(wg-bento): These props have no internal implementation yet.
'dock': {attr: 'dock', media: true},
};

export const layoutSizeDefined = true;

export const usesShadowDom = true;

export const loadable = true;

/**
* @param {Element} element
* @return {JsonObject}
*/
export function getJwplayerProps(element) {
return dict({
'queryParams': mergeQueryParams(element),
'contentSearch': getContextualSearch(element),
});
}

/**
* Gets contextual search value
* @param {Element} element
* @return {string} contextual search value
*/
function getContextualSearch(element) {
const searchVal = element.getAttribute('data-content-search');
if (searchVal !== '__CONTEXTUAL__') {
return searchVal;
}

const {head, title} = element.ownerDocument;
const ogTitleElement = head.querySelector('meta[property="og:title"]');
const ogTitle = ogTitleElement
? ogTitleElement.getAttribute('content')
: null;
return ogTitle || title || '';
}

/**
* Merges query params from multiple sources into 1 string
* @param {Element} element
* @return {string}
*/
function mergeQueryParams(element) {
const playerParams = getDataParamsFromAttributes(
element,
null,
/^playerParam(.+)/
);
const playerQueryString = element.getAttribute('data-player-querystring');
return mergeQueryParams_(playerParams, playerQueryString);
}

/**
* Merges query params from multiple sources into 1 string
* @param {Object} playerParams
* @param {string} playerQueryString
* @return {string}
*/
function mergeQueryParams_(playerParams, playerQueryString) {
const addEntries = (acc, entries) => {
for (const entry of entries) {
acc[entry[0]] = entry[1];
}
};
const p1 = new URLSearchParams(playerParams || '');
const p2 = new URLSearchParams(playerQueryString || '');
const params = {};
addEntries(params, p1.entries());
addEntries(params, p2.entries());
return params;
}
Loading

0 comments on commit c67efab

Please sign in to comment.