BrowserNav addon for NVDA

This add-on provides NVDA users powerful navigation commands in browser mode. It works in web browsers, as well as any other applications that support NVDA browse mode, such as Word documents and email clients.

Download

Please install via add-on store.

Usage in browsers and other programs that support browse mode

Please note, that starting with NVDA v2024.2, vertical navigation and same style navigation commands are now available in NVDA core. It is preferred to use builtin commands. They are not assigned any default gesture, so gestures must be assigned by the user in Input gestures dialog.

BrowserNav can be used to navigate by horizontal offset from the left edge of the screen, by font size, or by font style.

BrowserNav rotor is used to switch between these options. Depending on the setting of this rotor, BrowserNav will indicate with beeps either horizontal offset or font size of currently selected item. In addition, BrowserNav will crackle on QuickNav commands to indicate how much text has been skipped over (this feature is only available in Google Chrome and Firefox).

BrowserNav works in any browser supported by NVDA. Although some features may not be available in all browsers. BrowserNav also works in other applications that support NVDA browse mode, such as Word documents and email clients.

Keystrokes:

QuickJump Bookmarks

BrowserNav QuickJump bookmarks is a powerful tool that allows to navigate around web pages and automate some repetitive actions.

Bookmark keystrokes

You can also configure custom keystrokes for most bookmark types (except for SkipClutter, Hierarchical and Numeric Script bookmarks).

Sites

The first thing you would need to configure is the site where you want to create bookmarks. In most cases you would want to specify match type to be either domain match or Match domain and its subdomains. To illustrate the latter option, you can specify:

If you need finer control, you can also specify exact URL or define a regular expression for URL.

Because of this flexible definition, on every given webpage multiple QuickJump sites might be active at the same time.

Bookmark types

Once you have configured site definition, you can proceed to define some bookmarks on it.

BrowserNav supports several types of bookmarks:

Creating a new bookmark

Once you have configured a site, the easiest way to create a new bookmark would be to navigate to the desired paragraph in the document , press NVDA+J to show bookmarks context menu and select Bookmarks > Create new bookmark for site ...

Bookmark configuration dialog will open. You can now customize bookmark. You can change how text is matched (e.g. string match or regular expression).

Other options in this dialog:

Advanced site options

In site configuration dialog you can specify a number of advanced options:

Scripting

Starting from BrowserNav v2.5 you can customize your bookmarks with Python scripting. Scripting can be used for two purposes: 1. To enhance matching algorithm where existing match options are not enough. This applies to QuickJump, QuickSpeak, QuickClick, hierarchical and SkipClutter bookmarks. 2. To execute arbitrary Python code in order to automate certain actions on the web pages. This can be done via Script or Numeric Script bookmarks.

Scripting API

In your script you are provided the following variables: * p - current paragraph. This is an instance of Paragraph class defined in paragraph.py * t - current textInfo object.

It is recommended to work with paragraphs, since they provide higher level interface then textInfos.

Your script must decide whether current paragraph matches your custom rule or not. You can either:

You are also allowed to import any modules and write general purpose scripts.

You can use print() statement to debug your script: the output will be printed to NVDA log.

Example scripts

  1. This script checks that current paragraph is a link and that the text of the previous heading level 5 starts with text of current paragraph: try: if controlTypes.Role.LINK in p.roles and p.previousHeading5.textInfo.text.startswith(p.text): print(f"pp5 {p.previousHeading5.textInfo.text}") return True except NotFoundError: return None
  2. This script doesn't perform a match, but activates the last edit box on the page: ''' p.end.previous.previousEdit.activate() '''
  3. This script finds username, which can be one or two paragraphs ahead; then it finds the beginning of the comment by analyzing font size; then it finds the end of the comment by searching for "Reply" text. Then it matches the entire body of the comment and adds username to be spoken prior to matched text: user = p.next if user.text == "downvote": user = user.next try: username = user.text.split()[0] except IndexError: username = '?' pp = p begin = None for i in range(5): fs = pp.attributes.get(ParagraphAttribute.FONT_SIZE, []) #print(f"i={i} fs={fs}") if '9_pt' in fs: begin = pp break pp = pp.next else: return end = begin while end.text != 'reply': end = end.next match(textInfoRange(begin, end), username)
  4. This script is a generator, which means whatever it yields will be used as sleep time before the next line is executed. This script will be executed in a background thread in a non-blocking manner. This script performs a series of actions:

    yield from retry(waitForDialogAndClickCheckbox, count=20) yield 500 yield from retry(lambda: p.home.find("Run Query").activate(), count=10) 6. This is a numeric script since it takes `level` as input variable. This finds `level`-th edit box from the beginning of the page (or from the end if level is negative) and invokes `script_editJupyter` on it. if level > 0: p = p.home for i in range(level): p = Paragraph(p.nextEdit.textInfo) elif level <= 0: level = 1-level p = p.end.previous tones.beep(500, 50) for i in range(level): p = Paragraph(p.previousEdit.textInfo) else: tones.beep(500, 50) p.textInfo.obj.currentFocusableNVDAObject = p.textInfo.focusableNVDAObjectAtStart p.textInfo.obj.script_editJupyter(None) ```

    Configuration

Bookmark definitions are stored in NVDA configuration directory in file browserNavRules.json. You can edit this file manually or share it with someone.

NVDA Configuration directory can be found by opening Start menu and typing: Explore NVDA user configuration directory.

BrowserNav comes with default configuration file with sample bookmarks.

Editing semi-accessible edit boxes

Many modern web applications, notably Jupyter among others, use edit boxes, that are not that accessible, e.g. they appear blank, but you can copy text in and out of them using Control+A, Control+C and Control+V keystrokes.

BrowserNav offers an experimental feature to edit those edit boxes in a more convenient way. IN order to use it:

  1. Find edit box in the browser window.
  2. Press NVDA+E.
  3. A new window will appear with the contents of that edit box.
  4. Edit the contents of that edit box in this window.
  5. Once you're done, you can press Escape to close the accessible edit window and update the edit box on the web page.
  6. Alternatively, you can press Control+Enter, Shift+Enter or Alt+Enter. This will close the edit window, update the edit box and pass on the gesture on to the web application.
  7. In order to close the edit window without saving changes, press Alt+F4.
  8. At any time, if the contents of previously edited text is lost, press NVDA+Control+E to copy it to clipboard.

Notes:

Source code

Source code is available at http://github.com/mltony/nvda-indent-nav.