Skip to content

Commit

Permalink
🎭 Refactor overLink status using window actors
Browse files Browse the repository at this point in the history
  • Loading branch information
kierandrewett committed Mar 17, 2024
1 parent b81ac90 commit fbf518a
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 10 deletions.
72 changes: 72 additions & 0 deletions actors/DotLinkStatusChild.sys.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const { setTimeout, clearTimeout } = ChromeUtils.importESModule(
"resource://gre/modules/Timer.sys.mjs"
);

const { BrowserUtils } = ChromeUtils.importESModule(
"resource://gre/modules/BrowserUtils.sys.mjs"
);

export class LinkStatusChild extends JSWindowActorChild {
/**
* The current mouseover href
*/
_currentHref = null;

/**
* The timer before a mouseout event should clear the status
*/
_clearStatusInt = null;

/**
* Handles the over link status
* @param {string} href
*/
handleOverLink(href) {
// Prevent duplicate mouseover events from the
// same href firing multiple overLink events.
if (href && this._currentHref == href) return;

this.sendAsyncMessage("LinkStatus:OverLink", {
href
});

this._currentHref = href;
}

/**
* Handles incoming events to the LinkStatus actor
* @param {Event} event
*/
handleEvent(event) {
clearTimeout(this._clearStatusInt);

const [href, linkNode] =
BrowserUtils.hrefAndLinkNodeForClickEvent(event);

switch (event.type) {
case "mousemove":
this.handleOverLink(href);
break;
case "mouseout":
if (linkNode) {
// Clearing the overLink right after receiving `mouseout` is a bad idea.
//
// We rely on `mouseout` for determining if the mouse left the region
// of a link (for example tabbing out of the window, but leaving the cursor in the same position).
//
// Therefore, adding a timer allows us to bypass clearing overLink
// straight away, if the user happened to move their mouse between
// two links, giving `mousemove` enough time to re-update the href
// before `mouseout` can clear it.
this._clearStatusInt = setTimeout(() => {
this.handleOverLink(null);
}, 10);
}
break;
}
}
}
28 changes: 28 additions & 0 deletions actors/DotLinkStatusParent.sys.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

export class LinkStatusParent extends JSWindowActorParent {
/**
*
* @param {import("third_party/dothq/gecko-types/lib").ReceiveMessageArgument} msg
*/
receiveMessage(msg) {
if (msg.name !== "LinkStatus:OverLink") return;

const { href } = msg.data;

const browser = this.manager.browsingContext.top.embedderElement;
const win = browser.ownerGlobal;

if (!win.gDot) return;

const tab = win.gDot.tabs?.getTabForWebContents(browser);

if (tab) {
win.gDot.status.setTabStatus(tab, "overLink", href);
} else {
win.gDot.status.setStatus("overLink", href);
}
}
}
2 changes: 2 additions & 0 deletions actors/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ FINAL_TARGET_FILES.actors += [
"DotDevToolsChild.sys.mjs",
"DotGeckoCommandsChild.sys.mjs",
"DotLinkHandlerParent.sys.mjs",
"DotLinkStatusChild.sys.mjs",
"DotLinkStatusParent.sys.mjs",
"DotPromptParent.sys.mjs",
"DotTooltipListenerChild.sys.mjs",
"DotUAStylesChild.sys.mjs",
Expand Down
16 changes: 16 additions & 0 deletions components/DotGlue.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ const JSWINDOWACTORS = {
messageManagerGroups: ["browsers"]
},

LinkStatus: {
parent: {
esModuleURI: "resource:///actors/DotLinkStatusParent.sys.mjs"
},

child: {
esModuleURI: "resource:///actors/DotLinkStatusChild.sys.mjs",
events: {
mousemove: { capture: true, mozSystemGroup: true },
mouseout: { capture: true, mozSystemGroup: true }
}
},

allFrames: true
},

PageInfo: {
child: {
esModuleURI: "resource:///actors/PageInfoChild.sys.mjs"
Expand Down
11 changes: 1 addition & 10 deletions components/XULBrowserWindow.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ export class XULBrowserWindow {

status = "";
defaultStatus = "";
overLink = "";
startTime = 0;
isBusy = false;
busyUI = false;
hideOverLinkImmediately = false;

_state = null;
_lastLocation = null;
Expand All @@ -36,8 +34,6 @@ export class XULBrowserWindow {
// with the the HTTPS-Only Mode error page (more details in bug 1656027)
_isSecureContext = null;

_overlinkInt;

QueryInterface = ChromeUtils.generateQI([
"nsIWebProgressListener",
"nsIWebProgressListener2",
Expand Down Expand Up @@ -81,12 +77,7 @@ export class XULBrowserWindow {
* @param {string} url
*/
setOverLink(url) {
clearTimeout(this._overlinkInt);

this._overlinkInt = setTimeout(() => {
console.log("todo: rewrite to use actor");
this.#win.gDot.status.setStatus("overLink", url);
}, 100);
// noop: Handled by LinkStatus actor
}

/**
Expand Down
3 changes: 3 additions & 0 deletions third_party/dothq/gecko-types/lib/WindowGlobalParent.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

import { BrowsingContext } from "./BrowsingContext";
import { FrameLoader } from "./FrameLoader";
import { JSWindowActorParent } from "./JSWindowActorParent";
import { WindowGlobalChild } from "./WindowGlobalChild";
Expand All @@ -17,6 +18,8 @@ export interface WindowGlobalParentInstance {
readonly rootFrameLoader?: FrameLoader;
readonly childActor?: WindowGlobalChild;

readonly browsingContext: BrowsingContext;

/**
* Checks for any WindowContexts with "beforeunload" listeners in this
* WindowGlobal's subtree. If any exist, a "beforeunload" event is
Expand Down

0 comments on commit fbf518a

Please sign in to comment.