mirror of
https://github.com/vale981/tridactyl
synced 2025-03-06 01:51:40 -05:00
216 lines
6.9 KiB
TypeScript
216 lines
6.9 KiB
TypeScript
/** Background script entry point. */
|
|
|
|
/* tslint:disable:import-spacing */
|
|
|
|
import * as proxy_background from "@src/lib/browser_proxy_background"
|
|
|
|
import * as controller from "@src/lib/controller"
|
|
import * as perf from "@src/perf"
|
|
import { listenForCounters } from "@src/perf"
|
|
import * as messaging from "@src/lib/messaging"
|
|
import * as excmds_background from "@src/.excmds_background.generated"
|
|
import { CmdlineCmds } from "@src/background/commandline_cmds"
|
|
import { EditorCmds } from "@src/background/editor"
|
|
import * as convert from "@src/lib/convert"
|
|
import * as config from "@src/lib/config"
|
|
import * as dom from "@src/lib/dom"
|
|
import * as download_background from "@src/background/download_background"
|
|
import * as itertools from "@src/lib/itertools"
|
|
import * as keyseq from "@src/lib/keyseq"
|
|
import * as request from "@src/lib/requests"
|
|
import * as native from "@src/lib/native"
|
|
import state from "@src/state"
|
|
import * as webext from "@src/lib/webext"
|
|
import { AutoContain } from "@src/lib/autocontainers"
|
|
import * as extension_info from "@src/lib/extension_info"
|
|
import * as omnibox from "@src/background/omnibox"
|
|
import * as R from "ramda"
|
|
|
|
// Add various useful modules to the window for debugging
|
|
; (window as any).tri = Object.assign(Object.create(null), {
|
|
messaging,
|
|
excmds: excmds_background,
|
|
convert,
|
|
config,
|
|
controller,
|
|
dom,
|
|
download_background,
|
|
itertools,
|
|
native,
|
|
keyseq,
|
|
request,
|
|
state,
|
|
webext,
|
|
l: prom => prom.then(console.log).catch(console.error),
|
|
contentLocation: window.location,
|
|
R,
|
|
perf,
|
|
})
|
|
|
|
import { HintingCmds } from "@src/background/hinting"
|
|
// Set up our controller to execute background-mode excmds. All code
|
|
// running from this entry point, which is to say, everything in the
|
|
// background script, will use the excmds that we give to the module
|
|
// here.
|
|
controller.setExCmds({
|
|
"": excmds_background,
|
|
"ex": CmdlineCmds,
|
|
"text": EditorCmds,
|
|
"hint": HintingCmds
|
|
})
|
|
|
|
// {{{ tri.contentLocation
|
|
// When loading the background, use the active tab to know what the current content url is
|
|
browser.tabs.query({ currentWindow: true, active: true }).then(t => {
|
|
(window as any).tri.contentLocation = new URL(t[0].url)
|
|
})
|
|
// After that, on every tab change, update the current url
|
|
let contentLocationCount = 0
|
|
browser.tabs.onActivated.addListener(ev => {
|
|
const myId = contentLocationCount + 1
|
|
contentLocationCount = myId
|
|
browser.tabs.get(ev.tabId).then(t => {
|
|
// Note: we're using contentLocationCount and myId in order to make sure that only the last onActivated event is used in order to set contentLocation
|
|
// This is needed because otherWise the following chain of execution might happen: onActivated1 => onActivated2 => tabs.get2 => tabs.get1
|
|
if (contentLocationCount === myId) {
|
|
(window as any).tri.contentLocation = new URL(t.url)
|
|
}
|
|
})
|
|
})
|
|
// Update on navigation too (but remember that sometimes people open tabs in the background :) )
|
|
browser.webNavigation.onDOMContentLoaded.addListener(
|
|
() => {
|
|
browser.tabs.query({ currentWindow: true, active: true }).then(t => {
|
|
(window as any).tri.contentLocation = new URL(t[0].url)
|
|
})
|
|
},
|
|
)
|
|
|
|
// Prevent Tridactyl from being updated while it is running in the hope of fixing #290
|
|
browser.runtime.onUpdateAvailable.addListener(_ => undefined)
|
|
|
|
browser.runtime.onStartup.addListener(_ => {
|
|
config.getAsync("autocmds", "TriStart").then(aucmds => {
|
|
const hosts = Object.keys(aucmds)
|
|
// If there's only one rule and it's "all", no need to check the hostname
|
|
if (hosts.length === 1 && hosts[0] === ".*") {
|
|
controller.acceptExCmd(aucmds[hosts[0]])
|
|
} else {
|
|
native.run("hostname").then(hostname => {
|
|
for (const host of hosts) {
|
|
if (hostname.content.match(host)) {
|
|
controller.acceptExCmd(aucmds[host])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
})
|
|
|
|
// Nag people about updates.
|
|
// Hope that they're on a tab we can access.
|
|
config.getAsync("update", "nag").then(nag => {
|
|
if (nag === true) excmds_background.updatecheck("auto_polite")
|
|
})
|
|
|
|
// }}}
|
|
|
|
// {{{ AUTOCOMMANDS
|
|
|
|
// We could use ev.previousTabId here, but that field is empty when a
|
|
// tab is closed, and we do want to run "TabLeft" commands when that
|
|
// happens. Instead, we assume that the user can only be in one tab at
|
|
// a time and the last tab we entered has to be the one we're leaving.
|
|
let curTab = null
|
|
browser.tabs.onActivated.addListener(ev => {
|
|
const ignore = _ => _
|
|
if (curTab !== null) {
|
|
// messaging.messageTab failing can happen when leaving
|
|
// privileged tabs (e.g. about:addons) or when the tab is
|
|
// being closed.
|
|
messaging
|
|
.messageTab(curTab, "excmd_content", "loadaucmds", ["TabLeft"])
|
|
.catch(ignore)
|
|
}
|
|
curTab = ev.tabId
|
|
messaging
|
|
.messageTab(curTab, "excmd_content", "loadaucmds", ["TabEnter"])
|
|
.catch(ignore)
|
|
})
|
|
|
|
// }}}
|
|
|
|
// {{{ AUTOCONTAINERS
|
|
|
|
extension_info.init()
|
|
|
|
const aucon = new AutoContain()
|
|
|
|
// Handle cancelled requests as a result of autocontain.
|
|
browser.webRequest.onCompleted.addListener(aucon.completedRequestListener, {
|
|
urls: ["<all_urls>"],
|
|
types: ["main_frame"],
|
|
})
|
|
|
|
browser.webRequest.onErrorOccurred.addListener(aucon.completedRequestListener, {
|
|
urls: ["<all_urls>"],
|
|
types: ["main_frame"],
|
|
})
|
|
|
|
// Contain autocmd.
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
aucon.autoContain,
|
|
{ urls: ["<all_urls>"], types: ["main_frame"] },
|
|
["blocking"],
|
|
)
|
|
|
|
browser.tabs.onCreated.addListener(
|
|
aucon.tabCreatedListener,
|
|
)
|
|
|
|
// }}}
|
|
|
|
// {{{ PERFORMANCE LOGGING
|
|
|
|
// An object to collect all of our statistics in one place.
|
|
const statsLogger: perf.StatsLogger = new perf.StatsLogger()
|
|
const messages = {
|
|
excmd_background: excmds_background,
|
|
controller_background: controller,
|
|
performance_background: statsLogger,
|
|
download_background: {
|
|
downloadUrl: download_background.downloadUrl,
|
|
downloadUrlAs: download_background.downloadUrlAs,
|
|
},
|
|
browser_proxy_background: {shim: proxy_background.shim}
|
|
}
|
|
export type Messages = typeof messages
|
|
|
|
messaging.setupListener(messages)
|
|
// Listen for statistics from the background script and store
|
|
// them. Set this one up to log directly to the statsLogger instead of
|
|
// going through messaging.
|
|
const perfObserver = listenForCounters(statsLogger)
|
|
window.tri = Object.assign(window.tri || Object.create(null), {
|
|
// Attach the perf observer to the window object, since there
|
|
// appears to be a bug causing performance observers to be GC'd
|
|
// even if they're still the target of a callback.
|
|
perfObserver,
|
|
// Also attach the statsLogger so we can access our stats from the
|
|
// console.
|
|
statsLogger,
|
|
})
|
|
|
|
// }}}
|
|
|
|
// {{{ OMNIBOX
|
|
|
|
omnibox.init()
|
|
|
|
// }}}
|
|
|
|
// {{{ Obey Mozilla's orders https://github.com/tridactyl/tridactyl/issues/1800
|
|
|
|
native.unfixamo();
|
|
|
|
/// }}}
|