FrameManager: add FrameNavigated event and getMainFrames() method

The FrameManager now dispatches a FrameNavigated event on frame
navigation. A method to get all main frames is added as well. Both
will be needed by the application panel's frame tree.

Bug: chromium:1093247

Change-Id: I2ef6877a17c70c1b1e9ba93e24ff2e3bf33500f5
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2277983
Reviewed-by: Sigurd Schneider <[email protected]>
Commit-Queue: Wolfgang Beyer <[email protected]>
diff --git a/front_end/browser_sdk/FrameManager.js b/front_end/browser_sdk/FrameManager.js
index f2c592f..27ddb93 100644
--- a/front_end/browser_sdk/FrameManager.js
+++ b/front_end/browser_sdk/FrameManager.js
@@ -74,7 +74,7 @@
     const frameSet = this._framesForTarget.get(resourceTreeModel.target().id());
     if (frameSet) {
       for (const frameId of frameSet) {
-        this.decreaseOrRemoveFrame(frameId);
+        this._decreaseOrRemoveFrame(frameId);
       }
     }
     this._framesForTarget.delete(resourceTreeModel.target().id());
@@ -108,7 +108,7 @@
   _frameDetached(event) {
     const frame = /** @type {!SDK.ResourceTreeModel.ResourceTreeFrame} */ (event.data);
     // Decrease the frame's count or remove it entirely from the map.
-    this.decreaseOrRemoveFrame(frame.id);
+    this._decreaseOrRemoveFrame(frame.id);
 
     // Remove the frameId from the target's set of frameIds.
     const frameSet = this._framesForTarget.get(frame.resourceTreeModel().target().id());
@@ -122,6 +122,7 @@
    */
   _frameNavigated(event) {
     const frame = /** @type {!SDK.ResourceTreeModel.ResourceTreeFrame} */ (event.data);
+    this.dispatchEventToListeners(Events.FrameNavigated, {frame});
     if (frame.isTopFrame()) {
       this.dispatchEventToListeners(Events.TopFrameNavigated, {frame});
     }
@@ -130,7 +131,7 @@
   /**
    * @param {string} frameId
    */
-  decreaseOrRemoveFrame(frameId) {
+  _decreaseOrRemoveFrame(frameId) {
     const frameData = this._frames.get(frameId);
     if (frameData) {
       if (frameData.count === 1) {
@@ -158,6 +159,19 @@
     }
     return null;
   }
+
+  /**
+   * @return {!Array<!SDK.ResourceTreeModel.ResourceTreeFrame>}
+   */
+  getMainFrames() {
+    const result = [];
+    for (const frameData of this._frames.values()) {
+      if (frameData.frame.isMainFrame()) {
+        result.push(frameData.frame);
+      }
+    }
+    return result;
+  }
 }
 
 /** @enum {symbol} */
@@ -166,6 +180,7 @@
   // This means that for OOPIFs it is sent twice: once when it's added to a
   // parent frame and a second time when it's added to its own frame.
   FrameAddedToTarget: Symbol('FrameAddedToTarget'),
+  FrameNavigated: Symbol('FrameNavigated'),
   // The FrameRemoved event is only sent when a frame has been detached from
   // all targets.
   FrameRemoved: Symbol('FrameRemoved'),
diff --git a/test/unittests/front_end/browser_sdk/FrameManager_test.ts b/test/unittests/front_end/browser_sdk/FrameManager_test.ts
index d12dbdb..11051f0 100644
--- a/test/unittests/front_end/browser_sdk/FrameManager_test.ts
+++ b/test/unittests/front_end/browser_sdk/FrameManager_test.ts
@@ -35,6 +35,8 @@
       id: () => this._targetId,
     }),
   });
+
+  isMainFrame = () => true;
 }
 
 describe('FrameManager', () => {