Fixes promos remaining hidden

crrev.com/c/2505739 makes the promos hidden by default until it is
decided whether the promo can be shown or not. Promos now remain hidden
until the promo loaded event or a window resize event is fired where
visibility of the promo is recalculated externally based on whether or
not it overlaps with the most-visited tiles.

This change coordinates these two steps by firing the promo loaded event
after the promo's visibility is determined internally. It also uses a
consistent mechanism for controlling the promo's visibility internally
and externally, i.e., 'hidden' attr aka 'display: none;'

Fixed: 1144624, 1143366
Change-Id: I3b2d2d86e56e0baba3f8042077a07aa0b6ce20a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2514667
Reviewed-by: Esmael Elmoslimany <aee@chromium.org>
Commit-Queue: Moe Ahmadi <mahmadi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#823311}
diff --git a/chrome/browser/resources/new_tab_page/app.html b/chrome/browser/resources/new_tab_page/app.html
index 822807b..bf028bb9 100644
--- a/chrome/browser/resources/new_tab_page/app.html
+++ b/chrome/browser/resources/new_tab_page/app.html
@@ -288,7 +288,7 @@
           use-title-pill$="[[theme_.shortcutUseTitlePill]]">
       </ntp-most-visited>
       <ntp-middle-slot-promo
-          on-ntp-middle-slot-promo-loaded="onMiddleSlotPromoLoaded_" hidden>
+          on-ntp-middle-slot-promo-loaded="onMiddleSlotPromoLoaded_">
       </ntp-middle-slot-promo>
       <template is="dom-repeat" items="[[moduleDescriptors_]]" id="modules"
           on-dom-change="onModulesLoaded_">
diff --git a/chrome/browser/resources/new_tab_page/app.js b/chrome/browser/resources/new_tab_page/app.js
index 1c36a47d..b2cf9d9 100644
--- a/chrome/browser/resources/new_tab_page/app.js
+++ b/chrome/browser/resources/new_tab_page/app.js
@@ -869,10 +869,9 @@
     }
     const onResize = () => {
       const promoElement = $$(this, 'ntp-middle-slot-promo');
-      const hidePromo =
+      promoElement.hidden =
           $$(this, '#mostVisited').getBoundingClientRect().bottom >=
           promoElement.offsetTop;
-      promoElement.style.visibility = hidePromo ? 'hidden' : 'visible';
     };
     this.eventTracker_.add(window, 'resize', onResize);
     onResize();
diff --git a/chrome/browser/resources/new_tab_page/middle_slot_promo.js b/chrome/browser/resources/new_tab_page/middle_slot_promo.js
index 4846edb6..45b6fc6 100644
--- a/chrome/browser/resources/new_tab_page/middle_slot_promo.js
+++ b/chrome/browser/resources/new_tab_page/middle_slot_promo.js
@@ -99,10 +99,10 @@
                 BrowserProxy.getInstance().now(), promo.logUrl || null);
             this.hidden = false;
           }
+          this.dispatchEvent(new Event(
+              'ntp-middle-slot-promo-loaded', {bubbles: true, composed: true}));
         });
       }
-      this.dispatchEvent(new Event(
-          'ntp-middle-slot-promo-loaded', {bubbles: true, composed: true}));
     });
   }
 
diff --git a/chrome/test/data/webui/new_tab_page/app_test.js b/chrome/test/data/webui/new_tab_page/app_test.js
index 61dcef5b..260c57ea 100644
--- a/chrome/test/data/webui/new_tab_page/app_test.js
+++ b/chrome/test/data/webui/new_tab_page/app_test.js
@@ -488,6 +488,10 @@
             title: 'Bar Title',
           }
         ]);
+        $$(app, 'ntp-middle-slot-promo')
+            .dispatchEvent(new Event(
+                'ntp-middle-slot-promo-loaded',
+                {bubbles: true, composed: true}));
         testProxy.callbackRouterRemote.setModulesVisible(visible);
         await flushTasks();  // Wait for module descriptor resolution.
 
diff --git a/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js b/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js
index def4d89..6a3feb7 100644
--- a/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js
+++ b/chrome/test/data/webui/new_tab_page/middle_slot_promo_test.js
@@ -62,7 +62,8 @@
 
     const middleSlotPromo = document.createElement('ntp-middle-slot-promo');
     document.body.appendChild(middleSlotPromo);
-    await eventToPromise('ntp-middle-slot-promo-loaded', document.body);
+    const loaded =
+        eventToPromise('ntp-middle-slot-promo-loaded', document.body);
     await promoBrowserCommandTestProxy.handler.whenCalled(
         'canShowPromoWithCommand');
     assertEquals(
@@ -74,6 +75,7 @@
     } else {
       assertEquals(0, testProxy.handler.getCallCount('onPromoRendered'));
     }
+    await loaded;
     return middleSlotPromo;
   }
 
@@ -136,14 +138,17 @@
     }));
   });
 
-  test('sends loaded event if no promo', async () => {
+  test('promo remains hidden if there is no data', async () => {
+    const promoBrowserCommandTestProxy = PromoBrowserCommandProxy.getInstance();
     const testProxy = BrowserProxy.getInstance();
     testProxy.handler.setResultFor('getPromo', Promise.resolve({promo: null}));
-    const loaded =
-        eventToPromise('ntp-middle-slot-promo-loaded', document.body);
     const middleSlotPromo = document.createElement('ntp-middle-slot-promo');
     document.body.appendChild(middleSlotPromo);
-    await loaded;
+    assertEquals(
+        0,
+        promoBrowserCommandTestProxy.handler.getCallCount(
+            'canShowPromoWithCommand'));
+    assertEquals(0, testProxy.handler.getCallCount('onPromoRendered'));
     assertTrue(middleSlotPromo.hasAttribute('hidden'));
   });
 });