Delete irrelevant litcoffee flies

This commit is contained in:
Oliver Blanthorn 2017-07-16 16:52:47 +01:00
parent 32491df069
commit 22b01774ea
No known key found for this signature in database
GPG key ID: 2BB8C36BB504BFF3
6 changed files with 0 additions and 266 deletions

View file

@ -1,47 +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)

View file

@ -1,16 +0,0 @@
TODO: get litcoffee highlighting off @cmcaine
commands = {
"setTab": tridactyl.func.setTab
}
exStrParser = (str) ->
strArray = str.split(" ")
command = strArray[0]
func = commands[command]
args = strArray.slice(1)
args = ((if Number(a) then Number(a) else a) for a in args) # more concise way of doing this?
return {func, args}
Example: call `var x = exStrParser("setTab 1"); funcParser(x.func,x.args)` in the Firefox addon console

View file

@ -1,7 +0,0 @@
Takes functions from parser controller and calls them. Eventually, this will get more complicated to allow command chaining.
funcParser = (command,args) ->
command(args...) # ... is unpacks the list
Example: call `var x = exStrParser("setTab 1"); funcParser(x.func,x.args)` in the Firefox addon console

View file

@ -1,101 +0,0 @@
# 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)
- adapt vim-coffeescript to work with litcoffee2
- stop coffeescript vim thing from making newline # in markdown
- update vim-coffeescript to highlight await keywords, etc.
The following is an attempt at namespacing in CoffeeScript. If we used TypeScript instead we could just use modules, but Olie is squeamish about the syntax (no list comprehensions and too much that can be implied, like `let` and all the damn braces). I sympathise, but the compile time errors are really useful. For now, we'll stick with Coffee.
tridactyl = {}
tridactyl.func ?= {}
tridactyl.func.__init__ = ->
This allows us to use setTab in this file, but requires us to use the entire name outside.
tridactyl.func.setTab = setTab = (id) ->
browser.tabs.update(id,{active:true})
tridactyl.func.tabByIndex = tabByIndex = (index) ->
browser.tabs.query({}).then((tabs) ->
desiredTab = (tab for tab in tabs when tab.index == desIndex)[0]
)
tridactyl.func.incTab = 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)
## First attempt at message parsing wrapper to avoid duplication of code
The following functions all talk to the content.js script to perform functions that need to operate on, e.g., the `window.history` object.
tridactyl.func.goHistory = goHistory = (n) ->
sendMessageToActiveTab({command:"history", number:n})
tridactyl.func.goScroll = goScroll = (n) ->
sendMessageToActiveTab({command:"scroll",number:n})
tridactyl.func.sendMessageToActiveTab = sendMessageToActiveTab = (message) ->
sendMessageToFilteredTabs({active:true},message)
tridactyl.func.sendMessageToFilteredTabs = sendMessageToFilteredTabs = (filter,message) ->
filtTabs = await browser.tabs.query(filter)
browser.tabs.sendMessage(tab.id,message) for tab in filtTabs
tridactyl.func.doArbitraryCodeInWindow = doArbitraryCodeInWindow = (object, args) ->
sendMessageToActiveTab({command:"arbitrary",object,args})
# example: doArbitraryCodeInWindow("scrollBy",[0,100])
## Regex test
Adapted from http://www.dustindiaz.com/autocomplete-fuzzy-matching
tridactyl.mystrings = mystrings = ["colin", "olie", "jake", "harri"]
tridactyl.func.matchString = matchString = (input) ->
search = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i')
mystrings.filter((string) ->
if string.match(search)
return string
)
## Finish the Tridactyl namespace and initialise it
tridactyl.func.__init__()
# Misc helper functions
## Modulus
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)
Let the console know we got home safely.
console.log("Loaded Tridactyl")

View file

@ -1,91 +0,0 @@
# A simple observable-like class
**This doesn't work.** Async functions (any function that contains the `await` keyword) return a promise immediately and do their work sometime in the future. I think the principle is still doable, without polling, but not like this.
This class guarantees that the subscriber is called once per push and that each call of the subscriber completes before the next call. This indirection is required because subscriber() may be paused by an `await` - if subscriber was called directly by e.g. onKeyEvent(subscriber), then more than one subscriber call can be threaded concurrently if subscriber ever pauses execution... Controlling flow like this must have been a real pain in the arse before `await`...
class Sequential
constructor: (subscriber) ->
this._subscriber = subscriber
this._is_consuming = false
push: (v) ->
this._queue.push(v)
if not this._is_consuming
this.consume()
consume: ->
this._is_consuming = true
for v in this._queue
this._subscriber(v)
this._is_consuming = false
sleep = (ms) ->
new Promise((resolve) ->
setTimeout(resolve, ms))
class ParserController
constructor: ->
this._state = ""
pushEvent: (ev) =>
await sleep(1000)
this._state += ev.key
console.log(this._state)
parserController = new ParserController()
queue = new Sequential(parserController.pushEvent)
document.addEventListener(queue.push)
## This time with generators: simpler and maybe more idiomatic
I was very confused about how the `await` shims could work, so I had TypeScript output me one: turns out they're built on generators! That's a much more natural mechanism for our original use case.
For now, we'll just keep parserController synchronous and use this generator syntax.
ParserController = ->
# Loop forever.
loop
# Receive keys until the mode parser tells us to handle an ex_str.
loop
keys = []
ex_str = ""
# Pause execution until someone calls parserController.next(<somevalue>)
keys.push(yield)
# Mode parsers can return an object with either a `keys` or an `ex_str` property.
# If `.keys` exists it is a mapping of keys to continue to append to and resend (the mapping was not terminal, send me these keys again). `.keys` may differ from the passed value.
# If `.ex_str`, the mapping was terminal: drop all the keys you have now and break to handle the ex_str.
response = normal_mode_parser(keys)
if response.keys != undefined
keys = response.keys
else
ex_str = response.ex_str
break
# Parse the ex_str into a function and command to run.
[func, args] = ex_str_parser(ex_str)
# Execute the ex_str.
func(args...)
# Create the generator object
parserController = ParserController()
# Run the parserController until the first yield.
parserController.next()
# parserController.next needs isn't bound to parserController, so needs to be made indirect:
feeder = (ev) ->
parserController.next(ev)
# Feed the parserController events.
document.addEventListener("keyDown", feeder)
Fun digression: I first encountered the generator/yield syntax in Python2 where it was not asynchronous and only allows data transfer from the yielder to the caller of next(). It took me an embarassingly long time to get my head around the new semantics when I saw it again in python3's async library and the data was moving in both directions.
Don't be like me: grok it now with these helpful links: [mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*), [python wiki](https://wiki.python.org/moin/Generators)

View file

@ -1,4 +0,0 @@
# Test
test = () ->
"hello"