-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use the built-in keyboard commands system #73
base: master
Are you sure you want to change the base?
Conversation
I'll have to test this, but being able to drop |
I use Firefox Dev Edition with my modification manually installed, and it has worked well for me. Something I hadn't fully tested was a cross-domain iframe, but I got that working with the latest changes. I tested in a CodePen (without saving it) using only this HTML: <iframe width=100% height=400 src=http://www.coconut.com.fj/contact/></iframe> |
The only issues are that any existing customised shortcut cannot be copied to to the updated version, and I set the default to one that does not conflict with the core 'bookmark all tabs'. Not sure about the best way to notify users of that. |
cab8032
to
e499201
Compare
Could you give it a whirl? https://github.com/Roy-Orbison/textern/releases/tag/v0.8b1 |
I'm still using this patched version, regularly, without issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this and apologies for the delay. I've taken it for a spin and it works great. I think we should move in this direction but we need to handle migration carefully. Add-ons are automatically updated by default, and we don't want users' shortcuts to break from one version to the next.
Hmm, I think we'll need to keep carrying the old approach temporarily but mark it as deprecated. Then we can remove it in a future version. I'm thinking something like:
- in the next release, roll this out and give users the chance to opt-in to test it
- if all goes well, in the next version, mark the previous shortcut setting as deprecated: one way we can do this is when the shortcut is pressed, we send a browser notification with the deprecation message and a link to a GitHub issue detailing the migration
- finally, in the next version (maybe after 3 months or so?), remove support for the previous shortcut setting
I can drive this change, but more immediately for this PR, let's restore support for the current approach.
@@ -19,7 +19,7 @@ function assertNoResponse(response) { | |||
} | |||
|
|||
function notifyError(error) { | |||
browser.notifications.create({ | |||
browser.notifications?.create({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like an unrelated change. Can you either remove it or add it as a separate commit with a commit message explaining it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When testing, and constantly reloading the add-on from the dev directory, the extension console did not work flawlessly. I added optional chaining in several places when some things did not appear to be working in the debugger.
@@ -17,7 +17,7 @@ function assertNoResponse(response) { | |||
} | |||
|
|||
function notifyError(error) { | |||
browser.notifications.create({ | |||
browser.notifications?.create({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too.
@@ -5,7 +5,7 @@ | |||
"manifest_version": 2, | |||
"version": "0.7", | |||
|
|||
"applications": { | |||
"browser_specific_settings": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was updating the manifest to use the shortcut APIs, it made sense to me to use the recommended keys for the whole document.
"commands": { | ||
"textern": { | ||
"suggested_key": { | ||
"default": "Shift+Alt+D" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about "Ctrl+Shift+F"? Looks like that's not taken by Firefox already, and is close to the current default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wary of any specifying any shortcut with a Ctrl in it. They are regularly commandeered by both applications, and software running at the desktop level. There aren't many spare Ctrl + Shift + Letter keys available to begin with, so you're practically guaranteed to annoy some of your users.
@@ -124,3 +124,16 @@ function onMessage(message, sender, respond) { | |||
} | |||
|
|||
browser.runtime.onMessage.addListener(onMessage); | |||
|
|||
browser.commands.onCommand.addListener(function(command) { | |||
if (command === 'textern') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I wonder if the shortcut name should be something more specific, in case we add others in the future. Though if I understand correctly the API docs, we should be free to change this identifier in a future version, so maybe that's OK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these names are internally namespaced to each extension to avoid such collisions. If you want to make it more reflective of the action, that's fine.
if (tabs?.length && tabs[0].id != browser.tabs.TAB_ID_NONE) { | ||
browser.tabs.sendMessage(tabs[0].id, {type: 'shortcut'}).then(assertNoResponse, logError); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not logError
here?
currentWindow: true, | ||
active: true | ||
}).then(function(tabs) { | ||
if (tabs?.length && tabs[0].id != browser.tabs.TAB_ID_NONE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the ?
here? From the docs, it should never be undefined.
function onMessage(message, sender, respond) { | ||
if (sender.id != "textern@jlebon.com") | ||
return; | ||
if (message.type == "set_text") | ||
if (message.type == 'shortcut') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's call this message register
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already effectively namespaced by sender.id
, so you can call it whatever. I think register
is a bit generic. In the context of code, I think of "registering" as attaching a listener, or in some way saying "I want to know about this event", not the occurrence of the relevant event.
if (shadowRoot && shadowRoot.activeElement) { | ||
return getActiveElement(shadowRoot.activeElement) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, didn't know about shadow roots before. Do you have an example page where a textarea on which you'd want to use Textern is actually nested under a shadow root?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it was only to ensure we attach to the right element. I read this answer on SO, and didn't want neglect pages that used more complex DOMs.
@@ -129,43 +128,37 @@ function setText(id, text) { | |||
fadeBackground(e); | |||
} | |||
|
|||
function getActiveElement(element = document.activeElement) { | |||
if (element.nodeName === 'IFRAME' || element.nodeName === 'FRAME') | |||
return null; // skip to allow child documents to handle shortcut |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using all_frames
and handling it like this here, would it be more elegant to recurse into it in this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite possibly, I don't recall if I tried that approach.
I like your idea of phasing in the new shortcut to preserve people's preferences. Might it be possible to push an update which still has a default shortcut, but uses |
@jlebon I had an idea for how to smooth out the migration, because I don't think the web extension API provides a way to differentiate updates from new installs, and it's possible to use your extension without setting any prefs. If you push a minor version where the only change ensures a setting is saved, such as a string containing the current version, then subsequent versions will be able to detect whether they are being updated or not, based on its presence or absence. They can then update the setting after any migration is performed. In the context of this PR, |
Ahh nice, hadn't realized
Hmm, we should be able to use the presence of the current Modifying the previous plan, how about something like this:
|
As per my previous comment, it's possible to use your extension without setting any prefs, so that key is not guaranteed to exist (I just tested this in a fresh profile). We can't know how many users rely on the default settings. Even if it's only a few, you wouldn't want to break their migration. Best to push an update that uses the existing shortcut system but also guarantees a value in the extension storage. That timeline seems like a good approach, as long as you do the above to differentiate new installs. I hope having both shortcut methods in the code at the same time doesn't cause conflicts. |
Just a note here before I forget, I stumbled upon https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onInstalled which looks like it'd be helpful here. |
@jlebon Well done. I looked for something like that, assuming it would be there but didn't find it. |
Registration and conflict resolution is simplified. Change default to one that's unused by Firefox itself. Simplifies code but requires an extra permission to find current tab.
e499201
to
c047e59
Compare
Using the
commands
manifest key simplifies registration and conflict resolution of shortcuts (the user automatically gets warnings about existing bindings). This also changes the default shortcut to one that's unused by Firefox itself. It does require an extra permission to find the current tab.