tridactyl/src/commandline_content.ts

78 lines
2.3 KiB
TypeScript
Raw Normal View History

/** Inject an input element into unsuspecting webpages and provide an API for interaction with tridactyl */
import Logger from "./logging"
const logger = new Logger("messaging")
/* TODO:
CSS
Friendliest-to-webpage way of injecting commandline bar?
Security: how to prevent other people's JS from seeing or accessing the bar or its output?
- Method here is isolation via iframe
- Web content can replace the iframe, but can't view or edit its content.
- see doc/escalating-privilege.md for other approaches.
*/
// inject the commandline iframe into a content page
2017-10-05 15:27:45 +01:00
let cmdline_iframe: HTMLIFrameElement = undefined
function init() {
if (cmdline_iframe === undefined) {
try {
cmdline_iframe = window.document.createElement("iframe")
2018-03-04 14:15:26 +01:00
cmdline_iframe.className = "cleanslate"
cmdline_iframe.setAttribute(
"src",
browser.extension.getURL("static/commandline.html"),
)
2017-10-28 20:16:15 +08:00
cmdline_iframe.setAttribute("id", "cmdline_iframe")
hide()
window.document.documentElement.appendChild(cmdline_iframe)
} catch (e) {
2017-12-30 00:46:26 +00:00
logger.error("Couldn't initialise cmdline_iframe!", e)
}
}
2017-10-05 15:27:45 +01:00
}
// TODO: Propagate awaits back through messaging system or resend
// commandline_frame messages from excmd_content if you want to avoid init'ing
// every time.
init()
export function show() {
const height =
cmdline_iframe.contentWindow.document.body.offsetHeight + "px"
2018-03-04 14:15:26 +01:00
cmdline_iframe.setAttribute("style", `height: ${height} !important;`)
2017-10-05 15:27:45 +01:00
}
export function hide() {
2018-03-04 14:15:26 +01:00
cmdline_iframe.setAttribute("style", "height: 0px !important;")
}
export function focus() {
2017-10-05 15:27:45 +01:00
cmdline_iframe.focus()
}
2017-10-28 19:20:31 +08:00
export function blur() {
cmdline_iframe.blur()
}
export function executeWithoutCommandLine(fn) {
let parent
if (cmdline_iframe) {
parent = cmdline_iframe.parentNode
parent.removeChild(cmdline_iframe)
}
let result
try {
result = fn()
} catch (e) {
console.log(e)
}
if (cmdline_iframe) parent.appendChild(cmdline_iframe)
return result
}
import * as Messaging from "./messaging"
import * as SELF from "./commandline_content"
Messaging.addListener("commandline_content", Messaging.attributeCaller(SELF))