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

Firefox 57+ support / Turn VimFx into a WebExtension #860

Open
lydell opened this Issue Jan 7, 2017 · 42 comments

Comments

Projects
None yet
@lydell
Collaborator

lydell commented Jan 7, 2017

Note: VimFx is dead. It won't be updated for Firefox 57+. See README.md for more information.

Orginial post below. Warning! It contains some outdated stuff.


Firefox has several types of extensions. The newest type is called “WebExtensions.” Mozilla plans to stop supporting all other types than WebExtensions at the end of 2017.

See Mozilla’s blog post Add-ons in 2017 for more information.

VimFx is not a WebExtension.

The other types of extensions are very flexible. They can do almost anything. While that is really cool, it also holds back the development of Firefox. Wonder why multi-process Firefox took so long?

WebExtensions are not as powerful — yet. Mozilla seem to be open to adding new APIs, but it will take time.

VimFx will be maintained and continue to work like it does now as long as Mozilla supports the “legacy” types of extensions. But no new features will be added. The more features, the harder it will be to turn VimFx into a WebExtension.

For a couple of months, I looked into converting VimFx to a WebExtension. But I've lost the motivation.

So, for now I recommend supporting philc/vimium#2425.

I want to create a new extension with the best of VimFx. But I don't know when that will happen.

Here are a bunch of interesting links:

Summary:

  • You can use the current VimFx for the rest of 2017.
  • Then, Vimium is your best bet: philc/vimium#2425
  • VimFx is free software, so if somebody feels like converting it to a WebExtension they're totally free to do so! (But you're probably going to spend your time more wisely on Vimium.)
  • I hope to create a new add-on with the best parts from VimFx some day.
  • Firefox will become a better browser! It’s sad but worth the sacrifice.

lydell added a commit that referenced this issue Jan 7, 2017

@bhajneet bhajneet referenced this issue Feb 2, 2017

Closed

Single Character mode #862

4 of 8 tasks complete

@gulkily gulkily referenced this issue Feb 10, 2017

Closed

Unable to install in Seamonkey #863

6 of 11 tasks complete

@woctezuma woctezuma referenced this issue Mar 8, 2017

Closed

<s-escape> does not exit ignore mode #568 #871

6 of 11 tasks complete

@mingsu mingsu referenced this issue Mar 13, 2017

Closed

scroll in google inputbox suggestions #874

1 of 8 tasks complete

@losingkeys losingkeys referenced this issue Mar 18, 2017

Closed

Prevent autofocus on devdocs.io #875

6 of 11 tasks complete
@letientai299

This comment has been minimized.

Show comment
Hide comment
@letientai299

letientai299 Mar 28, 2017

Hi @akhodakivskiy, I've followed this topic for a while. Since there's nothing news recently, I wonder:

  • What is the current status of WebExtension VimFx versioon?
  • Where is the repo of WebExtension version? (So that we could learn and contribute)
  • When could we suggest new features for VimFx? The issue template still direct to this issue, which is clear that feature request are not accepted.

letientai299 commented Mar 28, 2017

Hi @akhodakivskiy, I've followed this topic for a while. Since there's nothing news recently, I wonder:

  • What is the current status of WebExtension VimFx versioon?
  • Where is the repo of WebExtension version? (So that we could learn and contribute)
  • When could we suggest new features for VimFx? The issue template still direct to this issue, which is clear that feature request are not accepted.

@e2dubba e2dubba referenced this issue Mar 28, 2017

Closed

Access to browser modules from config.js #880

4 of 11 tasks complete
@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Mar 28, 2017

Collaborator

Thanks for reaching out, @letientai299! Ive updated the issue description.

What is the current status of WebExtension VimFx versioon?

There is none.

Where is the repo of WebExtension version?

There is none.

When could we suggest new features for VimFx?

Never. (Or when a new maintainer decides that it would make sense.)

Collaborator

lydell commented Mar 28, 2017

Thanks for reaching out, @letientai299! Ive updated the issue description.

What is the current status of WebExtension VimFx versioon?

There is none.

Where is the repo of WebExtension version?

There is none.

When could we suggest new features for VimFx?

Never. (Or when a new maintainer decides that it would make sense.)

@f1u77y

This comment has been minimized.

Show comment
Hide comment
@f1u77y

f1u77y Mar 30, 2017

f1u77y commented Mar 30, 2017

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Mar 30, 2017

Collaborator

There could absolutely be a WebExtension version now: Vimium is living proof. But the keyboard shortcut handling is very different in WebExtensions, and more restricted. A WebExtension version will be similar but different. Never ever 100% the same.

Collaborator

lydell commented Mar 30, 2017

There could absolutely be a WebExtension version now: Vimium is living proof. But the keyboard shortcut handling is very different in WebExtensions, and more restricted. A WebExtension version will be similar but different. Never ever 100% the same.

@Noitidart Noitidart referenced this issue Apr 9, 2017

Closed

Move tab to previous window #883

4 of 12 tasks complete

githubpermutation added a commit to githubpermutation/VimFx that referenced this issue Apr 17, 2017

Pull from origin (#1)
* Fix unmousable bottom-right corner of the page scrollbars

VimFx's statuspanel (for notifications) had `pointer-events: auto;`
instead of `pointer-events: none;`, which statuspanels have by default.
The reason was to allow clicking the statuspanel to hide it.

This made it impossible to interact with the bottom-right corner of the
page scrollbars. The invisible statuspanel captured any clicks there.

This commit hides notifications when clicking _anything_ instead, and
removes `pointer-events: auto;`.

Fixes #787.

* Make it possible to create custom hint commands

My first idea was to use `vim.enterMode('hints', ...)`. However, that's
too complicated to be useful for any user.

Actually, I found that `vim.enterMode(...)` is too complicated for most
(all?) modes, so I decided to make it private (removing it from the
public API) while at it. (I also made the arguments of
`vim.enterMode`/`mode.onEnter` more consistent with each other.)

I also considered exposing the entire "API" that the `f` commands use
internally. However, that's more complicated than the average user
needs, and would increase the API surface _a lot._

Instead, the `f` commands now take a `callbackOverride` argument. This
lets you choose the `f` command that matches the elements you're looking
for and the override what happens when a hint marker is matched.

Fixes #785. Fixes #654.

* Fix broken `yv` command

Regression since commit c4c4173.

* Fix uncaught error on click in web page content

Introduced in commit 00eefb3.

* Update fr locale

Refs. #728

* Improve docs on "options object" with examples

See #791.

* Change default shortcuts for some hint commands

Many of the old ones were difficult to remember, and there was no space
for adding new ones.

Refs. #788.

* Change `zr` to `gC`

`zr` was the only shortcut starting with `z`. This frees that key up.

Refs. #788.

* Change `` ` `` into `'`

This is both for the `` ` `` shortcut (go to mark) and the `` ` `` mark
(last position). Both `` ` `` and `'` are used in Vim. `'` is a better
default, because it is easier to type -- both on an en-US QWERTY
keyboard and, more importantly, on some international layouts, such as
the sv-SE layout.

Refs. #788.

* Update devDependencies

* Fix documentation typos

* Document that VimFx overrides `'`

* VimFx v0.18.0

* Improve the `vimfx.addOptionOverrides` example

See #791.

* Prevent `vimfx.addOptionOverrides` from crashing on startup

Fixes #795.

* Partly revert "Use `prefs.get` directly in events-frame.coffee"

This partly reverts commit e7f3619.

That commit switched to using `prefs.get` directly in
events-frame.coffee instead of using `messageManager.get`. That avoids
synchronous messages, which is a good thing.

However, I forgot that when doing so, `vimfx.addOptionOverrides` won't
take effect.

This commit partly reverts to getting options via synchronous messages
again. In the very frequent 'keydown' event direct `prefs.get` is still
used for the unlikely-to-be-overridden `focus_previous_key` and
`focus_next_key` prefs, while synchronous messaging is used in the less
frequent 'focus' event, which enables the use case of overriding
`prevent_autofocus` on select pages.

* Minor documentation fixes. (#801)

* VimFx v0.18.1

* Improve hints support for CodeMirror

On https://gcc.godbolt.org/ the `<textarea>` that needs a hint is 0px
wide instead of the usual 1px.

* Fix initial visibility of second-pass hint markers

1. Go to a site where there is a noticeable delay between the two passes
   for the `f` command, such as on reddit.com.
2. Press a prefix hint char there before the second pass has completed.

When the second pass completes, the hint markers for that pass will be
shown, even though they cannot start with the prefix hint char you
pressed. This commit makes sure that the hint markers for the second
pass start out hidden if needed.

* Fix missing hint markers when re-entering Hints mode quickly

1. Enter Hints mode.
2. Press `<escape>` to exit it.
3. Press `f` to re-enter Hints mode within `hints_timeout` milliseconds.

This used to result in re-entering Hints mode as expected, but with no
hint markers on screen because of a timeout from the last Hints mode
session that removed the hints container. Removing the hints container
is done by ID for robustness, so it doesn't help that the hints
container actually is a new DOM element at that time.

This commit fixes the above problem, and makes the logic more robust.

In `onLeave` for Hints mode, it makes sense to always try to remove the
Hints container, so that it may not be accidentally be left on screen.
However, it does not make sense to do so after a timeout, which was
previously the case. Now, it is done _immediately_ instead.

The only case where he timeout is wanted, is when a hint marker just has
been matched. This commit also adds a check in that timeout callback that
Hints mode hasn't been re-entered before removing the hints container.

* Fix missing hint marker activation feedback for `v`

* Fix alphabetic sorting of functions in utils.coffee

* Add `gulp hints.html` to help styling hint markers

* Add UI to export, import and reset all prefs

See #262, #245, #267, #625, #802, #713.

* Add `gB` for quickly editing the blacklist

This also improves the description of the blacklist option, mentioning
that the patterns must match the _entire_ URL, since many people seem to
overlook this fact.

Fixes #593 and #677.

* Add `ep` for opening links in new private windows

Fixes #771.

* Add `ec` for opening the context menu of elements

Fixes #804.

* Make hint markers smaller

The hint markers are styled with `font: menu;` to get as close to the
user's system and preferences as possible. However, that turns out to be
slighly too big on all systems I've seen.

This commit still uses `font: menu;`, but then reduces the font size of
that to 80%, by using a clever CSS trick: `font: menu;` was moved to the
hints container, and the markers themselves use `font-size: 0.8em;`.

* Implement filtering hints by text and related changes

This brings several more or less breaking changes:

- Non-hint chars now filter hint markers by the text of their elements,
  using an algorithm similar to the location bar (split the search term
  on whitespace; all the items must occur in the search text, case
  insensitively, and may overlap). The matched text is highlighted on
  screen. If all remaining hints are the same, they are automatically
  activated. All of this can be turned off via prefs, though.

- Since space is used to filter hint markers by element text, the
  already existing `<space>` shortcut for rotating hint markers had to
  be changed. It is now `<c-space>`. (`<s-space>` remains unchanged.)

- Uppercase hint chars are now allowed. This is so that people who
  prefer filtering by text in the first hand can use uppercase hint
  chars. If mixed case is used, `text-transform: uppercase;` is not
  applied, to avoid confusion.

- Since using uppercase characters for filtering hint markers by element
  text and lowercase characters for hint chars (or vice versa) is now a
  thing, holding shift no longer lets you peek through the hint markers,
  because that felt like the markers blinking all the time. Instead, you
  now have to hold shift+control to peek through.

- Hint markers are now placed immediately to left of its element's text
  if it would cover the text otherwise. This is because when filtering
  hints by text, it can be quite difficult to see what to type
  otherwise. This also turned out to be helpful even when only using the
  hints (like before). It’s nice being able to see all the link text in
  many cases.

- Hint markers now get their `z-index` assigned based on their element's
  area, not their weight. It's confusing when a smaller element's hint
  cover the hint of a larger element. This could be the case where there
  are lots of small profile image links all with the same `href`.
  Previously, all those links got `z-index` based on their combined
  area. Now, their individual areas are used instead. This problem
  became apparent because of the above bullet point.

- The hint marker(s) with the best hint are now highlighted in blue.

- `<enter>` now activates the highlighted marker(s). `<c-enter>` and
  `<a-enter>` can be used to toggle where links open, just as when
  using those modifiers with the last hint char. However, these
  shortcuts were already taken, so the old ones had to be given new
  shortcuts:

  - "Increase count" now uses `<up>` (instead of `<enter>`).
  - "Toggle complementary" now uses `<c-backspace>` (instead of
    `<c-enter>`).

- All existing hints prefs were renamed from starting with `hint_` or
  `hints_` to starting with `hints.`, for consistency and organization.
  A few new prefs starting with `hints.` were added as well. Migrations
  are written for this.

  This also unveiled a problem. If a config file tries to set an old
  pref and VimFx is upgraded, the config file will throw errors. This is
  bad user experience, so a system for allowing old names was added.
  However, that might mean that users never notice that they use an
  outdated name and never update their config files. Therefore, old
  names are only allowed when the config file is loaded automatically
  (on startup), but _not_ when it is reloaded using `gC`. The idea is
  that people use `gC` while working on their config file, which usually
  involves fixing errors. Then they could just as well fix the old pref
  names as well.

- The options in VimFx's settings page in the Add-ons Manager have been
  slightly re-ordered to play better with the new options added, and to
  promote some very important prefs to the top.

All of the above required some significant refactoring of Hints mode,
that should make it more robust.

Fixes #340. A big thanks to @doy who got this all started with #789.

* Update dependencies

- vim-like-key-notation@1.0.1 simply has a smaller download size.

- n-ary-huffman@3.0.0 creates better hints for links with the same area.
  Instead of giving the _last_ of those the best hint, the _first_ one
  gets it.

* Show pref name for regular options in docs

* Don't hide changed notification when exiting Hints mode

For example, if the `f` command is used to click the "Export all" button
in VimFx's settings page in the Add-ons Manager, the export notification
was only visible until `hints.matched_timeout` had passed.

* Consistently refer to options as "options"

In documentation, UI and error messages, consistently refer to options
af "options", not "settings" and not "prefs".

* Improve `translations` documentation

* Improve styling documentation

* Properly hide notifications

In order to show the characters you have typed so far when filtering
hint markers by element text, commit ae106db changed the logic for when
notifications are hidden due to key presses.

Previously, notifications were hidden unconditionally when the pressed
key is not part of any shortcut, or caused a command to be run. Now, it
is up to every mode to deal with those cases. So that logic has
essentially been moved into Normal mode, and partly into Marks mode and
Caret mode as well.

The `<escape>` command now also explicitly hides notifications.

* Improve shortcuts documentation

* Improve notifications documentation

* Improve `gB` UX

If the page is _not_ blacklisted, everything stays the same.

If the page _is_ blacklisted, all matching blacklist patterns are moved
first and are delimited from all other patterns with several spaces.
There is also a new message for this case.

* Fix positioning of context menus inside frames

Take padding and border of the frame element into account.

This is for the `ec` command.

* Correctly suppress keys between `/` and find bar focus

Fixes #786.

* Improve hints after filtering by one element text char

1. Go to Reddit or Hackernews.
2. Press `f`.
3. Filter by one common element text character, such as "e".

Previously, that resulted in really terrible hints for most (of the
larger) elements. Basically, the difference in weight used for the
elements was so large, that all hint chars except the last were used as
single-char hints for the highest-weight elements. The same thing
happened for the hints starting with the last hint char; all hint chars
except the last were used for two-char hints. This resulted in some
really terrible hints like "VVVS". This looked very broken.

With this commit, the smallest elements still get the best hints after
filtering by element text, but the difference in the hints is not that
large.

* Improve Hints mode in various ways

- After having filtered hint markers by at least one character, select
  the entire text for the highlighted markers' elements. This makes it
  way easier to notice that you can stop typing and press `<enter>`
  instead to activate your desired hint marker.

- Because of the above point, it is now less important to make the
  highlighted hint markers stand out very much compared to other
  markers. So the styling has been changed to a more modest
  highlighting.

- Fixed: Links with the same href weren't getting the same hint after
  filtering hint markers by element text.

- Improved: After having filtered hint markers by element text, sort the
  markers by element text length, rather than element area. A large
  element might have less text than a smaller element.

- Improved: Don't allow typing more non-hint chars when all remaining
  markers have the same hint. This means less backspacing for the user
  in case of typos.

- Fixed: After having filtered hint markers by element text until all
  remaining markers have the same hint, _any_ hint char would activate
  the hint markers, even if that one didn't match the hint.

* Improve hint marker styling

- Increase contrast between the hint chars and the background color by
  changing the text color to fully black.

- Make the styling for hint markers for scrollable elements scale with
  the font size.

- Make highlighted hint markers more prominent. The changes in commit
  4bb0b56 made the difference _too_ subtle. While it looked pretty good
  on the computer I developed it on, the highlighting was almost
  invisible on a different screen. The new styling relies not solely on
  color, but also on border-radius, to increase the visual difference.

* Fix a case of being unable to filter hints by text

1. Disable the `hints.auto_activate` option.
2. Press `f`.
3. Filter hint markers by element text until only one link matches.
4. Press `<backspace>`.
5. Try to filter by element text again.

Result: Nothing happens. Previously, we got stuck in the `isMatched`
mode after deleting a typed char.

* Properly suppress keys and notifications in all modes

- Many modes previously forgot to suppress when getting a partial match
  for a command.

- Caret mode no correctly suppresses when entering a count.

- Ignore mode and Hints mode now explicitly make sure that notifications
  for counts are not shown in their `onInput` methods.

- The keys you've entered so far when filtering hint markers by element
  text now properly re-appear after the keys of a partial command match
  have been cleared due to the `timeout` option.

- `EnteredKeysManager` has been removed from events.coffee and has been
  merged into `Vim`, which turned out to be a nice refactor.

* Fix deleting hint char after filtering by text

1. Press `f`.
2. Filter hint markers by one element text char.
3. Press a hint char for a more-than-one-char hint.
4. Press `<backspace>`.

Result: The original hints are show, instead of only the ones show after
step 2. This commit fixes that.

* Simplify styling for highlighted markers

Let's try _only_ changing the background color, to bright green. This
particular green does stand out compared to other markers, and does not
obscure the text, in my opinion. Green is also commonly associated with
success -- in this case, having successfully filtered your way to a
specific link.

To make the above easier, I replaced the border and matched-char colors
with semi-transparent black, so that they work on the green background
as well.

* Remove unnecessary variables in modes.coffee

* Always treat the hint chars' case as-is

Since filtering hint markers by element text isn't available for the
`eb` command, the hint chars were previously treated as case insensitive
for that command. Similarly, they were also treated as case insensitive
when disabling the `hints.match_text` option.

However, the above led to numerous bugs. This commit simply gets rid of
that behavior, and keeps the hint chars consistent across all `f`
commands and options instead.

* Don't use wildcards with full URLs in the `gB` command

If there is no `location.host` available, such as for `about:*` and
`file://` pages, the _entire_ URL is used instead for the suggested
blacklist addition in the `gB` command. With this commit, such entire
URLs are no longer wrapped in `*` wildcards, as it makes no sense.

* Clarify the suggested blacklist pattern for `gB`

Clarify that the added pattern has not been saved yet, so that people
understand that the can simply dismiss the modal if they don't want to
edit the blacklist after all, without having to erase the added pattern
first.

* Fix validation of imported prefs: Don't allow array

* Improve wording for invalid prefs import message

* Improve error messages for the import prefs button

- Don't show "0 options imported successfully". That's confusing.
- Add an empty line between error messages.

* Improve zoom handling for hint markers

* Recognize explicit `tabindex="-1"` elements as focusable

This is especially helpful in the devtools, where many `<span>`s have
this attribute, but not much else to go for.

* Improve scrolling when holding h/l/j/k down

When you hold an arrow key down, the scrolling is sped up. With this
commit, the `h`, `l`, `j` and `k` do too, to be as close the the arrow
keys as possible.

Note that this includes a minor breaking API change: The object passed
to modes' `onInput`, and thus the object passed to commands, no longer
has the `uiEvent` property. Instead, there's an `event` property, which
_always_ is an `Event`. `vim.isUIEvent(event)` can be used to check if
it is a UI event or not.

* Only apply `vimfx.addKeyOverrides` in Normal mode

Previously, the key overrides were applied in _all_ modes, and the
current mode name was passed as the second argument to the matching
functions. However, it was way to easy to forget to also check the mode
in the matching functions (even the documentation forgot to!). For
example, if you added `j` as an override for some page, you then
couldn't press `j` in Hints mode to match a hint marker.

This commit fixes this problem by simply _only_ applying the key
overrides in Normal mode. I can't think of any use cases for wanting key
overrides in any other mode.

This is technically a minor breaking API change.

Fixes #812.

* Update help.html/hints.html `<title>`

* Update the readme and the documentation

This should make it easier and faster to find important features.

* Update devDependencies

* Update documentation example for custom modes

* VimFx v0.19.0

* Fix the `'` command crashing

* VimFx v0.19.1

* Add missing `return` after a `for` loop

* Improve config file documentation

Refs. #815.

* Update issue and PR templates

* Fix selection clipboard handling

This is only for systems with a "selection clipboard."

1. Copy text using one of the following methods:

   - `yv<hint>`
   - `av<hint>y`
   - `yf<hint>` on a contenteditable element

2. Use the `p` or `P` command.

Unlike other commands that copy text to the clipboard, such as `yy` and
`v<hint>wy`, the above methods previously didn't affect the selection
clipboard. This caused the `p` and `P` commands to operate on some other
text than expected.

This commit makes sure that all commands that copy text to the clipboard
also affect the selection clipboard (in a somewhat hacky, but working,
way).

Fixes #818.

* Fix z-index for hint markers

The hint markers are sorted by element area before assigning their
`z-index`es. This is so that the hint markers of larger elements appear
on top of hint markers for smaller elements. However,
`marker.wrapper.area` (which is `undefined`) was accidentally used
instead of `marker.wrapper.shape.area`. This caused the sorting to
essentially do nothing (since Firefox's `.sort` is stable).

* Fix the `'` mark after using `''`

The `'` mark is supposed to point to the location before the last
"jump." One such jump is using the `'` mark itself (by pressing `''`).
This means that running `''` several times in a row will flip back and
forth between two locations. However, that was previously broken. `''`
took you back to the last location, but then you got stuck there. This
commit fixes that bug.

Refs. #814.

* Remove unnecessary space

* Add the `/` mark

* Add `g[`, `g]` and a jump list

Fixes #814.

* VimFx v0.20.0

* Update devDependencies

Finally, no need to use a specific commit of CoffeeScript anymore!

* Update zh-CN locale (#820)

* Improve issue template change log link

* Tweak issue template

* Improve documentation for shortcut customization

See #823.

* Consistently refer to keypresses as "keypresses"

Not "key presses" and not "key press".

* Show error if trying to use a modifier in an invalid way

See #823.

* Improve documentation on re-mapping `<escape>`

Refs. #823.

* Fix text input refocus issue in GNOME

Previously, using a keyboard shortcut to switch keyboard layout in GNOME
while inside a text input caused the focus of that text input to be lost
when the prevent autofocus option was enabled.

Fixes #822.

* Make Caret browsing handling more robust

Make sure that people cannot end up with Caret mode accidentally
enabled.

Fixes #821.

* Clarify documentation on advanced options a bit

* Fix typo in package.json

* VimFx v0.20.1

* Update zh-CN locale (#824)

* Activate the hint marker for the largest element

* Fix element focusing with `f` commands

Fixes #825.

* Fix frame text input being focused when entering Caret mode

* Rename `skipBlurring` into `blur`

Negated options are confusing.

* Update devDependencies

* Update sv-SE locale

* VimFx v0.20.2

* Fix `<escape>` handling in Normal mode

When pressing `<escape>` inside a text input, `<escape>` is not supposed
to be passed on to the page (like is otherwise done), to allow blurring
text inputs inside modals without also closing the modal. There already
was logic for this, but it didn't work because the check for the
currently selected element and the running of the `<escape>` command was
run in the wrong order.

* Fix focusing scrollable elements using `f`

* Improve full page scrolling adjustment on some pages

On medium.com, there is a fixed footer. However, it is not
`position: fixed;` like fixed element usually are. Instead, it's
`position: absolute;` (and the page scroll is inside an adjacent element
instead of on `<html>`). This commit allows elements with
`position: absolute;` to as headers and footers as well.

* VimFx v0.20.3

* Improve links to the documentation index

* Fix the `n` and `N` commands in PDF.js tabs

Fixes #827.

* Fix `eb` not finding the tab bar overflow scroll buttons

Refs. #831.

* Document how to switch tabs

Refs. #831.

* Improve hint marker positioning

A pixel up, down, left or right _is_ visible. Using `Math.round` goes to
the most expected pixel. Previously, markers many times appeared to be
slightly too close to the top of elements, rather than at the center.

* Fix hint marker weights for the `eb` command

Refs. #831.

* Improve markable element area comparisons

Boxes that appear to be exactly the same size should be given "equally"
good hints, favoring earlier ones when needed. Sometimes, though, their
areas differ from a fraction of a pixel up to a couple of pixels.

This commits changes how the comparisons of marker weights (which
effectively are element areas), so that elements whose area differ by
less than 10px are considered to have the same area. That results in the
expected hints for same-sized boxes.

Refs. #831: The browser tabs often had this problem. At first, all tabs
could be given the expected hints: The first one getting the best one
etc. Opening a new tab, the best hint could suddenly be given to some
random tab in the middle.

* Make tab hints consistent for the `eb` command

Refs. #831.

* Make marker z-index rotation more functional-style

* Update devDependencies

* Fix highlighting of hint markers in the second pass

* Don't reset highlighted hint markers in the second pass

When injecting hint markers for the second pass, do reset which hint
markers are visually highlighted (in case they change), but _don't_
reset the actual data. Regression since commit e70ab84.

* Improve hints for the `eb` command

Tweak the hints for tab close buttons and non-tab elements. Continuation
aof commit d0cbbfd7.

* Find `<label>` elements in the first pass for `f`

It is common to implement custom styled checkboxes and radiobuttons by
hiding the actual `<input>` element and style its `<label>` instead.
Therefore it makes sense to find them in the first pass, so you don't
have to wait for their labels so long. This does not seem to degrade the
performance of the first pass.

* Blur the location bar consistently

Refs. #831: Let's say you added the custom command that focuses the
location bar, sets its text to '% ' and opens the autocomplete popup.
You set the shortcut to `q`. If you then press `q<escape>`, you'll end
up with '% ' being left in the location bar. Usually, the location bar
is cleared when blurring it. This is because of that the autocomplete
popup is open. This commit makes sure to close the location bar
autocomplete popup before blurring, fixing the problem.

* Add compatibility with the Tab Center add-on/experiment

Fixes #834.

* Always place markers next to text if appropriate

For example, the hint marker for buttons with centered text are now
placed just to the left of the text rather than at the left edge of
button. This is nice because it means that hint markers usually end up
where you were just reading.

* Update devDependencies

* VimFx v0.20.4

* Validate all config file API method arguments

This provides a better user experience and also prevents VimFx from
crashing due to invalid arguments.

Fixes #837.

* Improve holding keys for scrolling by page

Fixes #843.

* Fix tests in Firefox Nightly

Firefox have either moved the Assert.jsm module, or stopped exposing it.
I'm tired of that happening (it's not the first time), so I decided to
implement the small part of Assert.jsm that was actually used in VimFx's
test on my own. On the upside, this resulted in nicer error messages
when tests fail.

* Update devDependencies

* VimFx v0.20.5

* Improve hint marker position for multiline text

* Fix `ef` failing to focus elements in deeply nested frames

* Remove mentions of 1.0.0 in the documentation

* Fix the `'`, `g[` and `g]` commands crashing

Regression since commit d0d04fc.

Fixes #848.

* Properly clean up `addOptionOverrides` and `addKeyOverrides`

Fixes #849.

* Update de locale (#845)

* Update de translation for blacklist settings

Use word "Ausnahmen" ("Exception") for the blacklist description instead of using "Schwarze Liste". It could be considered to use "Exeptions" also for the english locale.

* Update de translation for auto activation

* Add more de translations

Tabs is also used mostly in german. Sometimes the word "Registerkarten" is used for that.

* Add new de translator to PEOPLE.md

* Update devDependencies

* VimFx v0.20.6

* Update de locale for "select most recent tab" (#852)

* Fix typo in issue template

* Find more elements for the `ef` command

This is basically a continuation of commit a3b2501:

> Recognize explicit `tabindex="-1"` elements as focusable

This is useful on Facebook, for example. See #859.

* Add ugly special-case for Facebook's "emoji picker"

Fixes #859.

* Add ugly special-case for Google prev/next page

Refs. #836.

* Feature requests are not accepted

See #860.

* Update devDependencies

* Update copyright years

* VimFx v0.20.7

* Properly remove frame scripts on shutdown

* Scroll closest scrollable parent

If you click a tweet on Twitter, a modal with the tweet as well as
responses to it pop up. That modal can be scrollable if there are enough
responses. The container for the main tweet is focused. It feels very
natural that the _modal_ should scroll when using VimFx commands, not
the page behind it. That used not to be the case, but now is. This was
implemented by not just checking if the active element _itself_ is
scrollable, but also whether one of its _parents_ are scrollable, and
using the closest scrollable parent (if any).

* Update devDependencies

* Update copyright years

* Update documentation for scrolling commands

* VimFx v0.20.8

* Fix the `yy` command in Reader View

Fixes #865.

* Update devDependencies

* Update copyright year

* VimFx v0.20.9

* Improve documentation referring to the issue tracker

* Update ja locale (#873)

* Prevent autofocus after 'popstate' events

Fixes #875.

* Use `vim.markPageInteraction()` instead of direct mutation

... of `vim.state.hasInteraction`.

* Update devDependencies

* Run `gulp sync-locales`

* Fix `vimfx.send` test

* Fix `selectAllSubstringMatches` test

* Fix lint error

* VimFx v0.20.10

* Mention testing in a new Firefox profile in the issue template

Closes #882.

* Try to avoid linking all new issues to issue #860

@mdibaiee mdibaiee referenced this issue Apr 20, 2017

Closed

Disable copy-on-delete #885

4 of 9 tasks complete
@Eremiell

This comment has been minimized.

Show comment
Hide comment
@Eremiell

Eremiell May 5, 2017

So I just noticed, my Firefox Nightly tagged VimFx as legacy today and came around to see, how things are. What I read here is a bunch of bad news.

I have Vimium installed in my Google Chrome and VimFx is one of the huge reasons I stick with Firefox. Even without VimFx I still wouldn't convert, as the other reasons add up, but it feels and works so much smoother and generally better.

I have no clear insight into how much work it is to convert VimFx or an other legacy add-on into the WebExtension, but I still really hope, this will happen.

Just wanted to personally thank you for all the hard work so far and show how much useful it is to me and certainly countless others and express my hopes it will survive this change.

Thank you and everyone who helped make this happen so far again.

Eremiell commented May 5, 2017

So I just noticed, my Firefox Nightly tagged VimFx as legacy today and came around to see, how things are. What I read here is a bunch of bad news.

I have Vimium installed in my Google Chrome and VimFx is one of the huge reasons I stick with Firefox. Even without VimFx I still wouldn't convert, as the other reasons add up, but it feels and works so much smoother and generally better.

I have no clear insight into how much work it is to convert VimFx or an other legacy add-on into the WebExtension, but I still really hope, this will happen.

Just wanted to personally thank you for all the hard work so far and show how much useful it is to me and certainly countless others and express my hopes it will survive this change.

Thank you and everyone who helped make this happen so far again.

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell May 5, 2017

Collaborator

I have no clear insight into how much work it is to convert VimFx or an other legacy add-on into the WebExtension, but I still really hope, this will happen.

Thanks for the positive words! But realistically, VimFx is basically dead. 😢

Collaborator

lydell commented May 5, 2017

I have no clear insight into how much work it is to convert VimFx or an other legacy add-on into the WebExtension, but I still really hope, this will happen.

Thanks for the positive words! But realistically, VimFx is basically dead. 😢

@Eremiell

This comment has been minimized.

Show comment
Hide comment
@Eremiell

Eremiell May 5, 2017

Is there any way I could possibly help? Most of my work happens in C++, but I probably can write an ECMAScript line or dozen. But I'm no expert on the domain, neither ECMAScript, nor browser plugins. Still would love to give a hand if possible.

Eremiell commented May 5, 2017

Is there any way I could possibly help? Most of my work happens in C++, but I probably can write an ECMAScript line or dozen. But I'm no expert on the domain, neither ECMAScript, nor browser plugins. Still would love to give a hand if possible.

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell May 5, 2017

Collaborator

Is there any way I could possibly help?

Nobody, including me, have "signed up" for doing this so far, so you wouldn't "help" but rather "do it all yourself". If you want to do that – great! You'd make lot's of people happy. Having worked on every single part of the code base, I can provide guidance to anyone who would like to try porting to a WebExtension a go. 👍

Collaborator

lydell commented May 5, 2017

Is there any way I could possibly help?

Nobody, including me, have "signed up" for doing this so far, so you wouldn't "help" but rather "do it all yourself". If you want to do that – great! You'd make lot's of people happy. Having worked on every single part of the code base, I can provide guidance to anyone who would like to try porting to a WebExtension a go. 👍

@Eremiell

This comment has been minimized.

Show comment
Hide comment
@Eremiell

Eremiell May 5, 2017

I'm not sure, I'm the right person to push the whole thing through as I haven't done any major ECMAScript since 90s before the whole "block scripting in your browser" movement (which was huge at least locally), which turned me other ways. I may look into WebExtensions docs (there are some, right?) once I have an hour or two to see what it actually expects. I have agreed before to go ahead on projects I had no technical knowledge about and if it gave me one thing, it was to look into it before whenever possible.

I'd love to see VimFx to roll on and if I find out, I'm able to help that, be it rewrite it myself, I'll give it my best. But don't put up bets on that yet. If anyone else feels like pushing it forward, someone with more experience in ECMAScript and browser extensions, I'll gladly assist.

Eremiell commented May 5, 2017

I'm not sure, I'm the right person to push the whole thing through as I haven't done any major ECMAScript since 90s before the whole "block scripting in your browser" movement (which was huge at least locally), which turned me other ways. I may look into WebExtensions docs (there are some, right?) once I have an hour or two to see what it actually expects. I have agreed before to go ahead on projects I had no technical knowledge about and if it gave me one thing, it was to look into it before whenever possible.

I'd love to see VimFx to roll on and if I find out, I'm able to help that, be it rewrite it myself, I'll give it my best. But don't put up bets on that yet. If anyone else feels like pushing it forward, someone with more experience in ECMAScript and browser extensions, I'll gladly assist.

@lydell lydell referenced this issue May 6, 2017

Closed

Implement "ZZ" as "save and exit" #853

5 of 8 tasks complete
@braham-snyder

This comment has been minimized.

Show comment
Hide comment
@braham-snyder

braham-snyder May 7, 2017

another alternative is qutebrowser (it's not Firefox, but that's of course better in some ways: it's unencumbered by WebExtensions, for example), whose author just funded a kickstarter (that hasn't ended yet) to work full-time on v1.0

braham-snyder commented May 7, 2017

another alternative is qutebrowser (it's not Firefox, but that's of course better in some ways: it's unencumbered by WebExtensions, for example), whose author just funded a kickstarter (that hasn't ended yet) to work full-time on v1.0

@f1u77y

This comment has been minimized.

Show comment
Hide comment
@f1u77y

f1u77y May 8, 2017

I'd like to try translating (subset of?) VimFx to WebExtension. I know that Vimium exists but their main goal is to support Chrome and not to struggle with non-trivial Firefox incompatibilities. And I do also like the VimFx way(extensive usage of default browser features instead of reinventing the wheel).

I've looked into the code but I have now some questions to @lydell:

  1. AFAIK features like "focus some browser element" are dead due to nature of WebExtensions. That could be main reason for Vimium authors to implement their own UI for opening pages(which I don't like). Could there be any progress in the related issue?
  2. I cannot understand how does the smooth scrolling work. As I can see it calls element.scrollBy({ top: someNumber, behaviour: 'smooth' }) but when I try to call it from the console, scrolling is not smooth.

f1u77y commented May 8, 2017

I'd like to try translating (subset of?) VimFx to WebExtension. I know that Vimium exists but their main goal is to support Chrome and not to struggle with non-trivial Firefox incompatibilities. And I do also like the VimFx way(extensive usage of default browser features instead of reinventing the wheel).

I've looked into the code but I have now some questions to @lydell:

  1. AFAIK features like "focus some browser element" are dead due to nature of WebExtensions. That could be main reason for Vimium authors to implement their own UI for opening pages(which I don't like). Could there be any progress in the related issue?
  2. I cannot understand how does the smooth scrolling work. As I can see it calls element.scrollBy({ top: someNumber, behaviour: 'smooth' }) but when I try to call it from the console, scrolling is not smooth.
@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell May 9, 2017

Collaborator

@f1u77y Awesome!

  1. Yep, "Click browser element" is dead, and won't come back, and yes, this is the main reason for Vimium re-implementing UI stuff. You'll have to look at bugzilla for progress on potential APIs for such things, but I haven't seen anything there lately, and I actually don't expect any progress either. For now, all commands that simply can't be done must be dropped.

  2. Smooth scrolling uses element.scrollBy({ top: someNumber, behaviour: 'smooth' }), that's correct. (Search for "spring" through the entire codebase and you'll find everything you need to know, including documentation.) In other words, VimFx uses the web standard for "native" smooth scrolling. Unfortunately, the default scrolling speed is a bit too slow. The speed can be adjusted using the layout.css.scroll-behavior.spring-constant in about:config, though, so VimFx temporarily sets that pref to a different value while scrolling. Chances are that VimFx has failed to reset that pref to the previous value again some time, which might be why you don't see the smooth scrolling when running the code in the console. Try resetting it, and then run document.documentElement.scrollBy({top: -100, behavior: 'smooth'}) in the console on this page; that should scroll 100px up smoothly (it does for me at least). A WebExtension can't set the layout.css.scroll-behavior.spring-constant pref temporarily though, so you would need to implement your own smooth scrolling, like Vimium does. That might be good anyway, since the current setup is a bit hacky and many people prefer Vimium's "scroll without stopping" behavior: #811.

I'd say that the biggest challenges for a WebExtension version of VimFx are:

  • Content scripts can no longer reach into every frame. So instead of loading one single content script per tab, we need to load one content script into every frame and have them communicate with each other. This affects event listeners and DOM element finding. (big change)
  • Key handling can no longer be done in the main Firefox process, only in content scripts. (somewhat big change)
  • Smooth scrolling needs to be manually implemented. (meh, but needs to be done)
  • Caret mode uses Firefox's own caret mode. A WebExtension can't do that, so Caret mode will need some re-thinking. (big change)
  • Currently, Firefox's built-in UI for VimFx's settings is used. As a WebExtension, all UI must be manually implemented. (kinda easy, but also easy to get carried away)
  • Taking decisions on all trade-offs and workarounds needed to get the VimFx experience as a WebExtension. (again, easy to get carried away)
Collaborator

lydell commented May 9, 2017

@f1u77y Awesome!

  1. Yep, "Click browser element" is dead, and won't come back, and yes, this is the main reason for Vimium re-implementing UI stuff. You'll have to look at bugzilla for progress on potential APIs for such things, but I haven't seen anything there lately, and I actually don't expect any progress either. For now, all commands that simply can't be done must be dropped.

  2. Smooth scrolling uses element.scrollBy({ top: someNumber, behaviour: 'smooth' }), that's correct. (Search for "spring" through the entire codebase and you'll find everything you need to know, including documentation.) In other words, VimFx uses the web standard for "native" smooth scrolling. Unfortunately, the default scrolling speed is a bit too slow. The speed can be adjusted using the layout.css.scroll-behavior.spring-constant in about:config, though, so VimFx temporarily sets that pref to a different value while scrolling. Chances are that VimFx has failed to reset that pref to the previous value again some time, which might be why you don't see the smooth scrolling when running the code in the console. Try resetting it, and then run document.documentElement.scrollBy({top: -100, behavior: 'smooth'}) in the console on this page; that should scroll 100px up smoothly (it does for me at least). A WebExtension can't set the layout.css.scroll-behavior.spring-constant pref temporarily though, so you would need to implement your own smooth scrolling, like Vimium does. That might be good anyway, since the current setup is a bit hacky and many people prefer Vimium's "scroll without stopping" behavior: #811.

I'd say that the biggest challenges for a WebExtension version of VimFx are:

  • Content scripts can no longer reach into every frame. So instead of loading one single content script per tab, we need to load one content script into every frame and have them communicate with each other. This affects event listeners and DOM element finding. (big change)
  • Key handling can no longer be done in the main Firefox process, only in content scripts. (somewhat big change)
  • Smooth scrolling needs to be manually implemented. (meh, but needs to be done)
  • Caret mode uses Firefox's own caret mode. A WebExtension can't do that, so Caret mode will need some re-thinking. (big change)
  • Currently, Firefox's built-in UI for VimFx's settings is used. As a WebExtension, all UI must be manually implemented. (kinda easy, but also easy to get carried away)
  • Taking decisions on all trade-offs and workarounds needed to get the VimFx experience as a WebExtension. (again, easy to get carried away)
@senden9

This comment has been minimized.

Show comment
Hide comment
@senden9

senden9 May 9, 2017

@lydell: To point 1: What is with the HTMLElement.click() method? It seems to be a DOM standard. Is it not possible to call this from webextensions? (I have to say that i never before programmed a webextension)

senden9 commented May 9, 2017

@lydell: To point 1: What is with the HTMLElement.click() method? It seems to be a DOM standard. Is it not possible to call this from webextensions? (I have to say that i never before programmed a webextension)

@The-Compiler

This comment has been minimized.

Show comment
Hide comment
@The-Compiler

The-Compiler May 9, 2017

@senden9 That's for web elements, not browser UI things.

The-Compiler commented May 9, 2017

@senden9 That's for web elements, not browser UI things.

@f1u77y

This comment has been minimized.

Show comment
Hide comment
@f1u77y

f1u77y May 9, 2017

so VimFx temporarily sets that pref to a different value while scrolling

Yes, that was my fault. I've set the spring constant to VimFx value and made it work. Thanks!

you would need to implement your own smooth scrolling

What's the problem with instructing user to set it himself? Yes, that's not smooth scrolling out of box, but that works the same as default Firefox scrolling and I don't think adding any solutions that browser already has is a good idea except if they are notably different from browser ones.

Extensive usage of default UI with modified keyboard shortcuts was the main reason behind using this extension for me.

f1u77y commented May 9, 2017

so VimFx temporarily sets that pref to a different value while scrolling

Yes, that was my fault. I've set the spring constant to VimFx value and made it work. Thanks!

you would need to implement your own smooth scrolling

What's the problem with instructing user to set it himself? Yes, that's not smooth scrolling out of box, but that works the same as default Firefox scrolling and I don't think adding any solutions that browser already has is a good idea except if they are notably different from browser ones.

Extensive usage of default UI with modified keyboard shortcuts was the main reason behind using this extension for me.

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell May 9, 2017

Collaborator

What's the problem with instructing user to set it himself?

Different commands unfortunately need different values.

Collaborator

lydell commented May 9, 2017

What's the problem with instructing user to set it himself?

Different commands unfortunately need different values.

@chetgurevitch

This comment has been minimized.

Show comment
Hide comment
@chetgurevitch

chetgurevitch May 16, 2017

Chromium-vim has vimfx-like smooth scrolling, (I believe this is the relevant code).

Could that be applicable?

chetgurevitch commented May 16, 2017

Chromium-vim has vimfx-like smooth scrolling, (I believe this is the relevant code).

Could that be applicable?

@eejdoowad

This comment has been minimized.

Show comment
Hide comment
@eejdoowad

eejdoowad May 17, 2017

So... I happened to work on smooth scrolling today in my keybinding extension. cVim's smooth scrolling works, but pauses for a split second after the first keypress. Vimium's smooth scrolling works great, but doesn't make sense. Have a look at how I do it. Also take a look at the smooth scroll polyfill.

eejdoowad commented May 17, 2017

So... I happened to work on smooth scrolling today in my keybinding extension. cVim's smooth scrolling works, but pauses for a split second after the first keypress. Vimium's smooth scrolling works great, but doesn't make sense. Have a look at how I do it. Also take a look at the smooth scroll polyfill.

@eejdoowad

This comment has been minimized.

Show comment
Hide comment
@eejdoowad

eejdoowad May 17, 2017

I'm building a keybinding web extension that derives from existing ones like Vimium, cVim, and VimFX. I want to address some of the challenges you mentioned:

Content scripts can no longer reach into every frame. So instead of loading one single content script per tab, we need to load one content script into every frame and have them communicate with each other. This affects event listeners and DOM element finding.

This complicates things a lot, but is manageable, (as shown by cVim and Vimium). You have to make sure to

  1. load the content script into every frame
  2. listen for events in all frames
  3. message between frames to access information and send commands.

An example is link hints. When you press F, you expect to see link hints for all visible elements, including those in frames. Only one frame will detect the F keydown event. It then messages all frames in the current tab telling them to find the hintable elements. Each frame messages back the total number of hintable elements found, and the total number is sent back to each frame so that the correct string can be rendered in the link hint.

Key handling can no longer be done in the main Firefox process, only in content scripts.

We're stuck with native DOM events... as you've no doubt discovered. This isn't too hard to work around, but... there will definitely be corner cases that will be hard to cover. E.g. Google Groups keyboard shortcuts are captured and might run before listeners installed by the extension.

Smooth scrolling needs to be manually implemented.

Piece of cake

Currently, Firefox's built-in UI for VimFx's settings is used. As a WebExtension, all UI must be manually implemented.

True. The options page is typically just an html page which saves stuff to local storage. Should be easy to port the firefox UI's functionality.

Taking decisions on all trade-offs and workarounds needed to get the VimFx experience as a WebExtension.

Are there any notable differences between VimFx and Vimium/cVim? Anything VimFX has that you feel those don't quite replicate?

Also, are there any docs on VimFx's architecture? How do you keep track of which mode is active? Vimium has its handler stack, cVim has variables and conditions, I use a state machine, what does VimFx do?

Also, have any tips on making link hints better?

One last also, VimFx is the only one i've noticed that addresses quirks mode behavior. Anything major to watch out for?

eejdoowad commented May 17, 2017

I'm building a keybinding web extension that derives from existing ones like Vimium, cVim, and VimFX. I want to address some of the challenges you mentioned:

Content scripts can no longer reach into every frame. So instead of loading one single content script per tab, we need to load one content script into every frame and have them communicate with each other. This affects event listeners and DOM element finding.

This complicates things a lot, but is manageable, (as shown by cVim and Vimium). You have to make sure to

  1. load the content script into every frame
  2. listen for events in all frames
  3. message between frames to access information and send commands.

An example is link hints. When you press F, you expect to see link hints for all visible elements, including those in frames. Only one frame will detect the F keydown event. It then messages all frames in the current tab telling them to find the hintable elements. Each frame messages back the total number of hintable elements found, and the total number is sent back to each frame so that the correct string can be rendered in the link hint.

Key handling can no longer be done in the main Firefox process, only in content scripts.

We're stuck with native DOM events... as you've no doubt discovered. This isn't too hard to work around, but... there will definitely be corner cases that will be hard to cover. E.g. Google Groups keyboard shortcuts are captured and might run before listeners installed by the extension.

Smooth scrolling needs to be manually implemented.

Piece of cake

Currently, Firefox's built-in UI for VimFx's settings is used. As a WebExtension, all UI must be manually implemented.

True. The options page is typically just an html page which saves stuff to local storage. Should be easy to port the firefox UI's functionality.

Taking decisions on all trade-offs and workarounds needed to get the VimFx experience as a WebExtension.

Are there any notable differences between VimFx and Vimium/cVim? Anything VimFX has that you feel those don't quite replicate?

Also, are there any docs on VimFx's architecture? How do you keep track of which mode is active? Vimium has its handler stack, cVim has variables and conditions, I use a state machine, what does VimFx do?

Also, have any tips on making link hints better?

One last also, VimFx is the only one i've noticed that addresses quirks mode behavior. Anything major to watch out for?

@f1u77y

This comment has been minimized.

Show comment
Hide comment
@f1u77y

f1u77y May 17, 2017

@eejdoowad

Are there any notable differences between VimFx and Vimium/cVim? Anything VimFX has that you feel those don't quite replicate?

I'd like to note:

  • VimFx uses Firefox native scrolling while Vimium uses its own
  • VimFx uses Firefox native UI while Vimium uses its own
  • VimFx is customizable with config file while Vimium is not

f1u77y commented May 17, 2017

@eejdoowad

Are there any notable differences between VimFx and Vimium/cVim? Anything VimFX has that you feel those don't quite replicate?

I'd like to note:

  • VimFx uses Firefox native scrolling while Vimium uses its own
  • VimFx uses Firefox native UI while Vimium uses its own
  • VimFx is customizable with config file while Vimium is not
@eejdoowad

This comment has been minimized.

Show comment
Hide comment
@eejdoowad

eejdoowad May 17, 2017

  • Is native scrolling better? People don't like webpages hijacking scroll behavior because it's unexpected, but they know exactly how their keybinding extension scrolls.
  • If you want, you can replicate something that looks native. Is the UI a driving factor for why people use VimFx?
  • True. Just want to clarify, is it the ability to modify configurations with text that's important? Or the ability to save and restore your configuration? In my extension, I allow users to create and switch between settings profiles, e.g. sometimes they want to use both hands, other times they want to use only their left hand. This makes text configurations a little bit more complicated.

eejdoowad commented May 17, 2017

  • Is native scrolling better? People don't like webpages hijacking scroll behavior because it's unexpected, but they know exactly how their keybinding extension scrolls.
  • If you want, you can replicate something that looks native. Is the UI a driving factor for why people use VimFx?
  • True. Just want to clarify, is it the ability to modify configurations with text that's important? Or the ability to save and restore your configuration? In my extension, I allow users to create and switch between settings profiles, e.g. sometimes they want to use both hands, other times they want to use only their left hand. This makes text configurations a little bit more complicated.
@f1u77y

This comment has been minimized.

Show comment
Hide comment
@f1u77y

f1u77y May 17, 2017

  • No but it's just more familiar to me then Vimium's one. Anyway I haven't noticed great difference.
  • Personally for me native UI was a driving factor for migrating here from Vimperator. Replicating is not solution. lydell has created some API proposals for Mozilla about this but the issue is still open.
  • Multiple profiles is great idea! About textual config: I use VimFx configuration for something like "userscripts" which add some shortcuts for certain pages or remove them for using pages' ones.

f1u77y commented May 17, 2017

  • No but it's just more familiar to me then Vimium's one. Anyway I haven't noticed great difference.
  • Personally for me native UI was a driving factor for migrating here from Vimperator. Replicating is not solution. lydell has created some API proposals for Mozilla about this but the issue is still open.
  • Multiple profiles is great idea! About textual config: I use VimFx configuration for something like "userscripts" which add some shortcuts for certain pages or remove them for using pages' ones.
@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell May 17, 2017

Collaborator

Thanks for your input, @eejdoowad!

Are there any notable differences between VimFx and Vimium/cVim? Anything VimFX has that you feel those don't quite replicate?

I can't really say anything about cVim, but I can make some comparisons with Vimium.

First I'd like to address the three points brought up by @f1u77y. In my opinion, those points are not very important at all.

  • "VimFx uses Firefox native scrolling while Vimium uses its own"

    I've never had any issues with Vimium's scrolling. I'm confident that a custom implementation will be just as good or better.

  • "VimFx uses Firefox native UI while Vimium uses its own"

    This isn't really about Vimium vs. VimFx, but about Chrome vs. Firefox. And now when Firefox drops support for interacting with most UI it's not relevant anymore.

  • "VimFx is customizable with config file while Vimium is not"

    To me, the text format is not really that important. It should be easy to backup and sync all settings, and be possible to add custom commands. It's good if the export format can be read and modified by hand. But I prefer the UI when customizing VimFx – it helps me get the command names and key syntax right.

My favorite features of VimFx that aren't in Vimium are:

  • Subtle differences in Hints mode.

    • VimFx tries to give you shorter hints for elements that you are more likely to click. If two elements are equally probable, the earlier one wins (this involves edge cases with one-off pixel calculations and stuff).
    • If hints overlap, the "better" hint is on top.
    • Lots of edge cases for finding clickable elements is covered.
    • VimFx tries to put the hint markers right next to the text of links and buttons, without covering the text itself (rather than putting them in the top-left corner).
    • VimFx tries really hard to only show hints for visible elements.
    • VimFx takes the performance challenge of Hints mode seriously and has a two-phase system to speed things up (most links show up quickly, the rest a little bit later).
    • No need to choose between "regular old hints mode" and "type the text of links and use number hints as a fallback" mode. VimFx simply uses any typed non-hint-char keys to match by link text. Super useful for me who prefers "regular old hints mode" but occasionally match by link text (especially for pagination number links). Those who prefer matching by text simply change their hint chars to all numbers or all uppercase or something.
    • Hold shift+ctrl to peek through markers.
    • If the element for a marker moves, the marker moves as well.

    Read more about Hints mode.

  • Being able to enter Caret mode by using hints: v for placing the cursor at any element, av for also selecting the entire element, and yv for copying the element text without even entering Caret mode. I use all three all the time. Read more about Caret mode.

  • Robust key handling, through vim-like-key-notation. It features a well-defined syntax for shortcuts, and the "Ignore keyboard layout" option which is very useful to people who use several keyboard layouts. Read more about shortcuts.

  • All keys of every mode are customizable, not just Normal mode.

  • You can focus any scrollable element and scroll it using the regular VimFx scrolling commands.

  • Blacklisting really means "Enter Ignore mode by default", which means that you can still opt in to a short burst of VimFx usage on a blacklisted site if you want to.

  • The help dialog uses the entire screen and shows you every single available shortcut. You can even search in it!

  • Custom commands.

You can also search for VimFx in the Vimium issue tracker to find VimFx differences.

Also, are there any docs on VimFx's architecture?

Other than that, there's not much more documentation on the architecture itself than the summarizing comment at the beginning of each file.

How do you keep track of which mode is active?

VimFx has one object for tracking global state (the VimFx class). Then, there's one object per tab keeping track of tab specific state (the Vim class). The current mode is tab specific, so it is stored on the Vim objects. The .name property on a Vim instance is simply the string name of the current mode. Each mode is simply an object that implement certain methods, such as onEnter(), onLeave() and onInput() (see modes.coffee and Mode object). Vim::_enterMode(modeStringName) is used to switch mode.

Also, have any tips on making link hints better?

Plenty. Hints mode is what I've spent the most time on in VimFx. See my comparison with Vimium above. I'm more than happy sharing what I've learned about it, so feel free to ask questions! Here are some links:

  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/markable-elements.coffee
  • helper_follow = (options, matcher, {vim, pass}) ->
    {id, combine = true, selectors = FOLLOW_DEFAULT_SELECTORS} = options
    if vim.content.document instanceof XULDocument
    selectors = ['*']
    if pass == 'auto'
    pass = if selectors.length == 2 then 'first' else 'single'
    vim.state.markerElements = [] if pass in ['single', 'first']
    hrefs = {}
    filter = (element, getElementShape) ->
    type = matcher({vim, element, getElementShape})
    if vim.hintMatcher
    type = vim.hintMatcher(id, element, type)
    if pass == 'complementary'
    type = if type then null else 'complementary'
    return unless type
    shape = getElementShape(element)
    unless shape.nonCoveredPoint then switch
    # CodeMirror editor uses a tiny hidden textarea positioned at the caret.
    # Targeting those are the only reliable way of focusing CodeMirror
    # editors, and doing so without moving the caret.
    when id == 'normal' and element.localName == 'textarea' and
    element.ownerGlobal == vim.content
    rect = element.getBoundingClientRect()
    # Use `.clientWidth` instead of `rect.width` because the latter includes
    # the width of the borders of the textarea, which are unreliable.
    if element.clientWidth <= 1 and rect.height > 0
    shape = {
    nonCoveredPoint: {
    x: rect.left
    y: rect.top + rect.height / 2
    offset: {left: 0, top: 0}
    }
    area: rect.width * rect.height
    }
    # Putting a large `<input type="file">` inside a smaller wrapper element
    # with `overflow: hidden;` seems to be a common pattern, used both on
    # addons.mozilla.org and <https://blueimp.github.io/jQuery-File-Upload/>.
    when id in ['normal', 'focus'] and element.localName == 'input' and
    element.type == 'file' and element.parentElement?
    parentShape = getElementShape(element.parentElement)
    shape = parentShape if parentShape.area <= shape.area
    if not shape.nonCoveredPoint and pass == 'complementary'
    shape = getElementShape(element, -1)
    return unless shape.nonCoveredPoint
    text = utils.getText(element)
    originalRect = element.getBoundingClientRect()
    length = vim.state.markerElements.push({element, originalRect})
    wrapper = {
    type, text, shape,
    combinedArea: shape.area
    elementIndex: length - 1
    parentIndex: null
    }
    if wrapper.type == 'link'
    {href} = element
    wrapper.href = href
    # Combine links with the same href.
    if combine and wrapper.type == 'link' and
    # If the element has an 'onclick' attribute we cannot be sure that all
    # links with this href actually do the same thing. On some pages, such
    # as startpage.com, actual proper links have the 'onclick' attribute,
    # so we can’t exclude such links in `utils.isProperLink`.
    not element.hasAttribute?('onclick') and
    # GitHub’s diff expansion buttons are links with both `href` and
    # `data-url`. They are JavaScript-powered using the latter attribute.
    not element.hasAttribute?('data-url')
    if href of hrefs
    parent = hrefs[href]
    wrapper.parentIndex = parent.elementIndex
    parent.combinedArea += wrapper.shape.area
    parent.numChildren += 1
    else
    hrefs[href] = wrapper
    return wrapper
    selector =
    if pass == 'complementary'
    '*'
    else
    selectors[if pass == 'second' then 1 else 0]
    return {
    wrappers: markableElements.find(vim.content, filter, selector)
    viewport: viewportUtils.getWindowViewport(vim.content)
    pass
    }
    commands.follow = helper_follow.bind(
    null, {id: 'normal'},
    ({vim, element, getElementShape}) ->
    document = element.ownerDocument
    isXUL = (document instanceof XULDocument)
    type = null
    switch
    # Bootstrap. Match these before regular links, because especially slider
    # “buttons” often get the same hint otherwise.
    when element.hasAttribute?('data-toggle') or
    element.hasAttribute?('data-dismiss') or
    element.hasAttribute?('data-slide') or
    element.hasAttribute?('data-slide-to')
    type = 'clickable'
    when isProperLink(element)
    type = 'link'
    when isTypingElement(element)
    type = 'text'
    when element.localName in ['a', 'button'] or
    element.getAttribute?('role') in CLICKABLE_ARIA_ROLES or
    # <http://www.w3.org/TR/wai-aria/states_and_properties>
    element.hasAttribute?('aria-controls') or
    element.hasAttribute?('aria-pressed') or
    element.hasAttribute?('aria-checked') or
    (element.hasAttribute?('aria-haspopup') and
    element.getAttribute?('role') != 'menu')
    type = 'clickable'
    when utils.isFocusable(element) and
    # Google Drive Documents. The hint for this element would cover the
    # real hint that allows you to focus the document to start typing.
    element.id != 'docs-editor'
    type = 'clickable'
    when element != vim.state.scrollableElements.largest and
    vim.state.scrollableElements.has(element)
    type = 'scrollable'
    when element.hasAttribute?('onclick') or
    element.hasAttribute?('onmousedown') or
    element.hasAttribute?('onmouseup') or
    element.hasAttribute?('oncommand') or
    # Twitter.
    element.classList?.contains('js-new-tweets-bar') or
    element.hasAttribute?('data-permalink-path') or
    # Feedly.
    element.hasAttribute?('data-app-action') or
    element.hasAttribute?('data-uri') or
    element.hasAttribute?('data-page-action') or
    # Google Drive Document.
    element.classList?.contains('kix-appview-editor')
    type = 'clickable'
    # Facebook comment fields.
    when element.parentElement?.classList?.contains('UFIInputContainer')
    type = 'clickable-special'
    # Putting markers on `<label>` elements is generally redundant, because
    # its `<input>` gets one. However, some sites hide the actual `<input>`
    # but keeps the `<label>` to click, either for styling purposes or to keep
    # the `<input>` hidden until it is used. In those cases we should add a
    # marker for the `<label>`. Trying to access `.control` on an element in
    # `about:config` throws an error, so exclude XUL pages.
    when not isXUL and element.localName == 'label' and element.control and
    not getElementShape(element.control).nonCoveredPoint
    type = 'clickable'
    # Last resort checks for elements that might be clickable because of
    # JavaScript.
    when (not isXUL and
    # It is common to listen for clicks on `<html>` or `<body>`. Don’t
    # waste time on them.
    element not in [document.documentElement, document.body]) and
    (utils.includes(element.className, 'button') or
    utils.includes(element.getAttribute?('aria-label'), 'close') or
    # Do this last as it’s a potentially expensive check.
    (utils.hasEventListeners(element, 'click') and
    # Twitter. The hint for this element would cover the hint for
    # showing more tweets.
    not element.classList?.contains('js-new-items-bar-container')))
    # Make a quick check for likely clickable descendants, to reduce the
    # number of false positives. the element might be a “button-wrapper” or
    # a large element with a click-tracking event listener.
    unless element.querySelector?('a, button, input, [class*=button]')
    type = 'clickable'
    # When viewing an image it should get a marker to toggle zoom. This is the
    # most unlikely rule to match, so keep it last.
    when document.body?.childElementCount == 1 and
    element.localName == 'img' and
    (element.classList?.contains('overflowing') or
    element.classList?.contains('shrinkToFit'))
    type = 'clickable'
    type = null if isXUL and element.classList?.contains('textbox-input')
    return type
    )
    commands.follow_in_tab = helper_follow.bind(
    null, {id: 'tab', selectors: ['a']},
    ({element}) ->
    type = if isProperLink(element) then 'link' else null
    return type
    )
    commands.follow_copy = helper_follow.bind(
    null, {id: 'copy'},
    ({element}) ->
    type = switch
    when isProperLink(element)
    'link'
    when isContentEditable(element)
    'contenteditable'
    when isTypingElement(element)
    'text'
    else
    null
    return type
    )
    commands.follow_focus = helper_follow.bind(
    null, {id: 'focus', combine: false},
    ({vim, element}) ->
    type = switch
    when utils.isFocusable(element)
    'focusable'
    when element != vim.state.scrollableElements.largest and
    vim.state.scrollableElements.has(element)
    'scrollable'
    else
    null
    return type
    )
    commands.follow_context = helper_follow.bind(
    null, {id: 'context', selectors: FOLLOW_CONTEXT_SELECTORS},
    ({element}) ->
    type =
    if element.localName in FOLLOW_CONTEXT_TAGS or
    utils.hasMarkableTextNode(element)
    'context'
    else
    null
    return type
    )
    commands.follow_selectable = helper_follow.bind(
    null, {id: 'selectable', selectors: FOLLOW_SELECTABLE_SELECTORS},
    ({element}) ->
    type =
    if utils.hasMarkableTextNode(element)
    'selectable'
    else
    null
    return type
    )
    commands.focus_marker_element = ({vim, elementIndex, browserOffset, options}) ->
    {element} = vim.state.markerElements[elementIndex]
    # To be able to focus scrollable elements, `FLAG_BYKEY` _has_ to be used.
    options.flag = 'FLAG_BYKEY' if vim.state.scrollableElements.has(element)
    utils.focusElement(element, options)
    vim.clearHover()
    vim.setHover(element, browserOffset)
    commands.click_marker_element = (
    {vim, elementIndex, type, browserOffset, preventTargetBlank}
    ) ->
    {element} = vim.state.markerElements[elementIndex]
    if element.target == '_blank' and preventTargetBlank
    targetReset = element.target
    element.target = ''
    if type == 'clickable-special'
    element.click()
    else
    isXUL = (element.ownerDocument instanceof XULDocument)
    sequence = switch
    when isXUL
    if element.localName == 'tab' then ['mousedown'] else 'click-xul'
    when type == 'context'
    'context'
    else
    'click'
    utils.simulateMouseEvents(element, sequence, browserOffset)
    utils.openDropdown(element)
    element.target = targetReset if targetReset
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/marker-container.coffee
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/marker.coffee
  • mode('hints', {
    onEnter: ({vim, storage}, options) ->
    {
    markerContainer, callback, matchText = true, count = 1, sleep = -1
    } = options
    storage.markerContainer = markerContainer
    storage.callback = callback
    storage.matchText = matchText
    storage.count = count
    storage.isMatched = {byText: false, byHint: false}
    storage.skipOnLeaveCleanup = false
    if matchText
    markerContainer.visualFeedbackUpdater =
    hintsMode.updateVisualFeedback.bind(null, vim)
    vim._run('clear_selection')
    if sleep >= 0
    storage.clearInterval = utils.interval(vim.window, sleep, (next) ->
    if markerContainer.markers.length == 0
    next()
    return
    vim._send('getMarkableElementsMovements', null, (diffs) ->
    for {dx, dy}, index in diffs when not (dx == 0 and dy == 0)
    markerContainer.markerMap[index].updatePosition(dx, dy)
    next()
    )
    )
    onLeave: ({vim, storage}) ->
    hintsMode.cleanup(vim, storage) unless storage.skipOnLeaveCleanup
    onInput: (args, match) ->
    {vim, storage} = args
    {markerContainer, callback} = storage
    switch match.type
    when 'full'
    match.command.run(Object.assign({match}, args))
    when 'none', 'count'
    # Make sure notifications for counts aren’t shown.
    vim._refreshPersistentNotification()
    {char, isHintChar} = hintsMode.getChar(match, storage)
    return true unless char
    return true if storage.isMatched.byText and not isHintChar
    visibleMarkers = markerContainer.addChar(char, isHintChar)
    storage.isMatched = hintsMode.isMatched(visibleMarkers, markerContainer)
    if (storage.isMatched.byHint and isHintChar) or
    (storage.isMatched.byText and not isHintChar and
    vim.options['hints.auto_activate'])
    hintsMode.activateMatch(
    vim, storage, match, visibleMarkers, callback
    )
    unless isHintChar
    vim._parent.ignoreKeyEventsUntilTime =
    Date.now() + vim.options['hints.timeout']
    return true
    }, {
    exit: ({vim}) ->
    vim._enterMode('normal')
    activate_highlighted: ({vim, storage, match}) ->
    {markerContainer: {markers, highlightedMarkers}, callback} = storage
    return if highlightedMarkers.length == 0
    for marker in markers when marker.visible
    marker.hide() unless marker in highlightedMarkers
    hintsMode.activateMatch(
    vim, storage, match, highlightedMarkers, callback
    )
    rotate_markers_forward: ({storage}) ->
    storage.markerContainer.rotateOverlapping(true)
    rotate_markers_backward: ({storage}) ->
    storage.markerContainer.rotateOverlapping(false)
    delete_char: ({storage}) ->
    {markerContainer} = storage
    visibleMarkers = markerContainer.deleteChar()
    storage.isMatched =
    hintsMode.isMatched(visibleMarkers or [], markerContainer)
    increase_count: ({storage}) ->
    storage.count += 1
    # Uncomment this line if you want to use `gulp hints.html`!
    # utils.writeToClipboard(storage.markerContainer.container.outerHTML)
    toggle_complementary: ({storage}) ->
    storage.markerContainer.toggleComplementary()
    })
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/hints-mode.coffee
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/documentation/options.md#hint-characters
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/documentation/commands.md#the-hint-commands--hints-mode

One last also, VimFx is the only one i've noticed that addresses quirks mode behavior. Anything major to watch out for?

Only one thing: Whether <html> or <body> is to be considered as the root element. This needs to be taken into account when:

  • Scrolling the entire page.
  • Calculating the size of the current viewport.

Hacker News is an example of a real world quirks mode site.

Here are some links:

  • # In quirks mode (when the page lacks a doctype), such as on Hackernews,
    # `<body>` is considered the root element rather than `<html>`.
    getRootElement = (document) ->
    if document.compatMode == 'BackCompat' and document.body?
    return document.body
    else
    return document.documentElement
  • # Even in quirks mode the 'overflow' event is triggered for `<html>`, _not_
    # `<body>`. This method takes care of returning the appropriate element, so
    # we don’t need to think about it anywhere else.
    quirks: (element) ->
    document = element.ownerDocument
    if element == document.documentElement
    return utils.getRootElement(document)
    else
    return element
  • } = utils.getRootElement(window.document)

Again, thanks for your input, @eejdoowad! I wish you the best of luck for your keyboard extension! Feel free to open issues here if you'd like to ask about something (anything at all!). Make sure to ping back here when you feel like your extension is starting to get in a nice state. I want to eventually link people to replacements for VimFx.

Collaborator

lydell commented May 17, 2017

Thanks for your input, @eejdoowad!

Are there any notable differences between VimFx and Vimium/cVim? Anything VimFX has that you feel those don't quite replicate?

I can't really say anything about cVim, but I can make some comparisons with Vimium.

First I'd like to address the three points brought up by @f1u77y. In my opinion, those points are not very important at all.

  • "VimFx uses Firefox native scrolling while Vimium uses its own"

    I've never had any issues with Vimium's scrolling. I'm confident that a custom implementation will be just as good or better.

  • "VimFx uses Firefox native UI while Vimium uses its own"

    This isn't really about Vimium vs. VimFx, but about Chrome vs. Firefox. And now when Firefox drops support for interacting with most UI it's not relevant anymore.

  • "VimFx is customizable with config file while Vimium is not"

    To me, the text format is not really that important. It should be easy to backup and sync all settings, and be possible to add custom commands. It's good if the export format can be read and modified by hand. But I prefer the UI when customizing VimFx – it helps me get the command names and key syntax right.

My favorite features of VimFx that aren't in Vimium are:

  • Subtle differences in Hints mode.

    • VimFx tries to give you shorter hints for elements that you are more likely to click. If two elements are equally probable, the earlier one wins (this involves edge cases with one-off pixel calculations and stuff).
    • If hints overlap, the "better" hint is on top.
    • Lots of edge cases for finding clickable elements is covered.
    • VimFx tries to put the hint markers right next to the text of links and buttons, without covering the text itself (rather than putting them in the top-left corner).
    • VimFx tries really hard to only show hints for visible elements.
    • VimFx takes the performance challenge of Hints mode seriously and has a two-phase system to speed things up (most links show up quickly, the rest a little bit later).
    • No need to choose between "regular old hints mode" and "type the text of links and use number hints as a fallback" mode. VimFx simply uses any typed non-hint-char keys to match by link text. Super useful for me who prefers "regular old hints mode" but occasionally match by link text (especially for pagination number links). Those who prefer matching by text simply change their hint chars to all numbers or all uppercase or something.
    • Hold shift+ctrl to peek through markers.
    • If the element for a marker moves, the marker moves as well.

    Read more about Hints mode.

  • Being able to enter Caret mode by using hints: v for placing the cursor at any element, av for also selecting the entire element, and yv for copying the element text without even entering Caret mode. I use all three all the time. Read more about Caret mode.

  • Robust key handling, through vim-like-key-notation. It features a well-defined syntax for shortcuts, and the "Ignore keyboard layout" option which is very useful to people who use several keyboard layouts. Read more about shortcuts.

  • All keys of every mode are customizable, not just Normal mode.

  • You can focus any scrollable element and scroll it using the regular VimFx scrolling commands.

  • Blacklisting really means "Enter Ignore mode by default", which means that you can still opt in to a short burst of VimFx usage on a blacklisted site if you want to.

  • The help dialog uses the entire screen and shows you every single available shortcut. You can even search in it!

  • Custom commands.

You can also search for VimFx in the Vimium issue tracker to find VimFx differences.

Also, are there any docs on VimFx's architecture?

Other than that, there's not much more documentation on the architecture itself than the summarizing comment at the beginning of each file.

How do you keep track of which mode is active?

VimFx has one object for tracking global state (the VimFx class). Then, there's one object per tab keeping track of tab specific state (the Vim class). The current mode is tab specific, so it is stored on the Vim objects. The .name property on a Vim instance is simply the string name of the current mode. Each mode is simply an object that implement certain methods, such as onEnter(), onLeave() and onInput() (see modes.coffee and Mode object). Vim::_enterMode(modeStringName) is used to switch mode.

Also, have any tips on making link hints better?

Plenty. Hints mode is what I've spent the most time on in VimFx. See my comparison with Vimium above. I'm more than happy sharing what I've learned about it, so feel free to ask questions! Here are some links:

  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/markable-elements.coffee
  • helper_follow = (options, matcher, {vim, pass}) ->
    {id, combine = true, selectors = FOLLOW_DEFAULT_SELECTORS} = options
    if vim.content.document instanceof XULDocument
    selectors = ['*']
    if pass == 'auto'
    pass = if selectors.length == 2 then 'first' else 'single'
    vim.state.markerElements = [] if pass in ['single', 'first']
    hrefs = {}
    filter = (element, getElementShape) ->
    type = matcher({vim, element, getElementShape})
    if vim.hintMatcher
    type = vim.hintMatcher(id, element, type)
    if pass == 'complementary'
    type = if type then null else 'complementary'
    return unless type
    shape = getElementShape(element)
    unless shape.nonCoveredPoint then switch
    # CodeMirror editor uses a tiny hidden textarea positioned at the caret.
    # Targeting those are the only reliable way of focusing CodeMirror
    # editors, and doing so without moving the caret.
    when id == 'normal' and element.localName == 'textarea' and
    element.ownerGlobal == vim.content
    rect = element.getBoundingClientRect()
    # Use `.clientWidth` instead of `rect.width` because the latter includes
    # the width of the borders of the textarea, which are unreliable.
    if element.clientWidth <= 1 and rect.height > 0
    shape = {
    nonCoveredPoint: {
    x: rect.left
    y: rect.top + rect.height / 2
    offset: {left: 0, top: 0}
    }
    area: rect.width * rect.height
    }
    # Putting a large `<input type="file">` inside a smaller wrapper element
    # with `overflow: hidden;` seems to be a common pattern, used both on
    # addons.mozilla.org and <https://blueimp.github.io/jQuery-File-Upload/>.
    when id in ['normal', 'focus'] and element.localName == 'input' and
    element.type == 'file' and element.parentElement?
    parentShape = getElementShape(element.parentElement)
    shape = parentShape if parentShape.area <= shape.area
    if not shape.nonCoveredPoint and pass == 'complementary'
    shape = getElementShape(element, -1)
    return unless shape.nonCoveredPoint
    text = utils.getText(element)
    originalRect = element.getBoundingClientRect()
    length = vim.state.markerElements.push({element, originalRect})
    wrapper = {
    type, text, shape,
    combinedArea: shape.area
    elementIndex: length - 1
    parentIndex: null
    }
    if wrapper.type == 'link'
    {href} = element
    wrapper.href = href
    # Combine links with the same href.
    if combine and wrapper.type == 'link' and
    # If the element has an 'onclick' attribute we cannot be sure that all
    # links with this href actually do the same thing. On some pages, such
    # as startpage.com, actual proper links have the 'onclick' attribute,
    # so we can’t exclude such links in `utils.isProperLink`.
    not element.hasAttribute?('onclick') and
    # GitHub’s diff expansion buttons are links with both `href` and
    # `data-url`. They are JavaScript-powered using the latter attribute.
    not element.hasAttribute?('data-url')
    if href of hrefs
    parent = hrefs[href]
    wrapper.parentIndex = parent.elementIndex
    parent.combinedArea += wrapper.shape.area
    parent.numChildren += 1
    else
    hrefs[href] = wrapper
    return wrapper
    selector =
    if pass == 'complementary'
    '*'
    else
    selectors[if pass == 'second' then 1 else 0]
    return {
    wrappers: markableElements.find(vim.content, filter, selector)
    viewport: viewportUtils.getWindowViewport(vim.content)
    pass
    }
    commands.follow = helper_follow.bind(
    null, {id: 'normal'},
    ({vim, element, getElementShape}) ->
    document = element.ownerDocument
    isXUL = (document instanceof XULDocument)
    type = null
    switch
    # Bootstrap. Match these before regular links, because especially slider
    # “buttons” often get the same hint otherwise.
    when element.hasAttribute?('data-toggle') or
    element.hasAttribute?('data-dismiss') or
    element.hasAttribute?('data-slide') or
    element.hasAttribute?('data-slide-to')
    type = 'clickable'
    when isProperLink(element)
    type = 'link'
    when isTypingElement(element)
    type = 'text'
    when element.localName in ['a', 'button'] or
    element.getAttribute?('role') in CLICKABLE_ARIA_ROLES or
    # <http://www.w3.org/TR/wai-aria/states_and_properties>
    element.hasAttribute?('aria-controls') or
    element.hasAttribute?('aria-pressed') or
    element.hasAttribute?('aria-checked') or
    (element.hasAttribute?('aria-haspopup') and
    element.getAttribute?('role') != 'menu')
    type = 'clickable'
    when utils.isFocusable(element) and
    # Google Drive Documents. The hint for this element would cover the
    # real hint that allows you to focus the document to start typing.
    element.id != 'docs-editor'
    type = 'clickable'
    when element != vim.state.scrollableElements.largest and
    vim.state.scrollableElements.has(element)
    type = 'scrollable'
    when element.hasAttribute?('onclick') or
    element.hasAttribute?('onmousedown') or
    element.hasAttribute?('onmouseup') or
    element.hasAttribute?('oncommand') or
    # Twitter.
    element.classList?.contains('js-new-tweets-bar') or
    element.hasAttribute?('data-permalink-path') or
    # Feedly.
    element.hasAttribute?('data-app-action') or
    element.hasAttribute?('data-uri') or
    element.hasAttribute?('data-page-action') or
    # Google Drive Document.
    element.classList?.contains('kix-appview-editor')
    type = 'clickable'
    # Facebook comment fields.
    when element.parentElement?.classList?.contains('UFIInputContainer')
    type = 'clickable-special'
    # Putting markers on `<label>` elements is generally redundant, because
    # its `<input>` gets one. However, some sites hide the actual `<input>`
    # but keeps the `<label>` to click, either for styling purposes or to keep
    # the `<input>` hidden until it is used. In those cases we should add a
    # marker for the `<label>`. Trying to access `.control` on an element in
    # `about:config` throws an error, so exclude XUL pages.
    when not isXUL and element.localName == 'label' and element.control and
    not getElementShape(element.control).nonCoveredPoint
    type = 'clickable'
    # Last resort checks for elements that might be clickable because of
    # JavaScript.
    when (not isXUL and
    # It is common to listen for clicks on `<html>` or `<body>`. Don’t
    # waste time on them.
    element not in [document.documentElement, document.body]) and
    (utils.includes(element.className, 'button') or
    utils.includes(element.getAttribute?('aria-label'), 'close') or
    # Do this last as it’s a potentially expensive check.
    (utils.hasEventListeners(element, 'click') and
    # Twitter. The hint for this element would cover the hint for
    # showing more tweets.
    not element.classList?.contains('js-new-items-bar-container')))
    # Make a quick check for likely clickable descendants, to reduce the
    # number of false positives. the element might be a “button-wrapper” or
    # a large element with a click-tracking event listener.
    unless element.querySelector?('a, button, input, [class*=button]')
    type = 'clickable'
    # When viewing an image it should get a marker to toggle zoom. This is the
    # most unlikely rule to match, so keep it last.
    when document.body?.childElementCount == 1 and
    element.localName == 'img' and
    (element.classList?.contains('overflowing') or
    element.classList?.contains('shrinkToFit'))
    type = 'clickable'
    type = null if isXUL and element.classList?.contains('textbox-input')
    return type
    )
    commands.follow_in_tab = helper_follow.bind(
    null, {id: 'tab', selectors: ['a']},
    ({element}) ->
    type = if isProperLink(element) then 'link' else null
    return type
    )
    commands.follow_copy = helper_follow.bind(
    null, {id: 'copy'},
    ({element}) ->
    type = switch
    when isProperLink(element)
    'link'
    when isContentEditable(element)
    'contenteditable'
    when isTypingElement(element)
    'text'
    else
    null
    return type
    )
    commands.follow_focus = helper_follow.bind(
    null, {id: 'focus', combine: false},
    ({vim, element}) ->
    type = switch
    when utils.isFocusable(element)
    'focusable'
    when element != vim.state.scrollableElements.largest and
    vim.state.scrollableElements.has(element)
    'scrollable'
    else
    null
    return type
    )
    commands.follow_context = helper_follow.bind(
    null, {id: 'context', selectors: FOLLOW_CONTEXT_SELECTORS},
    ({element}) ->
    type =
    if element.localName in FOLLOW_CONTEXT_TAGS or
    utils.hasMarkableTextNode(element)
    'context'
    else
    null
    return type
    )
    commands.follow_selectable = helper_follow.bind(
    null, {id: 'selectable', selectors: FOLLOW_SELECTABLE_SELECTORS},
    ({element}) ->
    type =
    if utils.hasMarkableTextNode(element)
    'selectable'
    else
    null
    return type
    )
    commands.focus_marker_element = ({vim, elementIndex, browserOffset, options}) ->
    {element} = vim.state.markerElements[elementIndex]
    # To be able to focus scrollable elements, `FLAG_BYKEY` _has_ to be used.
    options.flag = 'FLAG_BYKEY' if vim.state.scrollableElements.has(element)
    utils.focusElement(element, options)
    vim.clearHover()
    vim.setHover(element, browserOffset)
    commands.click_marker_element = (
    {vim, elementIndex, type, browserOffset, preventTargetBlank}
    ) ->
    {element} = vim.state.markerElements[elementIndex]
    if element.target == '_blank' and preventTargetBlank
    targetReset = element.target
    element.target = ''
    if type == 'clickable-special'
    element.click()
    else
    isXUL = (element.ownerDocument instanceof XULDocument)
    sequence = switch
    when isXUL
    if element.localName == 'tab' then ['mousedown'] else 'click-xul'
    when type == 'context'
    'context'
    else
    'click'
    utils.simulateMouseEvents(element, sequence, browserOffset)
    utils.openDropdown(element)
    element.target = targetReset if targetReset
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/marker-container.coffee
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/marker.coffee
  • mode('hints', {
    onEnter: ({vim, storage}, options) ->
    {
    markerContainer, callback, matchText = true, count = 1, sleep = -1
    } = options
    storage.markerContainer = markerContainer
    storage.callback = callback
    storage.matchText = matchText
    storage.count = count
    storage.isMatched = {byText: false, byHint: false}
    storage.skipOnLeaveCleanup = false
    if matchText
    markerContainer.visualFeedbackUpdater =
    hintsMode.updateVisualFeedback.bind(null, vim)
    vim._run('clear_selection')
    if sleep >= 0
    storage.clearInterval = utils.interval(vim.window, sleep, (next) ->
    if markerContainer.markers.length == 0
    next()
    return
    vim._send('getMarkableElementsMovements', null, (diffs) ->
    for {dx, dy}, index in diffs when not (dx == 0 and dy == 0)
    markerContainer.markerMap[index].updatePosition(dx, dy)
    next()
    )
    )
    onLeave: ({vim, storage}) ->
    hintsMode.cleanup(vim, storage) unless storage.skipOnLeaveCleanup
    onInput: (args, match) ->
    {vim, storage} = args
    {markerContainer, callback} = storage
    switch match.type
    when 'full'
    match.command.run(Object.assign({match}, args))
    when 'none', 'count'
    # Make sure notifications for counts aren’t shown.
    vim._refreshPersistentNotification()
    {char, isHintChar} = hintsMode.getChar(match, storage)
    return true unless char
    return true if storage.isMatched.byText and not isHintChar
    visibleMarkers = markerContainer.addChar(char, isHintChar)
    storage.isMatched = hintsMode.isMatched(visibleMarkers, markerContainer)
    if (storage.isMatched.byHint and isHintChar) or
    (storage.isMatched.byText and not isHintChar and
    vim.options['hints.auto_activate'])
    hintsMode.activateMatch(
    vim, storage, match, visibleMarkers, callback
    )
    unless isHintChar
    vim._parent.ignoreKeyEventsUntilTime =
    Date.now() + vim.options['hints.timeout']
    return true
    }, {
    exit: ({vim}) ->
    vim._enterMode('normal')
    activate_highlighted: ({vim, storage, match}) ->
    {markerContainer: {markers, highlightedMarkers}, callback} = storage
    return if highlightedMarkers.length == 0
    for marker in markers when marker.visible
    marker.hide() unless marker in highlightedMarkers
    hintsMode.activateMatch(
    vim, storage, match, highlightedMarkers, callback
    )
    rotate_markers_forward: ({storage}) ->
    storage.markerContainer.rotateOverlapping(true)
    rotate_markers_backward: ({storage}) ->
    storage.markerContainer.rotateOverlapping(false)
    delete_char: ({storage}) ->
    {markerContainer} = storage
    visibleMarkers = markerContainer.deleteChar()
    storage.isMatched =
    hintsMode.isMatched(visibleMarkers or [], markerContainer)
    increase_count: ({storage}) ->
    storage.count += 1
    # Uncomment this line if you want to use `gulp hints.html`!
    # utils.writeToClipboard(storage.markerContainer.container.outerHTML)
    toggle_complementary: ({storage}) ->
    storage.markerContainer.toggleComplementary()
    })
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/extension/lib/hints-mode.coffee
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/documentation/options.md#hint-characters
  • https://github.com/akhodakivskiy/VimFx/blob/16d72926b11b8ed63b27a779047599b62eecaf62/documentation/commands.md#the-hint-commands--hints-mode

One last also, VimFx is the only one i've noticed that addresses quirks mode behavior. Anything major to watch out for?

Only one thing: Whether <html> or <body> is to be considered as the root element. This needs to be taken into account when:

  • Scrolling the entire page.
  • Calculating the size of the current viewport.

Hacker News is an example of a real world quirks mode site.

Here are some links:

  • # In quirks mode (when the page lacks a doctype), such as on Hackernews,
    # `<body>` is considered the root element rather than `<html>`.
    getRootElement = (document) ->
    if document.compatMode == 'BackCompat' and document.body?
    return document.body
    else
    return document.documentElement
  • # Even in quirks mode the 'overflow' event is triggered for `<html>`, _not_
    # `<body>`. This method takes care of returning the appropriate element, so
    # we don’t need to think about it anywhere else.
    quirks: (element) ->
    document = element.ownerDocument
    if element == document.documentElement
    return utils.getRootElement(document)
    else
    return element
  • } = utils.getRootElement(window.document)

Again, thanks for your input, @eejdoowad! I wish you the best of luck for your keyboard extension! Feel free to open issues here if you'd like to ask about something (anything at all!). Make sure to ping back here when you feel like your extension is starting to get in a nice state. I want to eventually link people to replacements for VimFx.

@polyzen

This comment has been minimized.

Show comment
Hide comment
@polyzen

polyzen May 18, 2017

I love the config file because it makes it easy to:

Doesn't seem the first two bullets will be possible with a webextension, so I mostly added the last item as a consolation (though it is great to have).

Shame to say I've only scratched the surface of VimFx.

polyzen commented May 18, 2017

I love the config file because it makes it easy to:

Doesn't seem the first two bullets will be possible with a webextension, so I mostly added the last item as a consolation (though it is great to have).

Shame to say I've only scratched the surface of VimFx.

@eejdoowad

This comment has been minimized.

Show comment
Hide comment
@eejdoowad

eejdoowad May 19, 2017

Thanks for the thoughtful response @lydell. I'll definitely review your link hints implementation thoroughly when I get around to optimizing mine. I had taken a look earlier, noticed bloom filters and huffman trees, then decided to save it for another day. What I have now favors ease of implementation and customizability over performance. Did you ever explore pre-computation/caching for link hints?

I've taken a similar approach with modes - each mode is a simple object with methods like onEnter and onExit, but also handlers for common DOM events and messages from other pages.

At this stage, Saka Key is usable for general browsing, but only normal mode and hints mode are implemented. The version on the Firefox marketplace is outdated, so it's best to build it yourself following the instructions on Github. Or try it out on Chrome.

@polyzen, the second bullet is possible. Surfing Keys sells itself on custom commands. 3 and 4 are really good points.

I'm currently working on:

  • ensuring keybindings work across different keyboard types - (by using KeyboardEvent.code + modifiers to store keybindings)
  • devising keybinding profiles (e.g. default, left hand, right hand, etc.)
  • communicating info between frames

All suggestions appreciated.

eejdoowad commented May 19, 2017

Thanks for the thoughtful response @lydell. I'll definitely review your link hints implementation thoroughly when I get around to optimizing mine. I had taken a look earlier, noticed bloom filters and huffman trees, then decided to save it for another day. What I have now favors ease of implementation and customizability over performance. Did you ever explore pre-computation/caching for link hints?

I've taken a similar approach with modes - each mode is a simple object with methods like onEnter and onExit, but also handlers for common DOM events and messages from other pages.

At this stage, Saka Key is usable for general browsing, but only normal mode and hints mode are implemented. The version on the Firefox marketplace is outdated, so it's best to build it yourself following the instructions on Github. Or try it out on Chrome.

@polyzen, the second bullet is possible. Surfing Keys sells itself on custom commands. 3 and 4 are really good points.

I'm currently working on:

  • ensuring keybindings work across different keyboard types - (by using KeyboardEvent.code + modifiers to store keybindings)
  • devising keybinding profiles (e.g. default, left hand, right hand, etc.)
  • communicating info between frames

All suggestions appreciated.

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell May 19, 2017

Collaborator

noticed bloom filters and huffman trees

To save you some time: We used bloom filters a few years ago, but not anymore. But very much huffman trees.

Did you ever explore pre-computation/caching for link hints?

Yep. My theory is that it can't be done. See also #409.

each mode is a simple object with methods like onEnter and onExit, but also handlers for common DOM events and messages from other pages.

Sound good! I forgot to mention that while most of all mode specific logic is contained in the mode objects, there are a few if vim.mode == 'hints' etc. sprinkled in event listeners and such. That has never grown out of control, though. But it definitely sounds nice to to have handlers for events on the mode objects! 👍

ensuring keybindings work across different keyboard types - (by using KeyboardEvent.code + modifiers to store keybindings)

For a long time, VimFx had trouble with other keyboard layouts than en-US QWERTY basically. See #249. Solving that required a lot of experimentation. What I learned is that some people want the character that would be typed when pressing a key to be seen by VimFx (event.key), such as German and Swedish users, while others want the key printed on the key cap to be seen by VimFx (event.code), such as Russian users. That's why VimFx has the "Ignore keyboard layout" option. So my advice is to not only use event.code! See #249 (comment).

Collaborator

lydell commented May 19, 2017

noticed bloom filters and huffman trees

To save you some time: We used bloom filters a few years ago, but not anymore. But very much huffman trees.

Did you ever explore pre-computation/caching for link hints?

Yep. My theory is that it can't be done. See also #409.

each mode is a simple object with methods like onEnter and onExit, but also handlers for common DOM events and messages from other pages.

Sound good! I forgot to mention that while most of all mode specific logic is contained in the mode objects, there are a few if vim.mode == 'hints' etc. sprinkled in event listeners and such. That has never grown out of control, though. But it definitely sounds nice to to have handlers for events on the mode objects! 👍

ensuring keybindings work across different keyboard types - (by using KeyboardEvent.code + modifiers to store keybindings)

For a long time, VimFx had trouble with other keyboard layouts than en-US QWERTY basically. See #249. Solving that required a lot of experimentation. What I learned is that some people want the character that would be typed when pressing a key to be seen by VimFx (event.key), such as German and Swedish users, while others want the key printed on the key cap to be seen by VimFx (event.code), such as Russian users. That's why VimFx has the "Ignore keyboard layout" option. So my advice is to not only use event.code! See #249 (comment).

@HunterGraubard

This comment has been minimized.

Show comment
Hide comment
@HunterGraubard

HunterGraubard Jun 14, 2017

I've been happily using VimFx for a long time, and with the release of Firefox 54 and its multi-process features, I decided to check compatibility for my add-ons... and found this thread. This is horrible news! VimFx is so much better than Vimium... I'm so sad to hear that it's not going to have a future...

HunterGraubard commented Jun 14, 2017

I've been happily using VimFx for a long time, and with the release of Firefox 54 and its multi-process features, I decided to check compatibility for my add-ons... and found this thread. This is horrible news! VimFx is so much better than Vimium... I'm so sad to hear that it's not going to have a future...

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Jun 15, 2017

Collaborator

@HunterGraubard VimFx works fine with multi-process and Firefox 54. (But VimFx is still basically dead.)

Collaborator

lydell commented Jun 15, 2017

@HunterGraubard VimFx works fine with multi-process and Firefox 54. (But VimFx is still basically dead.)

@HunterGraubard

This comment has been minimized.

Show comment
Hide comment
@HunterGraubard

HunterGraubard Jun 15, 2017

Yes, it may still work for now... but it's terrible news to hear that it's a dead project and that people are just being directed to Vimium... VimFx is really so much better than Vimium. I hope someone can take on the work required to keep this extension going. :(

HunterGraubard commented Jun 15, 2017

Yes, it may still work for now... but it's terrible news to hear that it's a dead project and that people are just being directed to Vimium... VimFx is really so much better than Vimium. I hope someone can take on the work required to keep this extension going. :(

@chetgurevitch

This comment has been minimized.

Show comment
Hide comment
@chetgurevitch

chetgurevitch Jun 15, 2017

The extension is going to stop working in a couple updates, would need to be completely rewritten and still couldn't preserve all the current functionality. It's not really a matter of needing someone to put in work.

chetgurevitch commented Jun 15, 2017

The extension is going to stop working in a couple updates, would need to be completely rewritten and still couldn't preserve all the current functionality. It's not really a matter of needing someone to put in work.

@eejdoowad

This comment has been minimized.

Show comment
Hide comment
@eejdoowad

eejdoowad Jul 5, 2017

Is it possible to relicense VimFx's code, particularly the logic for finding markable elements, under an MIT license? My current implementation in Saka Key is very slow on Firefox, especially on large pages. Thanks

eejdoowad commented Jul 5, 2017

Is it possible to relicense VimFx's code, particularly the logic for finding markable elements, under an MIT license? My current implementation in Saka Key is very slow on Firefox, especially on large pages. Thanks

@mcomella

This comment has been minimized.

Show comment
Hide comment
@mcomella

mcomella Aug 10, 2017

Contributor

FYI: it was announced that tomorrow's Firefox Nightly will disable legacy extensions by default so presumably VimFx will stop working in 57.

Contributor

mcomella commented Aug 10, 2017

FYI: it was announced that tomorrow's Firefox Nightly will disable legacy extensions by default so presumably VimFx will stop working in 57.

@lindhe

This comment has been minimized.

Show comment
Hide comment
@lindhe

lindhe Aug 10, 2017

Contributor

Regarding @eejdoowad's seemingly off-topic comment on the license: I generally like copy-left licenses like GPL, so my initial reaction was that we should not budge. But then I dwelt on it and think that it might make sense to not use a copy-left license on a dead project. The biggest upside with copy-left I think is that it ensures that "you can benefit from my code, but I can too benefit from your changes to that code". And while that is a really nice feature for an ongoing project, I see no reason for it on a dead project. The only reason to keep at a copy-left license would be to try and spread GPL licensing, which at that point would be purely for ideological purposes with no real benefit to this project.

Unusual as it is for me, I'd vouch to relicense the code. MIT is a great license.

Contributor

lindhe commented Aug 10, 2017

Regarding @eejdoowad's seemingly off-topic comment on the license: I generally like copy-left licenses like GPL, so my initial reaction was that we should not budge. But then I dwelt on it and think that it might make sense to not use a copy-left license on a dead project. The biggest upside with copy-left I think is that it ensures that "you can benefit from my code, but I can too benefit from your changes to that code". And while that is a really nice feature for an ongoing project, I see no reason for it on a dead project. The only reason to keep at a copy-left license would be to try and spread GPL licensing, which at that point would be purely for ideological purposes with no real benefit to this project.

Unusual as it is for me, I'd vouch to relicense the code. MIT is a great license.

@musoke

This comment has been minimized.

Show comment
Hide comment
@musoke

musoke Aug 12, 2017

musoke commented Aug 12, 2017

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Aug 16, 2017

Collaborator

@lindhe’s comment convinced me. I’d like to change the license, but there are more copyright holders. I emailed @akhodakivskiy and @zhuochun about a couple of days ago, but neither of them has replied yet. We also need to ask @XrXr (I don’t have his email address). If nobody answers, I guess we could change the license only of the files that only I have copyright on. We could possibly even change the license on stuff that @akhodakivskiy and @zhuochun have copyright on, because VimFx used to be MIT licensed and neither of them have contributed code after the license change to GPL.

Collaborator

lydell commented Aug 16, 2017

@lindhe’s comment convinced me. I’d like to change the license, but there are more copyright holders. I emailed @akhodakivskiy and @zhuochun about a couple of days ago, but neither of them has replied yet. We also need to ask @XrXr (I don’t have his email address). If nobody answers, I guess we could change the license only of the files that only I have copyright on. We could possibly even change the license on stuff that @akhodakivskiy and @zhuochun have copyright on, because VimFx used to be MIT licensed and neither of them have contributed code after the license change to GPL.

@XrXr

This comment has been minimized.

Show comment
Hide comment
@XrXr

XrXr Aug 16, 2017

Contributor

@lydell Got email from Github. I have no problem giving up my copyright on the stuff I contributed :) feel free to do whatever

Contributor

XrXr commented Aug 16, 2017

@lydell Got email from Github. I have no problem giving up my copyright on the stuff I contributed :) feel free to do whatever

@zhuochun

This comment has been minimized.

Show comment
Hide comment
@zhuochun

zhuochun Aug 17, 2017

Contributor

I have no problem giving up my copyright as well. Thanks for notifying.

Contributor

zhuochun commented Aug 17, 2017

I have no problem giving up my copyright as well. Thanks for notifying.

@ooker777 ooker777 referenced this issue Aug 17, 2017

Closed

How to move highlighted marked link #890

3 of 3 tasks complete
@eejdoowad

This comment has been minimized.

Show comment
Hide comment
@eejdoowad

eejdoowad Aug 23, 2017

Thanks for the relicense! Now I definitely have to port VimFX's algorithm.

Also wanted to mention that Saka Key is now a pretty good choice for Firefox (in my subjective opinion). It has import/export support, configurable profiles, good presets, smooth scroll, multi-frame link hints, and, as far as I can tell, no deal-breaking bugs.

Give it a chance by installing the Development Channel version from the Addons Marketplace. Don't install the default version as that's hopelessly outdated.

eejdoowad commented Aug 23, 2017

Thanks for the relicense! Now I definitely have to port VimFX's algorithm.

Also wanted to mention that Saka Key is now a pretty good choice for Firefox (in my subjective opinion). It has import/export support, configurable profiles, good presets, smooth scroll, multi-frame link hints, and, as far as I can tell, no deal-breaking bugs.

Give it a chance by installing the Development Channel version from the Addons Marketplace. Don't install the default version as that's hopelessly outdated.

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Aug 23, 2017

Collaborator

@eejdoowad The actual relicensing hasn't happened yet, but I'll get to it soon. Nice to hear about the progress on Saka Key! I want to try that out soon too, and add links to Saka Key and Vimium in the VimFx description so that people find their way to alternatives.

Collaborator

lydell commented Aug 23, 2017

@eejdoowad The actual relicensing hasn't happened yet, but I'll get to it soon. Nice to hear about the progress on Saka Key! I want to try that out soon too, and add links to Saka Key and Vimium in the VimFx description so that people find their way to alternatives.

@lydell lydell changed the title from Turn VimFx into a WebExtension / THE FUTURE OF VIMFX to Turn VimFx into a WebExtension Aug 25, 2017

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Aug 25, 2017

Collaborator

@eejdoowad VimFx has now been re-licensed to MIT. Enjoy!

I've also now officially declared VimFx dead, and added links to Vimium-FF and Saka Key in the readme as well as on AMO.

Collaborator

lydell commented Aug 25, 2017

@eejdoowad VimFx has now been re-licensed to MIT. Enjoy!

I've also now officially declared VimFx dead, and added links to Vimium-FF and Saka Key in the readme as well as on AMO.

@pluto439

This comment has been minimized.

Show comment
Hide comment
@pluto439

pluto439 Nov 7, 2017

How about continuing development for palemoon instead? I can try to help with something.

I tried to switch to chromium, but I can't get used to the ui. I tried remove this "use f11 to exit fullscreen mode", but the answer I found honestly asked me to patch dll file in hex editor. I'm shocked by how hard it is to get such simple things. https://superuser.com/questions/1264349/how-to-completely-remove-press-f11-to-exit-full-screen-chromes-message

Also it's impossible to get "ctrl-v to enter address bar" and "esc to leave it" in anything that's not VimFx. It's kind of glitchy in VimFx too though, sometimes it mutes the page instead. Still, it's a must have for me. I can't compile chromium on my own pc, so I can't change anything in there. Maybe with palemoon I'll be more lucky.

pluto439 commented Nov 7, 2017

How about continuing development for palemoon instead? I can try to help with something.

I tried to switch to chromium, but I can't get used to the ui. I tried remove this "use f11 to exit fullscreen mode", but the answer I found honestly asked me to patch dll file in hex editor. I'm shocked by how hard it is to get such simple things. https://superuser.com/questions/1264349/how-to-completely-remove-press-f11-to-exit-full-screen-chromes-message

Also it's impossible to get "ctrl-v to enter address bar" and "esc to leave it" in anything that's not VimFx. It's kind of glitchy in VimFx too though, sometimes it mutes the page instead. Still, it's a must have for me. I can't compile chromium on my own pc, so I can't change anything in there. Maybe with palemoon I'll be more lucky.

@lydell lydell changed the title from Turn VimFx into a WebExtension to Firefox 57+ support / Turn VimFx into a WebExtension Nov 16, 2017

@lydell

This comment has been minimized.

Show comment
Hide comment
@lydell

lydell Nov 16, 2017

Collaborator

Re-opening so peolpe can find this more easily.

Collaborator

lydell commented Nov 16, 2017

Re-opening so peolpe can find this more easily.

@lydell lydell reopened this Nov 16, 2017

@lydell lydell added the wontfix label Nov 16, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment