Навигация в браузъра (BrowserNav)

Тази добавка предоставя на потребителите на NVDA мощни команди за навигация в режим на разглеждане. Работи в уеб браузъри, както и във всички други приложения, които поддържат режима на разглеждане на NVDA, като документи на Word и клиенти за е-поща.

Изтегляне

Please install via add-on store.

Използване в браузъри и други програми, които поддържат режим на разглеждане

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 може да се използва за навигация по хоризонтални отстъпи от левия край на екрана, по размер на шрифта или по стил на шрифта.

  • При навигация по хоризонтални отстъпи можете лесно да намерите абзаци, които са вертикално подравнени на страницата. В частност, можете да натиснете NVDA+Alt+стрелка надолу или стрелка нагоре, за да преминете към следващия или предишния абзац, който има същия отстъп. Например, това може да бъде полезно при преглеждане на коментари, подредени в йерархична структура (например на reddit.com), за да преминавате между коментарите от първо ниво и да прескочите всички коментари от по-високо ниво.
  • Когато навигирате по размер на шрифта, лесно можете да намерите абзаци, написани със същия размер на шрифта или по-малък/по-голям размер на шрифта.
  • Можете също да навигирате по размер на шрифта с ограничение за един и същ стил на шрифта.

Роторът на "Навигация в браузъра" се използва за превключване между тези опции. В зависимост от настройката на този ротор, BrowserNav ще посочи със звукови сигнали или хоризонталното отместване, или размера на шрифта на текущо избрания елемент. В допълнение, "Навигация в браузъра" ще препуква при командите за бърза навигация, за да покаже колко текст е пропуснат (тази функция е налична само в Google Chrome и Firefox).

"Навигация в браузъра" работи във всеки браузър, поддържан от NVDA. Въпреки че някои функции може да не са налични във всички браузъри. "Навигация в браузъра" работи и в други приложения, които поддържат режима на разглеждане на NVDA, като документи на Word и клиенти за е-поща.

Клавишни команди:

  • NVDA+Alt+стрелка нагоре или стрелка надолу: Преминаване към предишен или следващ абзац със същия хоризонтален отстъп или размер на шрифта.
  • NVDA+Alt+Home или NVDA+Alt+Стрелка наляво: Преминаване към предишния абзац с по-малък отстъп или по-голям размер на шрифта (родителски абзац).
  • NVDA+Alt+End или NVDA+Control+alt+Стрелка наляво: Преминаване към следващия абзац с по-малък отстъп или по-голям размер на шрифта (следващ родителски абзац).
  • NVDA+Alt+Page Down или NVDA+Alt+Стрелка надясно: Преминаване към следващия абзац с по-голям отстъп или по-малък размер на шрифта (дъщерен абзац).
  • NVDA+Alt+Page Up или NVDA+Control+Alt+Стрелка надясно: Преминаване към предишния абзац с по-голям отстъп или по-малък размер на шрифта (предишен дъщерен абзац).
  • NVDA+O: Смяна на режима за навигация между хоризонтален отстъп, размер на шрифта, размер на шрифта със стил на шрифта.
  • \ или Shift+\ (обратна черта): Превъртане нагоре или надолу, за да се покаже всеки елемент от страницата. Може да бъде полезно в динамични уеб страници за зареждане на всички елементи. Също може да бъде полезно в уеб страници с безкрайно превъртане за зареждане на следващият сегмент.
  • NVDA+Shift+Стрелка наляво: Връщане към предишното местоположение на курсора в текущия документ.
  • NVDA+E: Редактиране на полудостъпни текстови полета (вижте съответния раздел по-долу).
  • T или Shift+T: Преминаване към следващата или предишната таблица, но поставяне на курсора в първата клетка. Понякога NVDA поставя курсора точно преди първата клетка и "Навигация в браузъра" поправя това поведение.

QuickJump Bookmarks

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

Клавишни команди за показалците

  • NVDA+J: Показване на изскачащото меню за бърз преход.
  • J или Shift+J: Преминаване към следващ или предишен QuickJump показалец.
  • / и Control+/: Превключване на режима "SkipClutter" за навигация съответно по ред (стрелка нагоре и стрелка надолу) и по абзац (Control+Стрелка нагоре и Control+Стрелка надолу).
  • Alt+J: click all QuickClick bookmarks on the current page.
  • Control+J: Speak all QuickSpeak bookmarks on the current page.
  • Alt+1, Alt+2, ..., Alt+0: jump to next hierarchical bookmark of corresponding level. 0 corresponds to level 10.; alternatively, call numerical script if defined.
  • Shift+Alt+1, Shift+Alt+2, ..., Shift+Alt+0: Преминаване към предишния йерархичен показалец.
  • Altили Shift+Alt+: Преминаване към следващ или предишен йерархичен показалец от всяко ниво.

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

Сайтове

Първото нещо, което трябва да конфигурирате, е сайтът, където искате да създавате показалци. В повечето случаи бихте искали да посочите съвпадение на тип или съвпадение на домейн или съвпадение на домейн и неговите поддомейни. За да илюстрирате последната опция, можете да посочите:

  • URL адрес: amazon.com
  • Съвпадение на тип: Съвпадение на домейн и неговите поддомейни
  • Това ще съответства на amazon.com, smile.amazon.com и всички други домейни *.amazon.com.

Ако имате нужда от по-фин контрол, можете също да посочите точен URL или да дефинирате регулярен израз за URL.

Поради тази гъвкава дефиниция на всяка дадена уеб страница могат да бъдат активни едновременно множество QuickJump сайтове.

Типове показалци

След като конфигурирате дефиницията на сайта, можете да продължите с дефиниране на няколко показалеца в него.

BrowserNav supports several types of bookmarks:

  • Показалци за бърз преход (QuickJump): Можете да преминете към тях, като натиснете J или Shift+J.
  • Показалци SkipClutter: Тези показалци се пропускат автоматично при навигация по ред (стрелка нагоре/надолу) или по абзац (Control+стрелка нагоре/надолу). Това позволява да се скрият претрупани части на уеб страниците, като празни редове, времеви клейма и всякаква друга излишна информация. Информацията не се премахва напълно – SkipClutter може да бъде временно изключено чрез командите / или Control+/. По подразбиране SkipClutter пропуска празни абзаци на всички уебсайтове.
  • QuickClick bookmarks: you can mark clickable elements, such as links, buttons or checkboxes to be QuickClick bookmarks. Then by pressing Alt+J you can quickly press all QuickClick bookmarks on current page with a single keystroke without moving the cursor. This can come in handy to press a frequently used button on a website, such as play button on YouTube or Mute button on video-conferencing websites.
  • QuickSpeak bookmarks: you can read this type of bookmarks by pressing Control+J keystroke; Curosr won't move. This is handy to check frequently changed elements of the page. You can also set quickClick bookmark to be autorefreshable, that is BrowserNav will scan the page preiodically and would auto-speak if matched text changes.
  • Hierarchical bookmarks: this is similar to quickJump bookmarks, but this takes into account horizontal offset of a bookmark. Sites like Reddit and Hacker News have a hierarchical tree of comments, that was pretty challenging to efficiently navigate for screenreader users. On these websites you can mark comments as a hierarchical bookmark and then you can navigate between them By pressing Alt+digit or Shift+Alt+ditgit, where digit stands for number row 1,2,3,...0 - that is the level of the comment. By default BrowserNav has hierarchical bookmarks configured for Hacker News and reddit.com.
  • Script bookmarks: Just execute provided script when invoked.
  • Numeric script: press Alt+0 through Alt+9 to execute script taking a number as its input. Can be handy for example to jump to i-th bookmark on the page in a single keystroke.

Създаване на нов показалец

След като сте конфигурирали сайт, най-лесният начин да създадете нов показалец би бил да отидете до желания абзац в документа, да натиснете NVDA+J, за да се покаже контекстното меню за показалците и да изберете Показалци -> Създай нов показалец за сайт...

Ще се отвори диалоговият прозорец за конфигуриране на показалец. Вече можете да персонализирате показалеца. Можете да промените начина на съпоставяне на текста (напр. съвпадение на низ или регулярен израз).

Други опции в този диалогов прозорец:

  • Категория: Определя типа на показалеца.
  • Показвано име: Незадължително име на този показалец за по-добра четливост. Това просто дава по-добро име, така че да можете да идентифицирате този показалец в дълъг списък от показалци.
  • Изговаряно съобщение при намиране на показалеца: Незадължително съобщение, което да бъде изговаряно всеки път, когато попаднете на този показалец в документа.
  • Отместване в абзаци: След намиране на съответстващ текст "Навигация в браузъра" ще премести курсора с толкова абзаци напред или назад. Това може да бъде полезно, например, ако целевият текст, към който искате да преминете, не съдържа общ текст, който може да бъде съпоставен (напр. публикация във форум), но предходен абзац съдържа съответстваща дума (напр. "upvote"). В този случай можете да съпоставите думата "upvote" и да посочите offset=1, за да поставите курсора върху първия абзац на публикацията вместо върху думата "upvote".
  • Атрибути: Разделен с интервал списък с атрибути на абзаци, които се съпоставят. Списъкът с налични атрибути за текущия абзац е достъпен в следващото поле на формуляра. Списъкът с атрибути е предварително попълнен с някои общи роли и обикновено не е необходимо да го редактирате.
  • Налични атрибути в текущия абзац: Това са всички атрибути, открити в текущия абзац. Можете да изберете и натиснете интервал, за да ги добавите към списъка със съответстващи атрибути.

Разширени опции за сайта

В диалоговия прозорец за конфигуриране на сайта можете да посочите редица разширени опции:

  • Показвано име: Незадължително показвано име за по-добра четливост в списъка със сайтове.
  • Режим на фокус: Това позволява да се замени обработката по подразбиране на събитията за фокусиране в NVDA. Някои уебсайтове злоупотребяват с събитията за фокусиране. За да ги използвате по-удобно, можете или да игнорирате събитията за фокусиране, или като алтернатива да изключите автоматичното влизане в режим на фокус при получаване на събитие за фокусиране.
  • Режим Live Region: Някои уебсайтове злоупотребяват с активни региони (live regions). Тази опция позволява да се забрани докладването на живи региони конкретно за текущия уеб сайт.
  • Debug beep mode: this is mostly good for debugging purposes. You can make NVDA beep when certain event (focus, live region update or successful QuickClick) happened.

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:

  • Return True if it matches, otherwise False.
  • Return None or no return statement to indicate no match.
  • Return an integer number i to indicate that i-th following or i-th preceding paragraph matches and must be spoken instead of current paragraph.
  • Return tuple (i: int, s:str) to indicate match with offset (see previous point) and have BrowserNav speak message s.
  • Call match() function to indicate a match. This function internally raises an Exception, so that execution of your script will be terminated after calling match. The function is defined as:

      def match(offset: int | TextInfo | Paragraph = None, message: str = None) -> None:
    

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:

    • Finds a button with a given name and presses it.
    • Enters dialog that pops up: p.home.nextEmbeddedObject.activate()
    • Obtains newly focused element within that dialog: d = getFocusParagraph()
    • Finds and checks checkbox in that dialog.
    • Finds another button in that dialog window by name and presses it.

    These steps are repeated 20 times via retry function. Then after 500 ms pause, it finds "Run Query" button and presses it.

     def waitForDialogAndClickCheckbox():
         try:
             p.home.find("Link Last Used").activate()
             p.home.nextEmbeddedObject.activate()
         except NotFoundError:
             pass
         d = getFocusParagraph()
         c = d.home.nextCheckBox
         if controlTypes.State.CHECKED not in c.obj.states:
             c.activate() 
         d.home.find("Link QCPR Project").activate()
    
     yield from retry(waitForDialogAndClickCheckbox, count=20)
     yield 500
     yield from retry(lambda: p.home.find("Run Query").activate(), count=10)
    
  5. 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)
    

Конфигуриране

Дефинициите на показалците се съхраняват в конфигурационната директория на NVDA във файла "browserNavRules.json". Можете да редактирате този файл ръчно или да го споделите с някого.

Конфигурационната директория на NVDA може да бъде намерена, като отворите менюто "Старт" и напишете "Преглеждане на папката с потребителските настройки на NVDA".

"Навигация в браузъра" идва с конфигурационен файл по подразбиране с примерни показалци.

Редактиране на полудостъпни текстови полета

Много съвременни уеб приложения, по-специално Jupyter наред с други, използват полета за редактиране, които не са толкова достъпни (напр. те изглеждат празни), но можете да копирате текст в и извън тях, като използвате клавишите Control+A, Control+C и Control+V.

"Навигация в браузъра" предлага експериментална функция за редактиране в такива текстови полета по по-удобен начин. ЗА да я използвате:

  1. Намерете текстовото поле в уеб страницата.
  2. Натиснете NVDA+E.
  3. Ще се появи нов прозорец със съдържанието на това текстово поле.
  4. Редактирайте съдържанието на въпросното текстово поле в този прозорец.
  5. След като сте готови, можете да натиснете Escape, за да затворите достъпния прозорец за редактиране и да актуализирате текстовото поле в уеб страницата.
  6. Като алтернатива можете да натиснете Control+Enter, Shift+Enter или Alt+Enter. Това ще затвори прозореца за редактиране, ще актуализира текстовото поле и ще предаде жеста към уеб приложението.
  7. За да затворите прозореца за редактиране, без да запазвате промените, натиснете Alt+F4.
  8. По всяко време, ако съдържанието на предходно редактирания текст се загуби, натиснете NVDA+Control+E, за да го копирате в клипборда.

Забележки:

  • Не променяйте състоянието на браузъра (напр. не превключвайте между раздели и не фокусирайте други елементи в раздела), докато прозорецът за редактиране на текст е отворен. Това ще попречи на "Навигация в браузъра" да актуализира правилно текста в полето.
  • Не забравяйте да освободите модификаторите Control, Shift или Alt бързо след натискане на Ctrl+Enter, Shift+Enter или Alt+Enter. Задържането им за повече от секунда ще доведе до проблеми.
  • Тази функция в момента е експериментална. Моля, очаквайте само около 90-95% успеваемост.
  • Тя е щателно тествана с Google Chrome и Firefox. Може да работи в други браузъри, но има по-голям шанс за проблеми, като например загуба на информация.

Изходен код

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