Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Bento amp-video-iframe #31055

Merged
merged 30 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1bfb403
✨ Bento amp-video-iframe
alanorozco Nov 9, 2020
5ca54e7
Props are specified per component
alanorozco Nov 9, 2020
56c427c
intersection
alanorozco Nov 10, 2020
c22e6ff
dep-check
alanorozco Nov 10, 2020
8cf5d0b
review
alanorozco Nov 19, 2020
69e719e
resolve window
alanorozco Nov 19, 2020
462bfc6
Merge branch 'main' of github.com:ampproject/amphtml into amp-video-i…
alanorozco Apr 22, 2021
62b0d2d
update/review
alanorozco Apr 22, 2021
881d744
optional chaining
alanorozco Apr 22, 2021
e59f3bc
experiment
alanorozco Apr 22, 2021
c32d64e
test
alanorozco Apr 22, 2021
a4db13c
local url
alanorozco Apr 22, 2021
5bf4d3a
Merge branch 'main' of github.com:ampproject/amphtml into amp-video-i…
alanorozco Apr 27, 2021
b0e1046
requires css
alanorozco Apr 27, 2021
8ab71b8
children is a prop
alanorozco Apr 27, 2021
f0e4fc2
VideoIframeWrapper
alanorozco Apr 27, 2021
7af564b
extensions/amp-video-iframe/1.0/component.js
alanorozco Apr 27, 2021
8898fd2
Merge branch 'main' of github.com:ampproject/amphtml into amp-video-i…
alanorozco Apr 29, 2021
30bd4b1
named function
alanorozco Apr 29, 2021
da6862f
add missing css file
alanorozco Apr 29, 2021
1a72b4e
use util
alanorozco Apr 29, 2021
a292b1a
update component hierarchy
alanorozco Apr 29, 2021
b3bb751
dep-check-config
alanorozco Apr 29, 2021
7c2dc3a
remove unused
alanorozco Apr 29, 2021
b51023c
alphabetical
alanorozco Apr 29, 2021
83d4745
Merge branch 'main' of github.com:ampproject/amphtml into amp-video-i…
alanorozco May 3, 2021
8b95817
Sources should be part of base-element
alanorozco May 3, 2021
33dd37a
Revert to props in base element so we can take <source> by default
alanorozco May 3, 2021
e3b341f
share definitions
alanorozco May 3, 2021
806a2f4
correct dep-check-config
alanorozco May 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build-system/compile/bundles.config.extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,12 @@
"options": {"hasCss": true}
},
{"name": "amp-video-iframe", "version": "0.1", "latestVersion": "0.1"},
{
"name": "amp-video-iframe",
"version": "1.0",
"latestVersion": "0.1",
"options": {"hasCss": true}
},
{
"name": "amp-viewer-integration",
"version": "0.1",
Expand Down
2 changes: 2 additions & 0 deletions build-system/compile/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ const CLOSURE_SRC_GLOBS = [
'extensions/amp-user-notification/**/*.js',
// Needed for video components in Bento.
'extensions/amp-video/1.0/**/*.js',
// amp-video-iframe 0.1 and 1.0 share this file.
'extensions/amp-video-iframe/amp-video-iframe-api.js',
// amp-vimeo 0.1 and 1.0 share this file.
'extensions/amp-vimeo/vimeo-api.js',
// Needed to access ConsentPolicyManager from other extensions
Expand Down
16 changes: 11 additions & 5 deletions build-system/test-configs/dep-check-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,24 @@ exports.rules = [
'extensions/amp-facebook-comments/0.1/amp-facebook-comments.js->extensions/amp-facebook/0.1/facebook-loader.js',
'extensions/amp-facebook-comments/1.0/amp-facebook-comments.js->extensions/amp-facebook/0.1/facebook-loader.js',

// Bento AMP Youtube
'extensions/amp-youtube/1.0/base-element.js->extensions/amp-video/1.0/base-element.js',
'extensions/amp-youtube/1.0/component.js->extensions/amp-video/1.0/video-iframe.js',
// Bento VideoIframe, amp-video-iframe
'extensions/amp-video-iframe/1.0/base-element.js->extensions/amp-video/1.0/base-element.js',
'extensions/amp-video-iframe/1.0/component.js->extensions/amp-video/1.0/video-iframe.js',
// Shared definition of the iframe integration API
'extensions/amp-video-iframe/0.1/amp-video-iframe.js->extensions/amp-video-iframe/amp-video-iframe-api.js',
'extensions/amp-video-iframe/1.0/amp-video-iframe.js->extensions/amp-video-iframe/amp-video-iframe-api.js',

// Bento Vimeo
// Bento Vimeo, amp-vimeo
'extensions/amp-vimeo/1.0/base-element.js->extensions/amp-video/1.0/base-element.js',
'extensions/amp-vimeo/1.0/component.js->extensions/amp-video/1.0/video-iframe.js',

// Shared definition of Vimeo API
'extensions/amp-vimeo/0.1/amp-vimeo.js->extensions/amp-vimeo/vimeo-api.js',
'extensions/amp-vimeo/1.0/component.js->extensions/amp-vimeo/vimeo-api.js',

// Bento Youtube, amp-youtube
'extensions/amp-youtube/1.0/base-element.js->extensions/amp-video/1.0/base-element.js',
'extensions/amp-youtube/1.0/component.js->extensions/amp-video/1.0/video-iframe.js',

// Amp geo in group enum
'extensions/amp-a4a/0.1/amp-a4a.js->extensions/amp-geo/0.1/amp-geo-in-group.js',
'extensions/amp-consent/0.1/consent-config.js->extensions/amp-geo/0.1/amp-geo-in-group.js',
Expand Down
17 changes: 2 additions & 15 deletions extensions/amp-video-iframe/0.1/amp-video-iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {BUBBLE_MESSAGE_EVENTS} from '../amp-video-iframe-api';
import {Deferred} from '../../../src/core/data-structures/promise';
import {
MIN_VISIBILITY_RATIO_FOR_AUTOPLAY,
Expand Down Expand Up @@ -62,20 +63,6 @@ const SANDBOX = [
SandboxOptions.ALLOW_TOP_NAVIGATION_BY_USER_ACTIVATION,
];

/**
* Events allowed to be dispatched from messages.
* @private @const
*/
const ALLOWED_EVENTS = [
VideoEvents.PLAYING,
VideoEvents.PAUSE,
VideoEvents.ENDED,
VideoEvents.MUTED,
VideoEvents.UNMUTED,
VideoEvents.AD_START,
VideoEvents.AD_END,
];

/**
* @return {!RegExp}
* @private
Expand Down Expand Up @@ -360,7 +347,7 @@ class AmpVideoIframe extends AMP.BaseElement {
break;
}

if (ALLOWED_EVENTS.indexOf(eventReceived) > -1) {
if (BUBBLE_MESSAGE_EVENTS.indexOf(eventReceived) > -1) {
dispatchCustomEvent(this.element, eventReceived);
return;
}
Expand Down
32 changes: 32 additions & 0 deletions extensions/amp-video-iframe/1.0/amp-video-iframe.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright 2021 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* Pre-upgrade:
* - display:block element
* - size-defined element
*/
amp-video-iframe {
display: block;
overflow: hidden;
position: relative;
}

/* Pre-upgrade: size-defining element - hide children. */
amp-video-iframe:not(.i-amphtml-built) > :not([placeholder]):not(.i-amphtml-svc) {
display: none;
content-visibility: hidden;
}
122 changes: 122 additions & 0 deletions extensions/amp-video-iframe/1.0/amp-video-iframe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {BUBBLE_MESSAGE_EVENTS} from '../amp-video-iframe-api';
import {BaseElement} from './base-element';
import {CSS} from '../../../build/amp-video-iframe-1.0.css';
import {MIN_VISIBILITY_RATIO_FOR_AUTOPLAY} from '../../../src/video-interface';
import {createCustomEvent} from '../../../src/event-helper';
import {dict} from '../../../src/core/types/object';
import {isExperimentOn} from '../../../src/experiments';
import {measureIntersection} from '../../../src/utils/intersection';
import {postMessageWhenAvailable} from '../../../src/iframe-video';
import {userAssert} from '../../../src/log';

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

/**
* @param {!Element} element
* @return {!Promise<number>}
*/
function getIntersectionRatioMinAutoplay(element) {
return measureIntersection(element).then(({intersectionRatio}) =>
// Only post ratio > 0 when in autoplay range to prevent internal
// autoplay implementations that differ from ours.
intersectionRatio < MIN_VISIBILITY_RATIO_FOR_AUTOPLAY
? 0
: intersectionRatio
);
}

class AmpVideoIframe extends BaseElement {
/** @override */
isLayoutSupported(layout) {
userAssert(
isExperimentOn(this.win, 'bento') ||
isExperimentOn(this.win, 'bento-video-iframe'),
'expected global "bento" or specific "bento-video-iframe" experiment to be enabled'
);
return super.isLayoutSupported(layout);
}
}

/**
* @param {!MessageEvent} e
*/
function onMessage(e) {
const {currentTarget} = e;
const method = e.data?.['method'];
const messageId = e.data?.['id'];
if (method) {
if (method == 'getIntersection') {
alanorozco marked this conversation as resolved.
Show resolved Hide resolved
// TODO(alanorozco): Throttle
getIntersectionRatioMinAutoplay(currentTarget).then(
(intersectionRatio) => {
postMessageWhenAvailable(
currentTarget,
JSON.stringify(
dict({
'id': messageId,
'intersectionRatio': intersectionRatio,
})
)
);
}
);
return;
}
throw new Error(`Unknown method ${method}`);
}
const event = e.data?.['event'];
if (!event) {
return;
}
if (event === 'analytics') {
// TODO(alanorozco): In classic AMP, this is an indirect chain of:
// VideoEvents.CUSTOM_TICK -> VideoAnalyticsEvents.CUSTOM.
// VideoManager "massages" the data for this event, adding a prefix.
// Whatever the VideoManager does, needs to be refactored.
return;
}
if (event === 'error' || BUBBLE_MESSAGE_EVENTS.indexOf(event) > -1) {
currentTarget.dispatchEvent(
createCustomEvent(window, event, /* detail */ null, {
bubbles: true,
cancelable: true,
})
);
return;
}
}

/**
* @param {string} method
* @return {string}
*/
const makeMethodMessage = (method) =>
JSON.stringify({
'event': 'method',
'method': method.toLowerCase(),
});

AmpVideoIframe['staticProps'] = dict({
'onMessage': onMessage,
'makeMethodMessage': makeMethodMessage,
});

AMP.extension(TAG, '1.0', (AMP) => {
AMP.registerElement(TAG, AmpVideoIframe, CSS);
});
38 changes: 38 additions & 0 deletions extensions/amp-video-iframe/1.0/base-element.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2021 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {VideoBaseElement} from '../../amp-video/1.0/base-element';
import {VideoIframe} from './component';

export class BaseElement extends VideoBaseElement {}

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

/** @override */
BaseElement['props'] = {
'autoplay': {attr: 'autoplay', type: 'boolean'},
'referrerpolicy': {attr: 'referrerpolicy'},
'implements-media-session': {attr: 'mediasession', type: 'boolean'},
'poster': {attr: 'poster'},
'src': {attr: 'src'},

// TODO(alanorozco): These props have no internal implementation yet.
'dock': {attr: 'dock'},
'rotate-to-fullscreen': {attr: 'rotate-to-fullscreen', type: 'boolean'},
};

/** @override */
BaseElement['usesShadowDom'] = true;
17 changes: 17 additions & 0 deletions extensions/amp-video-iframe/1.0/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright 2021 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export {VideoIframe} from '../../amp-video/1.0/video-iframe';
Loading