Skip to content

Commit

Permalink
Initial qutebrowser support
Browse files Browse the repository at this point in the history
Closes #1190
  • Loading branch information
glacambre committed Sep 27, 2021
1 parent fa6406d commit 5b1e270
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 1 deletion.
45 changes: 45 additions & 0 deletions src/firenvim
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/python3

import json
import os
import random
import re
import subprocess

xdg_data_home = os.environ.get("XDG_DATA_HOME", os.path.join(os.environ["HOME"], ".local", "share"))
userscripts_dir = os.path.join(xdg_data_home, "qutebrowser", "userscripts")
def dir(name):
return os.path.join(userscripts_dir, name)

password = random.getrandbits(64)

# Start firenvim script, send password, get port
firenvim = subprocess.Popen(["/home/me/.local/share/firenvim/firenvim"], stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.PIPE)
request = 'abcde{"newInstance":true,"password":"' + str(password) + '"}'
firenvim.stdin.write(bytes(request, 'utf-8'))
outs, errs = firenvim.communicate()
result = json.loads(outs[4:])

with open(dir("firenvim.js"), "rb") as f:
js = re.sub(rb'Promise.resolve({ port: .*, password: ".*" });',
bytes('Promise.resolve({ port: %s, password: "%s" });' % (result["port"], password), 'utf-8'),
f.read())

with open(dir("index.html"), "rb") as f:
html = f.read()
script_tag = html.find(b'<script type="application/javascript" src="index.js">')
script_tag_end = html[script_tag:].find(b'</script>')
html = html[0:script_tag] + b'<script>\n' + js + b'\n</script>' + html[script_tag_end:]
with open("/tmp/blah", "wb") as f2:
f2.write(html)

with open(dir("index.js"), "wb") as f:
f.write(b'const iframe = document.createElement("iframe");\n')
f.write(b'const blob = new Blob([new Uint8Array([')
f.write(bytes(''.join([str(c) + "," for c in html]), 'utf-8'))
f.write(b']).buffer], {type: "text/html; charset=utf-8"});\n')
f.write(b'iframe.src = URL.createObjectURL(blob);\n')
f.write(b'document.documentElement.appendChild(iframe);\n')

with open(os.environ["QUTE_FIFO"], "w") as f:
f.write("jseval --file %s" % dir("index.js"))
106 changes: 106 additions & 0 deletions src/qutebrowser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { PageEventEmitter } from "./page";
import { KeydownHandler } from "./KeyHandler";
import { setupInput } from "./input";

const connectionPromise = Promise.resolve({ port: 12345, password: "password" });
const pageLoaded = new Promise((resolve, reject) => {
window.addEventListener("load", resolve);
setTimeout(reject, 10000)
});

class QutePageEventEmitter extends PageEventEmitter {
private resizeCount = 0;
constructor() {
super();
const onResize = (() => {
this.resizeCount += 1;
this.emit("resize", [this.resizeCount, window.innerWidth, window.innerHeight]);
}).bind(this)
window.addEventListener("resize", onResize);
// We need to trigger a resize on startup because for some reason the
// window might be 1px wide when the compose script is created.
setTimeout(onResize, 100);
}
async evalInPage(js: string) { console.error(`eval(${js})`); }
async focusInput() { return Promise.resolve(); }
async focusPage() { return Promise.resolve(); }
async getEditorInfo() { return [document.location.href, "", [1, 1], undefined] as [string, string, [number, number], string] }
async getElementContent() {
return "Hello world";
}
async hideEditor() { return Promise.resolve(); }
async killEditor() { console.error("killEditor"); }
async pressKeys(_: any[]) { return Promise.resolve(); }
async resizeEditor(_: number, __: number) { return Promise.resolve(); }
async setElementContent(_: string) { return; }
async setElementCursor(_: number, __: number) { return Promise.resolve(); }
}


class QuteKeyHandler extends KeydownHandler {

constructor(private keyHandler: HTMLElement) {
super(keyHandler, {
alt: "all",
"<C-n>": "noop",
"<C-t>": "noop",
"<C-w>": "noop",
"<CS-n>": "noop",
"<CS-t>": "noop",
"<CS-w>": "noop",
ignoreKeys: {
"all": [],
"normal": [],
"visual": [],
"insert": [],
"replace": [],
"cmdline_normal": [],
"cmdline_insert": [],
"cmdline_replace": [],
"operator": [],
"visual_select": [],
"cmdline_hover": [],
"statusline_hover": [],
"statusline_drag": [],
"vsep_hover": [],
"vsep_drag": [],
"more": [],
"more_lastline": [],
"showmatch": [],
},
cmdlineTimeout: 3000,
});

const acceptInput = ((evt: any) => {
this.emit("input", evt.target.value);
evt.preventDefault();
evt.stopImmediatePropagation();
}).bind(this);

this.keyHandler.addEventListener("input", (evt: any) => {
if (evt.isTrusted && !evt.isComposing) {
acceptInput(evt);
evt.target.innerText = "";
evt.target.value = "";
}
});

this.keyHandler.addEventListener("compositionend", (e: CompositionEvent) => {
acceptInput(e);
});
}

moveTo(x: number, y: number) {
this.keyHandler.style.left = `${x}px`;
this.keyHandler.style.top = `${y}px`;
}
}

export const isReady = (async () => {
await pageLoaded;
return setupInput(
new QutePageEventEmitter(),
document.getElementById("canvas") as HTMLCanvasElement,
new QuteKeyHandler(document.getElementById("keyhandler")),
connectionPromise);
})();
45 changes: 44 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ const thunderbirdFiles = [
"static/firenvim.svg",
];

const qutebrowserFiles = [
"src/index.html",
"src/firenvim",
];

const config = {
mode: "development",

Expand Down Expand Up @@ -85,6 +90,7 @@ const package_json = JSON.parse(require("fs").readFileSync(path.join(__dirname,
const chrome_target_dir = path.join(__dirname, "target", "chrome")
const firefox_target_dir = path.join(__dirname, "target", "firefox")
const thunderbird_target_dir = path.join(__dirname, "target", "thunderbird")
const qutebrowser_target_dir = path.join(__dirname, "target", "qutebrowser")

const chromeConfig = (config, env) => {
const result = Object.assign(deepCopy(config), {
Expand Down Expand Up @@ -213,6 +219,36 @@ const thunderbirdConfig = (config, env) => {
return result;
}

const qutebrowserConfig = (config, env) => {
delete config.entry.background;
delete config.entry.content;
delete config.entry.index;
delete config.entry.browserAction;
config.entry.firenvim = "./src/qutebrowser.ts";
console.log(config)
const result = Object.assign(deepCopy(config), {
output: {
path: qutebrowser_target_dir,
},
plugins: [new CopyWebPackPlugin({
patterns: qutebrowserFiles.map(file => ({
from: file,
to: qutebrowser_target_dir,
transform: (content, src) => {
console.log(src);
return content;
}
}))
})]
});
try {
fs.rmdirSync(result.output.path, { recursive: true })
} catch (e) {
console.log(`Could not delete output dir (${e.message})`);
}
return result;
}

module.exports = args => {
let env = "";
if (args instanceof Object) {
Expand All @@ -236,7 +272,14 @@ module.exports = args => {
return [firefoxConfig(config, env)];
} else if (env.startsWith("thunderbird")) {
return [thunderbirdConfig(config, env)];
} else if (env.startsWith("qutebrowser")) {
return [qutebrowserConfig(config, env)];
}
return [chromeConfig(config, env), firefoxConfig(config, env), thunderbirdConfig(config, env)];
return [
chromeConfig(config, env),
firefoxConfig(config, env),
thunderbirdConfig(config, env),
qutebrowserConfig(config, env),
];
}

0 comments on commit 5b1e270

Please sign in to comment.