Age | Commit message (Collapse) | Author |
|
|
|
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.
|
|
Must have copy-pasted that s-expression from elsewhere in the file.
|
|
|
|
|
|
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.
|
|
|
|
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`.
|
|
|
|
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.
|
|
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.
|
|
Just learned that `string=` exists, and that seems to describe the
intent better than `equal`.
|
|
|
|
|
|
|
|
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.
|
|
Prefix the function name with the name of the DevTools domain to
distinguish Target message functions from Runtime functions.
|
|
|
|
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.
|
|
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.
|
|
Build an executable binary by dumping an SBCL image, using the method
described in:
https://lispcookbook.github.io/cl-cookbook/scripting.html#with-asdf
|
|
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.
|
|
Define the package so we can define things inside it.
|
|
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
Use the reverse DNS name in the manifest to ensure that it's unique.
|
|
Add Native Messaging host manifest. Use a temporary path until we come
up with an install script that can reference a more permanent path.
|
|
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
|
|
|
|
|