messaging: move more modules to new sys

This commit is contained in:
Colin Caine 2017-10-28 05:11:10 +01:00
parent 444f9259f7
commit 446bd0be21
6 changed files with 82 additions and 72 deletions

View file

@ -1,3 +1,5 @@
import * as Messaging from './messaging'
/** CommandLine API for inclusion in background script
Receives messages from commandline_frame
@ -13,16 +15,11 @@ export namespace onLine {
}
/** Receive events from commandline_frame and pass to listeners */
function handler(message: Message) {
if (message.type === "commandline") {
for (let listener of listeners) {
listener(message.exStr)
}
function recvExStr(exstr: string) {
for (let listener of listeners) {
listener(exstr)
}
// This is req. to shut typescript up.
// TODO: Fix onMessageBool in web-ext-types
return false
}
browser.runtime.onMessage.addListener(handler)
Messaging.addListener("commandline_background", Messaging.attributeCaller({recvExStr}))
}

View file

@ -8,6 +8,10 @@ let clInput = window.document.getElementById("tridactyl-input") as HTMLInputElem
export let focus = () => clInput.focus()
async function sendExstr(exstr) {
Messaging.message("commandline_background", "recvExStr", [exstr])
}
/* Process the commandline on enter. */
clInput.addEventListener("keydown", function (keyevent) {
if (keyevent.key === "Enter") {
@ -22,15 +26,15 @@ clInput.addEventListener("keydown", function (keyevent) {
*/
completions.innerHTML = ""
setTimeout(()=>{clInput.value = ""}, 0)
browser.runtime.sendMessage({type: "commandline", exStr: "hidecmdline"})
sendExstr("hidecmdline")
}
})
/* Send the commandline to the background script and await response. */
function process() {
console.log(clInput.value)
browser.runtime.sendMessage({type: "commandline", exStr: "hidecmdline"})
browser.runtime.sendMessage({type: "commandline", exStr: clInput.value})
sendExstr("hidecmdline")
sendExstr(clInput.value)
completions.innerHTML = ""
clInput.value = ""
}

View file

@ -12,6 +12,9 @@ import "./number.clamp"
import * as SELF from "./excmds_content"
//#content_helper
Messaging.addListener('excmd_content', Messaging.attributeCaller(SELF))
/** Message excmds_content.ts in the active tab of the currentWindow */
//#background_helper
import {messageActiveTab} from './messaging'
//#background_helper
import "./number.mod"
@ -62,17 +65,6 @@ async function activeTabID() {
return (await activeTab()).id
}
/** Message excmds_content.ts in the active tab of the currentWindow */
//#background_helper
async function message( type: "excmd_content" | "commandline_frame", command: string, args?: any[]) {
let message: Message = {
type,
command,
args,
}
browser.tabs.sendMessage(await activeTabID(), message)
}
//#background_helper
function tabSetActive(id: number) {
browser.tabs.update(id, {active: true})
@ -369,7 +361,7 @@ export function hidecmdline() {
export function fillcmdline(...strarr: string[]) {
let str = strarr.join(" ")
showcmdline()
message("commandline_frame", "fillcmdline", [str])
messageActiveTab("commandline_frame", "fillcmdline", [str])
}
// TODO: For security, this should really be in the background.
@ -412,7 +404,7 @@ const DEFAULT_FAVICON = browser.extension.getURL("static/defaultFavicon.svg")
//#background
export async function openbuffer() {
fillcmdline("buffer")
message("commandline_frame", "changecompletions", [await listTabs()])
messageActiveTab("commandline_frame", "changecompletions", [await listTabs()])
resizecmdline()
}

View file

@ -88,7 +88,7 @@ def content(lines, context):
sig = Signature(block.split('\n')[0])
return "cmd_params.set('{sig.name}', ".format(**locals()) + dict_to_js(sig.params) + """)
{sig.raw}
message(
messageActiveTab(
"excmd_content",
"{sig.name}",
""".format(**locals()) + str(list(sig.params.keys())).replace("'","") + """,

View file

@ -1,8 +1,26 @@
export type listener = (message: Message, sender?, sendResponse?) => void|any
export type TabMessageType =
"excmd_content" |
"keydown_content" |
"commandline_frame"
export type NonTabMessageType =
"keydown_background" |
"commandline_background"
export type MessageType = TabMessageType | NonTabMessageType
export interface Message {
type: MessageType
// and other unknown attributes...
[key: string]: any
}
export type listener = (message: Message, sender?, sendResponse?) => void|Promise<any>
/** await a promise and console.error and rethrow if it errors
Errors from promises don't get logged unless you seek them out.
There's an event for catching these, but it's not implemented in firefox
yet: https://bugzilla.mozilla.org/show_bug.cgi?id=1269371
*/
async function l(promise) {
try {
@ -13,24 +31,6 @@ async function l(promise) {
}
}
const listeners = new Map<string, Set<listener>>()
/** Register a listener to be called for each message with type */
export function addListener(type, callback: listener) {
if (!listeners.get(type)) {
listeners.set(type, new Set())
}
listeners.get(type).add(callback)
return () => { listeners.get(type).delete(callback) }
}
function onMessage(message, sender, sendResponse) {
if (listeners.get(message.type)) {
for (let listener of listeners.get(message.type)) {
listener(message, sender, sendResponse)
}
}
}
// Calls methods on obj that match .command and sends responses back
export function attributeCaller(obj) {
@ -41,22 +41,27 @@ export function attributeCaller(obj) {
if (message.args === undefined) message.args = []
// Call command on obj
let response = obj[message.command](...message.args)
try {
let response = obj[message.command](...message.args)
// Return response to sender
if (response instanceof Promise) {
return response
} else {
sendResponse(response)
// Return response to sender
if (response instanceof Promise) {
return response
} else {
sendResponse(response)
}
} catch (e) {
return new Promise((resolve, error)=>error(e))
}
}
return handler
}
/** Send a message to non-content scripts */
export async function message(type, command, args?) {
export async function message(type: NonTabMessageType, command, args?) {
// One day typescript will be smart enough to back propagate this cast.
return await l(browser.runtime.sendMessage({type, command, args} as Message))
return l(browser.runtime.sendMessage({type, command, args} as Message))
}
/** The first active tab in the currentWindow.
@ -76,22 +81,46 @@ async function activeTabID() {
/** Message the active tab of the currentWindow */
//#background_helper
export async function messageActiveTab(type, command: string, args?: any[]) {
messageTab(await activeTabID(), type, command, args)
export async function messageActiveTab(type: TabMessageType, command: string, args?: any[]) {
return messageTab(await activeTabID(), type, command, args)
}
export async function messageTab(tabId, type, command, args?) {
export async function messageTab(tabId, type: TabMessageType, command, args?) {
let message: Message = {
type,
command,
args,
}
l(browser.tabs.sendMessage(tabId, message))
return l(browser.tabs.sendMessage(tabId, message))
}
export async function messageAllTabs(type, command: string, args?: any[]) {
export async function messageAllTabs(type: TabMessageType, command: string, args?: any[]) {
let responses = []
for (let tab of await browser.tabs.query({})) {
messageTab(tab.id, type, command, args)
try { responses.push(await messageTab(tab.id, type, command, args)) }
catch (e) { console.error(e) }
}
return responses
}
const listeners = new Map<string, Set<listener>>()
/** Register a listener to be called for each message with type */
export function addListener(type: MessageType, callback: listener) {
if (!listeners.get(type)) {
listeners.set(type, new Set())
}
listeners.get(type).add(callback)
return () => { listeners.get(type).delete(callback) }
}
/** Recv a message from runtime.onMessage and send to all listeners */
function onMessage(message, sender, sendResponse) {
if (listeners.get(message.type)) {
for (let listener of listeners.get(message.type)) {
listener(message, sender, sendResponse)
}
}
}

14
src/tridactyl.d.ts vendored
View file

@ -3,24 +3,12 @@
// For some obscure reason, tsc doesn't like .d.ts files to share a name with
// .ts files. So don't do that.
// Ill-advised monkeypatching
interface Number {
mod(n: number): number
clamp(lo: number, hi: number): number
}
// For content.ts
interface Message {
type:
"excmd_content" |
"keydown_content" |
"keydown_background" |
"commandline" |
"commandline_frame"
// And other unknown attributes...
[key: string]: any
}
declare var content: any
// Firefox-specific dom properties
interface Window {