WEB-Браузер

Материал из LUWRAIN Wiki
Перейти к: навигация, поиск

Интерфейс пользователя[править]

Внешний вид и управление[править]

Браузер основан на представлении NavigationArea и вся логика представлена в классе org.luwrain.app.browser.BrowserArea проект app-browser. Это значит пользователь работает с однооконным приложением, содержащим заголовок и многострочный текст.

Заголовок окна содержит (и автоматически обновляется) заголовок текущей страницы (и отладочную информацию в конце строки - текущий статус загрузки org.luwrain.browser.Event.WebState и процент загрузки страницы от 0 до 100)

F5 - запускает пересканирование текущей страницы (но не обновление с веб-сервера) и сбрассывает текущую позицию курсора на странице, используется в случае каких-либо проблем с отображением или если браузер не смог по каким то причинам отследить

Это метод onRescanPageDom(), вызывает в частности page.RescanDOM(), сам по себе метод очень быстрый, даже для тяжелых страниц в сотни тысяч элементов работает миллисекунды (там формируется хитрый javascript и ижнектируется на страницу). Затем идет вызов перестройки документа - объекта WebDocument, позволяющего работать со страницей на логическом уровне (многоуровневый текст, параграфы, элементы форм, таблицы, списки....)
Кстати, page.RescanDom так же вызывается периодически для отслеживания изменений на странице, и если они возникли в пределах текущего предаставления, т.е. +- несколько (константа PAGE_SCANNER_AROUND_ELEMENTS_COUNT) элементов от текущего курсора), то представление в окне будет изменено (пока есть проблемы с текущим положением курсора, он числовой от номера элемента в списке, это нужно хитро переделать таким образом, чтобы при структурном обновлении страницы курсор оставался на прежнем элементе, проблема в том что нет адекватных инструментов идентификации элементов на странице)
Затем с помощью метода refill() обновляется объект WebView - построчное текстовое веб-представление документа в окне NavigationArea.

Документ в NavigationArea может являться как полностью текущей веб-страницей так и ее частью, так же он может быть представлен в двух режимах

  • нормальный (класс org.luwrain.app.browser.web.WebViewBuilder - WebBuilderNormal используется для наполнения WebView), это просто список элементов на странице (текст, кнопки, ссылки,..)
  • сложный (WebBuilderComplex) - режим навигации по таблицам и спискам (элементы представлены в виде коротких строчек), так же через этот механизм будет реализованы html-фреймы
Каждый элемент на странице может быть проверен методом element.needToBeComplex() (true - значит 'в него можно войти' по ENTER)

Например таблицы или списки, которые будут обнаружены на странице могут быть отображены в NavigationArea либо в виде собственно их содержимого (построчно) либо в виде короткого элемента, при активизации которого по ENTER содержимое NavigationArea будет заменено на его сложное представление, а при нажатии ENTER на одном из его элементов, содержимое заполнит NavigationArea и режим переключится обратно в нормальный. Пока навигации по истории переходов не реализовано и для возврата на основную страницу нужно использовать F5, собственно сам интерфейс и механизм перехода complex <-> normal нужно внимательно пересмотреть, так как это был эксперимент. Так же пока не решен вопрос о методе, с помощью которого сложные элементы на странице будут промаркированны как complex или normal (пока все таблицы - нормальные, а все списки ul/li - complex) Элементы будут размещены на странице в соответствии с их размещением в HTML документе, но решение о размещении каждого следующего элемента в строке принимается на основе его физического положения на экране (во время сканирования эта информация так же собирается, собственно именно она позволяет быстро определить видимость элемента), т.е. если два элемента рядом находятся в пределах координат Y друг друга то они будут размещены на одной строке, пока влезают в лимит luwrain.getAreaVisibleWidth(this)

Элементы на экране NavigationArea будут автоматически размещены по строчкам и в пределах одной строки (один элемент может так же занимать несколько строк, но в таком случае он полностью занимает эти строки), на текущий момент каждый элемент на экране дополнен его текстовым типом (label, edit, button, select..)

Элементы представлены в WebDocument объектами WebElement, базовый объект WebText (все элементы, способные содержать отображаемый текст, может содержать подэлементы) и порожденными от него классами org.luwrain.app.browser.web.Web...
Каждый элемент выдает как текстотвую строку для прочтения ридером getTextSay так и для отображения getTextView, а так же getTextShort - выдает тип элемента (или короткую информацию по нему, например для списка выдает urdered/unordered и с припиской multilevel для многоуровневых списков, и количество элементов)

В качестве примера отслеживания стилей текста, у элементов возможно получение CSS атрибутов (стиль bold, класс strong или собственно наименование шрифта

например element.getElement().getComputedStyleProperty("font-weight") или element.getAttributes().get("href");
Класс WebText в начале содержит подробные коментарии о своей работе на англйиском

TAB - зачитывает дополнительную информацию о текущем лементе, метод onInfoAction(), сейчас это наличие флага bold, наименование шрифта, атрибут href для ссылок, а внутри списка короткий брифинг о нем.

ENTER - вызывает событие на текущем элементе, в зависимости от типа этого элемента, результат будет отличаться, и по умолчанию, если действий не предусмотрено, будет сэмулировано нажатие левой кнопки мышки на нем, метод javascript click() Для полей ввода Edit (inputbox или textarea, а точнее это флаг у элемента - element.getElement().isEditable()) будет открыт диалог редактирования содержимого этого элемента (можно отменить редактирование по ESC или сохранить ENTER) Для полей выбора Select будет выдано окно выбора элементов из списка ♦Для кнопок и ссылок будет сэмулирован клик по ним (т.е. javascript click()

Ctrl+LEFT и Ctrl+RIGHT позволяет переходить последовательно по элементам на странице, если элементы в строке закончились, то курсор будет смещен в начало следующей строки

Просто стрелки UP, DOWN, LEFT и RIGHT - стандартная навигация по NavigationArea

F6 - открывает окно запроса ввода нового адреса, окно уже заполнено строкой http:// (но можно изменить на https например)

F10 - скрывает текущий документ NavigationArea и включает оригинальный браузер с текущей страницей (основанный на компоненте javafx.scene.web.WebView.WebView), где будет возможность используя курсор мыши и клавиатуру как в обычном браузере взаимодействовать со страницей. перезагрузка страницы не происходит, собственно этот браузер всегда работает, просто скрыт Внимание, в этом режиме продолжают работать кнопки управления NavigationArea, пока на странице не будет выбран какой-либо элемент уже средствами браузера (а это происходит при клике мышкой в любой элемент кроме простого текста), в этом случае уже браузер будет обрабатывать нажатые клавиши и они не будут доходить до NavigationArea Повторное нажатие F10 возвращает NavigationArea

JavaScript[править]

Так как реальная обработка веб-страницы происходит в полноценном браузере javafx.scene.web.WebView.WebView (основанный на WebKit) то javascript так же полноценно отрабатывает. Вся задача браузера в luwrain корректно обрабатывать изменения на странице. Например при изменениях на странице (текст, значения в элементах формы или видимость элементов) и даже открытие новой страницы отслеживаются (периодически с интервалом PAGE_SCANNER_INTERVAL) и при их наличии происходит обновление в NavigationArea

очень редко но я все еще встречаю ситуации когда изменения не отлавливаются

Объекты браузера[править]

WebPage[править]

Этот класс является реализацией абстрактного интерфейса Browser на базе javafx и размещен в проекте реализации Interaction - interaction-javafx. Тут же создается окно браузера webkit, размещены методы чтения (сканирования) страницы на DOM-элементы, а именно метод RescanDOM Все элементы на странице попадают в ассоциативный массив org.w3c.dom.Node -> (порядковый номер) -> org.luwrain.interaction.javafx.NodeInfo

ElementIterator-ы и Selector-ы[править]

Так как список объектов во время сканирования документа линейный то по нему необходимо перемещаться вперед и назад (по аналогии перемещения по текстовому файлу). Для этого создан интерфейс Selector (все его реализации определяют как именно необходимо перемещаться между элементами вперед и назад, в основном это перемещения между видимыми, содержащими читаемый текст элементами SelectorAllImpl, или, например, перемещение между элементами, содержащими подстроку в тексте - SelectorTextImpl, или специфическое значение атрибута CSS - SelectorCssImpl, или все 'дети' выбранной ноды - SelectorChildrenImpl. Т.е. с помощью этих селекторов можно анализировать список нод без построения их в соответствующие структуры, т.е. необходимый анализ проводится во время перемещения между нодами в методах moveNext/movePrev/... Но Selector это только действие над элементами, для сохранения текущей позиции на странице используется интерфейс ElementIterator, и его единственная реализация ElementIteratorImpl, обеспечивающая доступ к всей необходимой информации об html node - текст, атрибуты, стили, и т.п. а так же эмуляция действий пользователя (клик мыши).

WebDocument[править]

Класс, определяющий логическую структуру документа. Необходим для логического анализа страницы и собственно построения ее представления в NavigationArea. Во время анализа и создания этого объекта, структура HTML документа упрощается, остаются только значимые элементы, содержащие видимый текст (полезную информацию) или потомков (лишние уровни так же урезаются)

WebElement[править]

WebDocument состоит из дерева объектов-реализаций интерфейса WebElement. Фактически это конечные элементы на странице - текст (WebText/WebList/WebTable/..) или элементы форм (WebButton/WebEdit/WebSelect/..) Каждый элемент определяет свой способ отображения в NavigationArea, озвучиваемый ридером текст и сопроводительную информацию. Так же во время создания сами элементы 'решают' какими у них будут атрибуты, Например в элементы WebList или WebTable сами собирают информацию о своих потомках и принимают решение, быть им complex или normal элементами на странице (т.е. можно ли входить в них во время навигации или их содержимое сразу будет отображено). Каждый элемент хранит свой ElementIterator, указывающий на связанную с ним ноду в HTML документе, таким образом можно работать с элементом в браузере, выбрав нужный WebElement.

WebView и WebBuilder[править]

WebView - объект, содержит информацию о взаимном расположении WebElement-ов на экране NavigationArea. Т.е. Это построчное распределение элементов веб-страницы. В одной строке могут находиться несколько WebElement, если по длине в символах элемент не помещается в строку, то для него выделяются сразу несколько строк. Выбор размещения элементов в одной строке или на разных, делается на основе физического размещения HTML элементов на странице (во время сканирования RescanDOM собирает о каждом объекте их занимаемый прямоугольник на экране) и если их координаты по Y не совпадают то такие элементы не попадут в одну строку. В результате страница в NavigationArea очень похожа на реальную страницу (естественно, без лишних пробелов и выравниваний по X)

Используя собранную структуру документа WebDocument с помощью объектов-реализаций интерйейса WebBuilder (а именно WebBuilderComplex и WebBuilderNormal, они выбираются в зависимости от текущего типа режима просмотра) происходит наполнение представления WebView в соответствии с настройками NavigationArea (сейчас это только ширина окна в символах).

Алгоритм выявления объемных элементов страницы[править]

Пока в разработке, идея выделения некоторых элементов на странице как крупнейших, содержащих основную информацию, управляющие элементы и т.п. в идеале, чтобы в список таких жлементов попали целиком различные виды меню, статьи, списки новостей, и т.п.

WEB-Браузер:алгоритм выявления больших нод

Полезные ссылки[править]

JavaDoc - http://luwrain.org/api-browser/