Skip to content

Commit 03d74be

Browse files
committed
[frontend] improve contextmenu and make it work with nested iframes
1 parent a69cdca commit 03d74be

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

frontend/src/Menu.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ export const Menu: Component<{
2323
},
2424
{ once: true }
2525
);
26+
document.body.addEventListener(
27+
"contextmenu",
28+
() => {
29+
cx.root.remove();
30+
browser.unfocusframes = false;
31+
},
32+
{ once: true }
33+
);
2634

2735
cx.root.addEventListener("click", (e) => {
2836
e.stopPropagation();
@@ -46,9 +54,19 @@ Menu.css = `
4654
border-radius: 4px;
4755
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
4856
z-index: 1000;
49-
padding: 8px;
5057
display: flex;
5158
flex-direction: column;
59+
min-width: 10em;
60+
}
61+
button {
62+
background: none;
63+
border: none;
64+
font-size: 0.8em;
65+
padding: 1em;
66+
text-align: left;
67+
}
68+
button:hover {
69+
background: #f0f0f0;
5270
}
5371
`;
5472

frontend/src/browser.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,52 @@ export class Browser extends StatefulClass {
6969
frame.frame.addEventListener("load", (e) => {
7070
tab.url = frame.client.url.href;
7171
});
72-
frame.addEventListener("contextInit", (e) => {
73-
const framedoc = frame.frame.contentDocument!;
72+
frame.addEventListener("contextInit", (ctx) => {
73+
const framedoc = ctx.window.document;
7474

7575
framedoc.addEventListener("contextmenu", (e) => {
76-
createMenu(e.x, e.y, [
76+
// need to calculate the real position of the frame relative to the top
77+
let xoff = 0;
78+
let yoff = 0;
79+
let currentwin = ctx.window;
80+
while (currentwin.parent && currentwin.frameElement) {
81+
// this will return true until the end of the scramjet boundary
82+
let { x, y } = currentwin.frameElement.getBoundingClientRect();
83+
xoff += x;
84+
yoff += y;
85+
currentwin = currentwin.parent;
86+
}
87+
// parent is trapped, so it won't calculate the topmost iframe. do that manually
88+
let { x, y } = frame.frame.getBoundingClientRect();
89+
xoff += x;
90+
yoff += y;
91+
createMenu(xoff + e.pageX, yoff + e.pageY, [
92+
{
93+
label: "Back",
94+
action: () => {
95+
frame.back();
96+
},
97+
},
98+
{
99+
label: "Forward",
100+
action: () => {
101+
frame.forward();
102+
},
103+
},
104+
{
105+
label: "Reload",
106+
action: () => {
107+
frame.reload();
108+
},
109+
},
77110
{
78-
label: "??",
111+
label: "Bookmark",
112+
action: () => {
113+
console.log("Bookmarking", tab.title, tab.url);
114+
},
79115
},
80116
]);
117+
e.preventDefault();
81118
});
82119
const head = framedoc.querySelector("head")!;
83120
const observer = new MutationObserver(() => {

frontend/src/main.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ try {
4242
built.id = "app";
4343

4444
app.replaceWith(built);
45+
built.addEventListener("contextmenu", (e) => {
46+
e.preventDefault();
47+
});
4548
} catch (e) {
4649
let err = e as any;
4750
app.replaceWith(

0 commit comments

Comments
 (0)