Bug 1733104 - Implement runtime.getFrameId available from content scripts r=robwu
[gecko.git] / toolkit / components / extensions / WebNavigationFrames.jsm
blobe2ee62e026cd029c9f202056645edd2c80f86d58
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 const EXPORTED_SYMBOLS = ["WebNavigationFrames"];
9 /* exported WebNavigationFrames */
11 /**
12  * The FrameDetail object which represents a frame in WebExtensions APIs.
13  *
14  * @typedef  {Object}  FrameDetail
15  * @inner
16  * @property {number}  frameId        - Represents the numeric id which identify the frame in its tab.
17  * @property {number}  parentFrameId  - Represents the numeric id which identify the parent frame.
18  * @property {string}  url            - Represents the current location URL loaded in the frame.
19  * @property {boolean} errorOccurred  - Indicates whether an error is occurred during the last load
20  *                                      happened on this frame (NOT YET SUPPORTED).
21  */
23 /**
24  * Returns the frame ID of the given window. If the window is the
25  * top-level content window, its frame ID is 0. Otherwise, its frame ID
26  * is its outer window ID.
27  *
28  * @param {Window|BrowsingContext} bc - The window to retrieve the frame ID for.
29  * @returns {number}
30  */
31 function getFrameId(bc) {
32   if (!BrowsingContext.isInstance(bc)) {
33     bc = bc.browsingContext;
34   }
35   return bc.parent ? bc.id : 0;
38 /**
39  * Returns the frame ID of the given window's parent.
40  *
41  * @param {Window|BrowsingContext} bc - The window to retrieve the parent frame ID for.
42  * @returns {number}
43  */
44 function getParentFrameId(bc) {
45   if (!BrowsingContext.isInstance(bc)) {
46     bc = bc.browsingContext;
47   }
48   return bc.parent ? getFrameId(bc.parent) : -1;
51 /**
52  * Convert a BrowsingContext into internal FrameDetail json.
53  * @param {BrowsingContext} bc
54  * @returns {FrameDetail}
55  */
56 function getFrameDetail(bc) {
57   return {
58     frameId: getFrameId(bc),
59     parentFrameId: getParentFrameId(bc),
60     url: bc.currentURI?.spec,
61   };
64 var WebNavigationFrames = {
65   getFrame(bc, frameId) {
66     // frameId 0 means the top-level frame; anything else is a child frame.
67     let frame = BrowsingContext.get(frameId || bc.id);
68     if (frame && frame.top === bc) {
69       return getFrameDetail(frame);
70     }
71     return null;
72   },
74   getFrameId,
75   getParentFrameId,
77   getAllFrames(bc) {
78     let frames = [];
80     // Recursively walk the BC tree, find all frames.
81     function visit(bc) {
82       frames.push(bc);
83       bc.children.forEach(visit);
84     }
85     visit(bc);
86     return frames.map(getFrameDetail);
87   },
89   getFromWindow(target) {
90     if (target instanceof Window) {
91       return getFrameId(BrowsingContext.getFromWindow(target));
92     }
93     return -1;
94   },