/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/ad-helper.js
103 строки
3 KB
Shihua Zheng
commit (#39097)
06 июн 2023, 02:37
Не верифицирован
06 июн 2023, 02:37
649e4ac
Код
Авторство
О чём код?
import {computedStyle} from '#core/dom/style'; import {dev} from '#utils/log'; import {getParentWindowFrameElement} from './service-helpers'; const AD_CONTAINER_PROP = '__AMP__AD_CONTAINER'; /** * Tags that are allowed to have fixed positioning * @const {!{[key: string]: boolean}} */ const CONTAINERS = { 'AMP-FX-FLYING-CARPET': true, 'AMP-LIGHTBOX': true, 'AMP-STICKY-AD': true, 'AMP-LIGHTBOX-GALLERY': true, }; /** * Determines if an element is fixed-positioned. * OK to use, because it's only called from onLayoutMeasure * @param {!Element} el * @param {!Window} win * @return {boolean} */ function isPositionFixed(el, win) { const {position} = computedStyle(win, el); // We consider sticky positions as fixed, since they can be fixed. return position == 'fixed' || position == 'sticky'; } /** * @param {!Element} element * @param {!Window} win * @return {boolean} whether the element position is allowed. If the element * belongs to CONTAINERS, it is allowed to be position fixed. * If the element has a position fixed ancestor, it is not allowed. * This should only be called when a layout on the page was just forced * anyway. */ export function isAdPositionAllowed(element, win) { let hasFixedAncestor = false; let containers = 0; let el = element; do { if (CONTAINERS[el.tagName]) { // The containers must not themselves be contained in a fixed-position // element. Continue the search. containers++; hasFixedAncestor = false; } else if (isPositionFixed(dev().assertElement(el), win)) { // Because certain blessed elements may contain a position fixed // container (which contain an ad), we continue to search the // ancestry tree. hasFixedAncestor = true; } el = el.parentElement; } while (el && el.tagName != 'BODY'); return !hasFixedAncestor && containers <= 1; } /** * Returns the blessed container element tagName if the ad is contained by one. * This is called during layout measure. * @param {!Element} element * @return {?string} */ export function getAdContainer(element) { if (element[AD_CONTAINER_PROP] === undefined) { let el = element.parentElement; while (el && el.tagName != 'BODY') { if (CONTAINERS[el.tagName]) { return (element[AD_CONTAINER_PROP] = el.tagName); } el = el.parentElement; } element[AD_CONTAINER_PROP] = null; } return element[AD_CONTAINER_PROP]; } /** * Gets the resource ID of the amp-ad element containing the passed node. * If there is no containing amp-ad tag, then null will be returned. * TODO(jonkeller): Investigate whether non-A4A use case is needed. Issue 11436 * @param {!Element} node * @param {!Window} topWin * @return {?string} */ export function getAmpAdResourceId(node, topWin) { try { const frameParent = getParentWindowFrameElement(node, topWin).parentElement; if (frameParent.nodeName == 'AMP-AD') { return String(frameParent.getResourceId()); } } catch (e) {} // Whether we entered the catch above (e.g. due to attempt to access // across xdomain boundary), or failed to enter the if further above, the // node is not within a friendly amp-ad tag. So, there is no amp-ad // resource ID. How to handle that is up to the caller, but see TODO above. return null; }