mirror of
https://github.com/vale981/tridactyl
synced 2025-03-05 09:31:41 -05:00
Convert source to literate coffee script v2
We're intending to write all the source code in literate coffee script v2, which should make the code self-documenting and hopefully enforce better standards.
This commit is contained in:
parent
ec4eaced3d
commit
17c1bbc05f
4 changed files with 136 additions and 170 deletions
|
@ -1,50 +0,0 @@
|
|||
# Just a test
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
config =
|
||||
scrollDown: "j"
|
||||
scrollUp: "k"
|
||||
back: "H"
|
||||
forward: "L"
|
||||
|
||||
|
||||
console.log("hello")
|
||||
|
||||
historyHandler = (message) ->
|
||||
window.history.go(message.number)
|
||||
|
||||
scrollHandler = (message) ->
|
||||
window.scrollBy(0, message.number)
|
||||
# First 0 corresponds to horizontal scroll, which is literally never needed ever
|
||||
# We should work out some way to have a configuration file and hooks
|
||||
# And generally document things well
|
||||
|
||||
arbitraryHandler = (message) ->
|
||||
window[message.object].apply(window,message.args)
|
||||
# apply's first argument tells it what "this" is
|
||||
# I don't understand why it is needed, isn't "window" "this"?
|
||||
# only works with direct methods e.g. "scrollBy", not "history.go"
|
||||
|
||||
# Testing function for really arbitrary evaluation in the context of the content script.
|
||||
evalHandler = (message) ->
|
||||
eval(message.string)
|
||||
|
||||
messageHandler = (message) ->
|
||||
switch(message.command)
|
||||
when "history" then historyHandler(message)
|
||||
when "scroll" then scrollHandler(message)
|
||||
when "arbitrary" then arbitraryHandler(message)
|
||||
when "eval" then evalHandler(message)
|
||||
|
||||
browser.runtime.onMessage.addListener(messageHandler)
|
||||
|
||||
keyHandler = (event) ->
|
||||
switch(event.key)
|
||||
when config.scrollDown then scrollHandler({number:10})
|
||||
when config.scrollUp then scrollHandler({number:-10})
|
||||
when config.back then historyHandler({number:-1})
|
||||
when config.forward then historyHandler({number:1})
|
||||
|
||||
document.addEventListener("keydown", keyHandler)
|
50
addon/src/content.litcoffee
Normal file
50
addon/src/content.litcoffee
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Just a test
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
config =
|
||||
scrollDown: "j"
|
||||
scrollUp: "k"
|
||||
back: "H"
|
||||
forward: "L"
|
||||
|
||||
|
||||
console.log("hello")
|
||||
|
||||
historyHandler = (message) ->
|
||||
window.history.go(message.number)
|
||||
|
||||
scrollHandler = (message) ->
|
||||
window.scrollBy(0, message.number)
|
||||
# First 0 corresponds to horizontal scroll, which is literally never needed ever
|
||||
# We should work out some way to have a configuration file and hooks
|
||||
# And generally document things well
|
||||
|
||||
arbitraryHandler = (message) ->
|
||||
window[message.object].apply(window,message.args)
|
||||
# apply's first argument tells it what "this" is
|
||||
# I don't understand why it is needed, isn't "window" "this"?
|
||||
# only works with direct methods e.g. "scrollBy", not "history.go"
|
||||
|
||||
# Testing function for really arbitrary evaluation in the context of the content script.
|
||||
evalHandler = (message) ->
|
||||
eval(message.string)
|
||||
|
||||
messageHandler = (message) ->
|
||||
switch(message.command)
|
||||
when "history" then historyHandler(message)
|
||||
when "scroll" then scrollHandler(message)
|
||||
when "arbitrary" then arbitraryHandler(message)
|
||||
when "eval" then evalHandler(message)
|
||||
|
||||
browser.runtime.onMessage.addListener(messageHandler)
|
||||
|
||||
keyHandler = (event) ->
|
||||
switch(event.key)
|
||||
when config.scrollDown then scrollHandler({number:10})
|
||||
when config.scrollUp then scrollHandler({number:-10})
|
||||
when config.back then historyHandler({number:-1})
|
||||
when config.forward then historyHandler({number:1})
|
||||
|
||||
document.addEventListener("keydown", keyHandler)
|
|
@ -1,120 +0,0 @@
|
|||
# Quick and dirty prototyping.
|
||||
#
|
||||
# Functions declared here can be called in the debug window in ff.
|
||||
|
||||
handleBrowserAction = () ->
|
||||
# .then takes a function that consumes at least one argument. this is an
|
||||
# example of a named function, but anonymous functions are fine, too.
|
||||
browser.tabs.query({active: true}).then(console.log)
|
||||
|
||||
# Change to the next tab in window, wrapping back to the start, if req.
|
||||
#
|
||||
# Get an array of all tabs, find the active tab's index, and the tab id of
|
||||
# the tab with the next index.
|
||||
#
|
||||
# TODO: limit to focused window.
|
||||
nextTab1 = () ->
|
||||
browser.tabs.query({}).then(
|
||||
(tabs) ->
|
||||
# Doing my own list comprehensions means they're not done
|
||||
# asynchronously from each other, but they will be very fast and
|
||||
# this makes the code much simpler.
|
||||
active = (tab for tab in tabs when tab.active == true)[0]
|
||||
target_index = (active.index + 1) % tabs.length
|
||||
target = (tab for tab in tabs when tab.index == target_index)[0]
|
||||
displayTab(target.id)
|
||||
console.error)
|
||||
|
||||
# Change to the next tab in window, wrapping back to the start, if req.
|
||||
#
|
||||
# Get an array of all tabs, find the active tab's index, and the tab id of
|
||||
# the tab with the next index.
|
||||
#
|
||||
# TODO: limit to focused window.
|
||||
nextTab2 = () ->
|
||||
# Alternative implementation without list comprehensions.
|
||||
#
|
||||
# If querying all tabs to get number of tabs is too slow (as if), could
|
||||
# query for index+1 and then test if result array.length == 0.
|
||||
browser.tabs.query({}).then(
|
||||
(tabs) ->
|
||||
browser.tabs.query({active: true}).then(
|
||||
(tabs2) ->
|
||||
active = tabs2[0]
|
||||
target_index = (active.index + 1) % tabs.length
|
||||
browser.tabs.query({index: target_index}).then(
|
||||
(tabs3) ->
|
||||
displayTab(tabs3[0].id)
|
||||
, console.error)
|
||||
, console.error)
|
||||
, console.error)
|
||||
|
||||
# Convenience: mark tab_id as active (active tabs are displayed in their window)
|
||||
displayTab = (tab_id) ->
|
||||
browser.tabs.update(tab_id, {active: true}).then(null, console.error)
|
||||
|
||||
# Example of a listener. Presumably we wouldn't use the browserAction button in
|
||||
# the real thing.
|
||||
browser.browserAction.onClicked.addListener(handleBrowserAction)
|
||||
|
||||
incTab = (inc) ->
|
||||
browser.windows.getCurrent().then(
|
||||
(window) ->
|
||||
browser.tabs.query({windowId:window.id}).then(
|
||||
(tabs) ->
|
||||
activeTab = (tab for tab in tabs when tab.active)[0]
|
||||
desiredIndex = (activeTab.index + inc).mod(tabs.length)
|
||||
desiredTab = (tab for tab in tabs when tab.index == desiredIndex)[0]
|
||||
setTab(desiredTab.id)
|
||||
).catch(console.error)
|
||||
).catch(console.error)
|
||||
|
||||
setTab = (id) ->
|
||||
browser.tabs.update(id,{active:true})
|
||||
|
||||
tabByIndex = (index) ->
|
||||
browser.tabs.query({}).then((tabs) ->
|
||||
desiredTab = tab for tab in tabs when tab.index == desIndex
|
||||
)
|
||||
|
||||
# modulus that always returns a non-negative number, as mathematicians expect.
|
||||
#
|
||||
# In mathematics, mod usually returns the remainder of euclidean division of
|
||||
# two numbers and the remainder is always positive.
|
||||
#
|
||||
# In most programming languages, mod can return a negative number and the
|
||||
# return value of mod always matches the sign of one or the other of the
|
||||
# arguments. In JS the built-in % operator's returned value always has the same
|
||||
# sign as the dividend, in python, the divisor.
|
||||
Number.prototype.mod = (n) ->
|
||||
Math.abs(this % n)
|
||||
|
||||
##
|
||||
#
|
||||
# First attempt at message parsing wrapper to avoid duplication of code
|
||||
#
|
||||
##
|
||||
|
||||
# The following functions all talk to the content.js script
|
||||
goHistory = (n) ->
|
||||
sendMessageToActiveTab({command:"history", number:n})
|
||||
|
||||
goScroll = (n) ->
|
||||
sendMessageToActiveTab({command:"scroll",number:n})
|
||||
|
||||
sendMessageToActiveTab = (message) ->
|
||||
sendMessageToFilteredTabs({active:true},message)
|
||||
|
||||
sendMessageToFilteredTabs = (filter,message) ->
|
||||
browser.tabs.query(filter).then(
|
||||
(tabs) ->
|
||||
browser.tabs.sendMessage(tab.id,message) for tab in tabs
|
||||
)
|
||||
|
||||
|
||||
doArbitraryCodeInWindow = (object, args) ->
|
||||
sendMessageToActiveTab({command:"arbitrary",object,args})
|
||||
# example: doArbitraryCodeInWindow("scrollBy",[0,100])
|
||||
|
||||
|
||||
console.log("Loaded Tridactyl")
|
86
addon/src/main.litcoffee
Normal file
86
addon/src/main.litcoffee
Normal file
|
@ -0,0 +1,86 @@
|
|||
# main.litcoffee
|
||||
|
||||
## Introduction
|
||||
|
||||
We're writing everything in CoffeeScript v2: http://coffeescript.org/v2/
|
||||
You can install it with `npm install --global coffeescript@next`. You need Firefox version 52+ to use the `await` command we are using here.
|
||||
|
||||
Functions declared here can be called in the debug window in ff. This is the main
|
||||
background script that can access all of the WebExtension APIs.
|
||||
|
||||
## TODO:
|
||||
This is a todolist
|
||||
- get web-ext to run FF dev (~/bin/firefox)
|
||||
- stop coffeescript vim thing from making newline # in markdown
|
||||
- update vim-coffeescript to highlight await keywords, etc.
|
||||
|
||||
handleBrowserAction = () ->
|
||||
# .then takes a function that consumes at least one argument. this is an
|
||||
# example of a named function, but anonymous functions are fine, too.
|
||||
x = await browser.tabs.query({active: true}).then(console.log)
|
||||
|
||||
|
||||
# Example of a listener. Presumably we wouldn't use the browserAction button in
|
||||
# the real thing.
|
||||
|
||||
browser.browserAction.onClicked.addListener(handleBrowserAction)
|
||||
|
||||
incTab = (inc) ->
|
||||
try
|
||||
window = await browser.windows.getCurrent()
|
||||
tabs = await browser.tabs.query({windowId:window.id})
|
||||
activeTab = (tab for tab in tabs when tab.active)[0]
|
||||
desiredIndex = (activeTab.index + inc).mod(tabs.length)
|
||||
desiredTab = (tab for tab in tabs when tab.index == desiredIndex)[0]
|
||||
setTab(desiredTab.id)
|
||||
catch error
|
||||
console.log(error)
|
||||
|
||||
setTab = (id) ->
|
||||
browser.tabs.update(id,{active:true})
|
||||
|
||||
tabByIndex = (index) ->
|
||||
browser.tabs.query({}).then((tabs) ->
|
||||
desiredTab = tab for tab in tabs when tab.index == desIndex
|
||||
)
|
||||
|
||||
# modulus that always returns a non-negative number, as mathematicians expect.
|
||||
#
|
||||
# In mathematics, mod usually returns the remainder of euclidean division of
|
||||
# two numbers and the remainder is always positive.
|
||||
#
|
||||
# In most programming languages, mod can return a negative number and the
|
||||
# return value of mod always matches the sign of one or the other of the
|
||||
# arguments. In JS the built-in % operator's returned value always has the same
|
||||
# sign as the dividend, in python, the divisor.
|
||||
|
||||
Number.prototype.mod = (n) ->
|
||||
Math.abs(this % n)
|
||||
|
||||
##
|
||||
#
|
||||
# First attempt at message parsing wrapper to avoid duplication of code
|
||||
#
|
||||
##
|
||||
|
||||
# The following functions all talk to the content.js script
|
||||
|
||||
goHistory = (n) ->
|
||||
sendMessageToActiveTab({command:"history", number:n})
|
||||
|
||||
goScroll = (n) ->
|
||||
sendMessageToActiveTab({command:"scroll",number:n})
|
||||
|
||||
sendMessageToActiveTab = (message) ->
|
||||
sendMessageToFilteredTabs({active:true},message)
|
||||
|
||||
sendMessageToFilteredTabs = (filter,message) ->
|
||||
filtTabs = await browser.tabs.query(filter)
|
||||
browser.tabs.sendMessage(tab.id,message) for tab in filtTabs
|
||||
|
||||
doArbitraryCodeInWindow = (object, args) ->
|
||||
sendMessageToActiveTab({command:"arbitrary",object,args})
|
||||
# example: doArbitraryCodeInWindow("scrollBy",[0,100])
|
||||
|
||||
|
||||
console.log("Loaded Tridactyl")
|
Loading…
Add table
Reference in a new issue