aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)Author
2021-02-01Update TODOTeddy Wing
2021-02-01main: Ensure WebSocket connection is always closedTeddy Wing
Create a new `with-websocket-connection` decorator that starts and closes a WebSocket connection to the given `client` around the body forms. Thanks to Practical Common Lisp's "The Special Operators" chapter (http://www.gigamonkeys.com/book/the-special-operators.html#unwinding-the-stack) for introducing me to `unwind-protect`. Couldn't figure out how to get the new macro to auto-indent properly with Vlime, so ended up manually indenting it.
2021-02-01websocket-send: Use local `client` variable instead of globalTeddy Wing
Must have copy-pasted that s-expression from elsewhere in the file.
2021-01-31Update TODOTeddy Wing
2021-01-31Update TODOTeddy Wing
2021-01-31main: Replace `sleep` call with a `wait-group`Teddy Wing
The `sleep` call allowed me to test the behaviour of the program, since without it, it would exit before the WebSocket messages had a chance to be sent and received. But we shouldn't be waiting a fixed number of seconds for the program to execute. Instead, we should only keep the program alive as long as there are messages to be sent and received. This adds a Go-style wait group using my wait-group library that increments the wait group when we send a WebSocket message, and decrements it when we receive a WebSocket response. That allows us to keep the program alive only for the amount of time necessary for the messages to be exchanged.
2021-01-31Update TODOTeddy Wing
2021-01-31Convert `filter` from a function to a macroTeddy Wing
Doesn't make a big difference, just for fun. I like the idea of a compile-time version of this since it's essentially just renaming `remove-if-not`. Move it to a new file so we can include it before it's used in `main.lisp`.
2021-01-31Update TODOTeddy Wing
2021-01-30main.lisp: Use `find-if` in `requested-extension-p`Teddy Wing
I've been reading Practical Common Lisp's "Collections" chapter (http://www.gigamonkeys.com/book/collections.html) and it seemed like `find-if` would be nicer here than what I wrote before.
2021-01-30main.lisp: Change `filter` to use `remove-if-not`Teddy Wing
Just learned about `remove-if-not`. Really cleans up this function. Not even really necessary to keep `filter`, but I guess I'll hold on to it for now.
2021-01-30extension-targets: Use `string=` instead of `equal`Teddy Wing
Just learned that `string=` exists, and that seems to describe the intent better than `equal`.
2021-01-30Update TODOTeddy Wing
2021-01-30main.lisp: Update temporary WebSocket URLTeddy Wing
2021-01-24Add TODOTeddy Wing
2021-01-24main.lisp: Reload extensionsTeddy Wing
Send DevTools Protocol messages to reload extensions. Not easy to do things sequentially since the responses have to be handled in `ws-on-message`. Once we filter the list of extensions wanted to reload, attach to their DevTools targets, then send them JavaScript evaluation messages that tells the extensions to reload.
2021-01-24main.lisp: Rename `get-targets-msg` to `target-get-targets-msg`Teddy Wing
Prefix the function name with the name of the DevTools domain to distinguish Target message functions from Runtime functions.
2021-01-24filter: Fix `let` binding syntaxTeddy Wing
2021-01-24main.lisp: Filter DevTools targets to chosen extensionsTeddy Wing
Filter a list of extension background page targets. The extension IDs should come from the command line, but I've hard-coded the list here. Increased the `sleep` time to allow time for the messages to be sent & received before the program exits. Will need to figure out a proper way to do this later.
2021-01-24main.lisp: Parse `Target.getTargets` responseTeddy Wing
Use `jsown` to parse the response from the `Target.getTargets` message. Get a list of `targetInfos` from the response. Extracting keys from the JSON result with `jsown:val` raises an `error` exception when the key is not present. Turn the exception into `nil` with the `json-obj-get` function.
2021-01-24Build executableTeddy Wing
Build an executable binary by dumping an SBCL image, using the method described in: https://lispcookbook.github.io/cl-cookbook/scripting.html#with-asdf
2021-01-23Send `Target.getTargets` messageTeddy Wing
Add a `sleep` just in case we need that to have time to print the message. Use the `jsown` project for JSON encoding and decoding.
2021-01-23Define Lisp packageTeddy Wing
Define the package so we can define things inside it.
2021-01-23main.lisp: Update testing WebSocket URLTeddy Wing
2021-01-20Add a foundation for a Common Lisp versionTeddy Wing
Trying to see if I can write the program in Common Lisp. Learned how to set up an .asd project file and started with some websocket client code based on the example in: https://github.com/fukamachi/websocket-driver#client-side Need to work out how to set up JSON interaction.
2021-01-20extreload: Try parsing `GetTargets` responseTeddy Wing
Tried to parse the response from the `GetTargets` message, but ended up with this error: thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("unknown variant `iframe`, expected one of `page`, `background_page`, `service_worker`, `browser`, `other`", line: 0, column: 0)', /Users/tw/.cargo/registry/src/github.com-1ecc6299db9ec823/headless_chrome-0.9.0/src/protocol/mod.rs:90:70 Looks like the `headless_chrome` library doesn't include "iframe" as a `TargetType`: https://docs.rs/headless_chrome/0.9.0/headless_chrome/protocol/target/enum.TargetType.html Will have to modify the library, use a different library, or write my own types to serialize & deserialize.
2021-01-17Try using the Chrome DevTools protocolTeddy Wing
Get the list of targets using the Chrome DevTools protocol. Going to use this to reload the specified extensions since it isn't possible using the Chrome extension `management` API.
2021-01-17Set up Native Messaging and reload extensionsTeddy Wing
Get the extension IDs from the Native Messaging host and reload the specified extensions. Also reload the current tab. Turns out this doesn't work the way I expected. It does disable and re-enable the extension, but it doesn't reload the extension as with `chrome.runtime.reload()`. This means the specified extension isn't reloaded with the latest code changes. Unfortunately, it looks like there's no API to do what I want, and unless there's some magic in the `chrome.debugger` API I'll have to give up on this project.
2021-01-17extreload: Send extension IDs to extensionTeddy Wing
Send hard-coded extension IDs to the companion extension to tell it to reload them. Start an event loop to keep the native host running indefinitely. We'll then be able to send extension IDs from a command line client to the native host over a Unix domain socket IPC.
2021-01-17Rename manifest.json to com.teddywing.extreload.jsonTeddy Wing
Use the reverse DNS name in the manifest to ensure that it's unique.
2021-01-17Add extreload/manifest.jsonTeddy Wing
Add Native Messaging host manifest. Use a temporary path until we come up with an install script that can reference a more permanent path.
2021-01-17manifest.json: Add public keyTeddy Wing
Allows us to get a permanent extension ID that we can refer to for Native Messaging (ID: pacpdcpgfbpkdpmhfaljffnfbdanmblh). Generated the key with: $ openssl rsa -in key.pem -pubout -outform DER 2>/dev/null | openssl base64 -A && echo Using the explanation provided by Rob W (https://stackoverflow.com/users/938089/rob-w) on Stack Overflow: https://stackoverflow.com/questions/23873623/obtaining-chrome-extension-id-for-development/23877974#23877974
2021-01-17Add native messaging host (new Rust v1.49.0 project)Teddy Wing
2021-01-17Add manifest.jsonTeddy Wing