Commit 69f5c88d authored by Esmael El-Moslimany's avatar Esmael El-Moslimany Committed by Commit Bot

WebUI NTP: fix OneGoogleBar with dynamic bar height

This CL removes the assumption that overlays are visible elements
that extend past 64px (the fixed bar height) because it does not account
for the push-down promo which can increase the height of the bar below
the 64px threshold.

This CL also removes the code that attempts to reduce the number of
overlays that are tracked by trying to find a common parent overlay that
houses child overlay elements.

Bug: b/157846704, b/157136561
Change-Id: Ibb872a4ee1c4d7f146676b124b578fe0ba80a358
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2226634
Commit-Queue: Esmael Elmoslimany <aee@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#774719}
parent 2afc1161
......@@ -312,8 +312,6 @@
<div id="oneGoogleBarOverlayBackdrop"></div>
<svg>
<defs>
<clipPath id="oneGoogleBarClipPath">
<rect x="0" y="0" width="100vw" height="56"></rect>
</clipPath>
<clipPath id="oneGoogleBarClipPath"></clipPath>
</defs>
</svg>
......@@ -618,8 +618,7 @@ class AppElement extends PolymerElement {
BrowserProxy.getInstance().handler.onOneGoogleBarRendered(
BrowserProxy.getInstance().now());
} else if (data.messageType === 'overlaysUpdated') {
this.$.oneGoogleBarClipPath.querySelectorAll('rect:not(:first-child)')
.forEach(el => {
this.$.oneGoogleBarClipPath.querySelectorAll('rect').forEach(el => {
el.remove();
});
const overlayRects = /** @type {!Array<!DOMRect>} */ (data.data);
......
......@@ -2,24 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const oneGoogleBarHeightInPixels = 64;
let modalOverlays = false;
let darkThemeEnabled = false;
let shouldUndoDarkTheme = false;
/**
* @param {boolean} enabled
* @return {!Promise}
*/
async function enableDarkTheme(enabled) {
if (!window.gbar) {
return;
}
darkThemeEnabled = enabled;
const ogb = await window.gbar.a.bf();
ogb.pc.call(ogb, enabled ? 1 : 0);
}
/**
* The following |messageType|'s are sent to the parent frame:
* - loaded: sent on initial load.
......@@ -42,24 +24,58 @@ function postMessage(messageType, data) {
'chrome://new-tab-page');
}
const overlays = new Set();
// Object that exposes:
// - |getEnabled()|: returns whether dark theme is enabled.
// - |setEnabled(value)|: updates whether dark theme is enabled using the
// OneGoogleBar API.
const darkTheme = (() => {
let enabled = false;
function sendOverlayUpdate() {
// Remove overlays detached from DOM or elements in a parent overlay.
Array.from(overlays).forEach(overlay => {
if (!overlay.parentElement) {
overlays.delete(overlay);
/** @return {boolean} */
const getEnabled = () => enabled;
/**
* @param {boolean} value
* @return {!Promise}
*/
const setEnabled = async value => {
if (!window.gbar) {
return;
}
let parent = overlay.parentElement;
while (parent) {
if (overlays.has(parent)) {
enabled = value;
const ogb = await window.gbar.a.bf();
ogb.pc.call(ogb, enabled ? 1 : 0);
};
return {getEnabled, setEnabled};
})();
// Object that exposes:
// - |track()|: sets up MutationObserver to track element visibility changes.
// - |update(potentialNewOverlays)|: determines visibility of tracked elements
// and sends an update to the top frame about element visibility.
const overlayUpdater = (() => {
const modalOverlays = document.documentElement.hasAttribute('modal-overlays');
let shouldUndoDarkTheme = false;
/** @type {!Set<!Element>} */
const overlays = new Set();
/** @param {!Array<!Element>} potentialNewOverlays */
const update = (potentialNewOverlays) => {
Array.from(potentialNewOverlays).forEach(overlay => {
if (overlay.getBoundingClientRect().width > 0) {
overlays.add(overlay);
}
});
// Remove overlays detached from DOM.
Array.from(overlays).forEach(overlay => {
if (!overlay.parentElement) {
overlays.delete(overlay);
return;
}
parent = parent.parentElement;
}
});
const barHeight = document.body.querySelector('#gb').offsetHeight;
// Check if an overlay and its parents are visible.
const overlayRects =
Array.from(overlays)
......@@ -76,7 +92,8 @@ function sendOverlayUpdate() {
}
return true;
})
.map(el => el.getBoundingClientRect());
.map(el => el.getBoundingClientRect())
.filter(rect => !modalOverlays || rect.bottom > barHeight);
if (!modalOverlays) {
postMessage('overlaysUpdated', overlayRects);
return;
......@@ -87,26 +104,26 @@ function sendOverlayUpdate() {
// OneGoogleBar iframe. The dark theme for the OneGoogleBar is then enabled
// for better visibility.
if (overlayShown) {
if (!darkThemeEnabled) {
if (!darkTheme.getEnabled()) {
shouldUndoDarkTheme = true;
enableDarkTheme(true);
darkTheme.setEnabled(true);
}
} else if (shouldUndoDarkTheme) {
shouldUndoDarkTheme = false;
enableDarkTheme(false);
darkTheme.setEnabled(false);
}
}
};
function trackOverlayState() {
const track = () => {
const observer = new MutationObserver(mutations => {
// After loaded, there could exist overlays that are shown, but not mutated.
// Add all elements that could be an overlay. The children of the actual
// overlay element are removed before sending any overlay update message.
if (overlays.size === 0) {
const potentialNewOverlays = [];
// After loaded, there could exist overlays that are shown, but not
// mutated. Add all elements that could be an overlay. The children of the
// actual overlay element are removed before sending any overlay update
// message.
if (!modalOverlays && overlays.size === 0) {
Array.from(document.body.querySelectorAll('*')).forEach(el => {
if (el.offsetTop + el.offsetHeight > oneGoogleBarHeightInPixels) {
overlays.add(el);
}
potentialNewOverlays.push(el);
});
}
// Add any mutated element that is an overlay to |overlays|.
......@@ -121,9 +138,7 @@ function trackOverlayState() {
target.parentElement.tagName === 'BODY') {
return;
}
if (target.offsetTop + target.offsetHeight > oneGoogleBarHeightInPixels) {
overlays.add(target);
}
potentialNewOverlays.push(target);
// Update links that are loaded dynamically to ensure target is "_blank"
// or "_top".
// TODO(crbug.com/1039913): remove after OneGoogleBar links are updated.
......@@ -135,21 +150,32 @@ function trackOverlayState() {
});
}
});
sendOverlayUpdate();
update(potentialNewOverlays);
});
observer.observe(
document, {attributes: true, childList: true, subtree: true});
}
observer.observe(document, {
attributes: true,
childList: true,
subtree: true,
});
if (!modalOverlays) {
update([document.body.querySelector('#gb')]);
}
};
return {track, update};
})();
window.addEventListener('message', ({data}) => {
if (data.type === 'enableDarkTheme') {
enableDarkTheme(data.enabled);
darkTheme.setEnabled(data.enabled);
}
});
// Need to send overlay updates on resize because overlay bounding rects are
// absolutely positioned.
window.addEventListener('resize', sendOverlayUpdate);
window.addEventListener('resize', () => {
overlayUpdater.update([]);
});
// When the account overlay is shown, it does not close on blur. It does close
// when clicking the body.
......@@ -167,5 +193,5 @@ document.addEventListener('DOMContentLoaded', () => {
});
modalOverlays = document.documentElement.hasAttribute('modal-overlays');
postMessage('loaded');
trackOverlayState();
overlayUpdater.track();
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment