/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/core/dom/video/index.js
126 строк
4 KB
Viktor Szépe
Fix typos in src/ (#39606)
12 авг 2025, 21:35
Не верифицирован
12 авг 2025, 21:35
fca692e
Код
Авторство
О чём код?
import {devAssertElement} from '#core/assert'; import {tryResolve} from '#core/data-structures/promise'; import {setStyles} from '#core/dom/style'; import {devExpectedError} from '#core/error'; /** * @param {Window} win * @return {Promise<boolean>} */ export function detectIsAutoplaySupported(win) { // To detect autoplay, we create a video element and call play on it, if // `paused` is true after `play()` call, autoplay is supported. Although // this is unintuitive, it works across browsers and is currently the lightest // way to detect autoplay without using a data source. const detectionElement = /** @type {HTMLVideoElement} */ ( win.document.createElement('video') ); // NOTE(aghassemi): We need both attributes and properties due to Chrome and // Safari differences when dealing with non-attached elements. detectionElement.setAttribute('muted', ''); detectionElement.setAttribute('playsinline', ''); detectionElement.setAttribute('webkit-playsinline', ''); detectionElement.setAttribute('height', '0'); detectionElement.setAttribute('width', '0'); detectionElement.muted = true; detectionElement.playsInline = true; /** @type {*} */ (detectionElement)['playsinline'] = true; /** @type {*} */ (detectionElement)['webkitPlaysinline'] = true; setStyles(detectionElement, { position: 'fixed', top: '0', width: '0', height: '0', opacity: '0', }); // Promise wrapped this way to catch both sync throws and async rejections. // More info: https://github.com/tc39/proposal-promise-try playIgnoringError(detectionElement); return Promise.resolve(!detectionElement.paused); } const AUTOPLAY_SUPPORTED_WIN_PROP = '__AMP_AUTOPLAY'; /** * Determines autoplay support. * * Note that even if platform supports autoplay, users or browsers can disable * autoplay to save data / battery. This detects both platform support and * when autoplay has been disabled by the user. * * @param {Window} win * @return {Promise<boolean>} */ export function isAutoplaySupported(win) { if (win[AUTOPLAY_SUPPORTED_WIN_PROP] == null) { win[AUTOPLAY_SUPPORTED_WIN_PROP] = detectIsAutoplaySupported(win); } return /** @type {Promise<boolean>} */ (win[AUTOPLAY_SUPPORTED_WIN_PROP]); } /** * @param {Window} win * @visibleForTesting */ export function resetIsAutoplaySupported(win) { delete win[AUTOPLAY_SUPPORTED_WIN_PROP]; } /** * @param {Element} element * @return {Element} */ export function getInternalVideoElementFor(element) { const el = element.querySelector('video, iframe'); devAssertElement(el); return el; } /** * @typedef {{ * play: (function(boolean): Promise<undefined>|undefined) * }} */ let VideoOrBaseElementPlayableDef; /** * Tries to play the media element, marking any rejected error as an expected * error for reproting. * * @param {HTMLMediaElement|VideoOrBaseElementPlayableDef} element * @param {boolean=} isAutoplay * @return {Promise<void>} */ export function tryPlay(element, isAutoplay) { // Some browsers return undefined, some a boolean, and some a real promise. // Using tryResolve coerces all of those into a real promise. const promise = tryResolve(() => element.play(!!isAutoplay)); // Fork the promise chain to report any rejected error as expected. We don't // return the promise returned by `.catch()` so that we don't // introduce any new microtasks. promise.catch((err) => { devExpectedError('TRYPLAY', err); }); return promise; } /** * Plays the media element, discarding any error without reporting it. * * @param {HTMLMediaElement} element */ export function playIgnoringError(element) { // Some browsers return undefined, some a boolean, and some a real promise. // Using tryResolve coerces all of those into a real promise. tryResolve(() => element.play()).catch(() => { // Empty catch to prevent useless unhandled promise rejection logging. // Play can fail for many reasons such as video getting paused before // play() is finished. // We use events to know the state of the video and do not care about // the success or failure of the play()'s returned promise. }); }