Рендеринг: - Новый движок вместо TWB: страница проходит через DOM, вычисление стилей, раскладку и отрисовку отдельными этапами - Рисуется только видимая область, холст размером с окно - расход памяти не растёт с длиной страницы - Прокрутка сдвигает уже нарисованный холст и дорисовывает только появившуюся полосу - Страница показывается, не дожидаясь картинок; таблицы стилей, наоборот, дожидаются - до них на экране остаётся предыдущая страница CSS: - Источники правил: <style>, атрибут style="", <link> и @import - Селекторы: тег, .class, #id, *, атрибутные, комбинаторы - пробел, >, +, ~ - :is() и :where() раскрываются в обычные правила - Псевдоклассы: first-child, last-child, only-child, first-of-type, last-of-type, only-of-type, root, empty, checked, disabled, not, nth-child, nth-last-child, nth-of-type, nth-last-of-type - Псевдоэлементы ::before и ::after - @media по ширине и высоте окна - var(), calc(), min(), max(), clamp() - Блочная модель целиком: margin, padding, border, min/max-width и height - float, flex, grid - position: static, relative, absolute, fixed, sticky, z-index - vertical-align, в том числе super и sub; теги <sup> и <sub> Таблицы: - colspan и rowspan, неявные строки и ячейки, <caption>, вложенные таблицы - Ширины колонок считаются по содержимому и по заданным процентам - <table align> и <center> вокруг таблицы Сеть и кэш: - Картинки и таблицы стилей грузятся параллельно потоками самого WebView - до 12 одновременно, вместо отдельного процесса dl на каждый файл - Снято ограничение в 256 байт на адрес, и запросы уходят с куками - Кэш файлов в /tmp0/1/Cache с индексом: повторный заход на страницу не перекачивает картинки - SVG и WebP открываются через конвертер (по умолчанию wsrv.nl, адрес меняется в app.ini) - Куки: приём, хранение и отправка - Оборванное соединение распознаётся - обрезанный файл не сохраняется и не попадает в кэш, страница помечается неполной Формы: - Отправка по GET и по POST - Контролы: текстовое поле, пароль, чекбокс, радиокнопка, обычная кнопка и кнопка отправки, <select>, <textarea> - Размеры контролов берутся из CSS и атрибутов страницы, а не фиксированы Текст и шрифты: - Выделение и копирование текста, поиск по странице - Курсив для <i>, <em>, <cite>, <var>, <dfn>, <address> и font-style: системные шрифты курсива не имеют, поэтому нарисованная строка наклоняется сдвигом пикселей - Мелкий шрифт для текста 10 px и меньше - но только если такого текста меньше половины страницы - Изменение размера шрифта: Ctrl+- и Ctrl++ - Определение кодировки по <meta charset> и по содержимому Интерфейс: - Обновлены встроенные страницы: новая вкладка и страница ошибки - Пункт меню "Открыть в NetSurf" - Кнопка папки загрузок на панели - Правый клик по картинке: открыть, сохранить, скопировать адрес - До 5 вкладок Убрано: - Страница истории WebView:history и пункт меню к ней Изменения вне браузера: - dl: оборванная загрузка считается ошибкой, обрезанный файл не сохраняется; путь назначения принимается после | в параметре - menu: не реагирует на события мыши до создания окна - иначе меню закрывалось сразу после запуска - lib/obj/http.h: в _http появилось поле flags, наружу выведен HTTP_GOT_ALL_DATA - lib/draw_buf.h: холст держит размер, заданный Init(); неиспользуемые методы не попадают в программу - lib/collection.h: swap() для двух записей - lib/obj/box_lib.h: edit_box приведена к раскладке переписанного box_lib (OS PR #662) Размер запакованного приложения - 64 КБ: 65 261 байт (EN) и 65 456 (RU). --------- Co-authored-by: Burer <burer@kolibrios.org> Reviewed-on: #14 Reviewed-by: Burer <burer@kolibrios.org> Co-authored-by: leency <lipatov.kiril@gmail.com>
101 lines
2.9 KiB
C
101 lines
2.9 KiB
C
enum { TAG=1, VALUE, TEXT, COMMENT, SCRIPT};
|
|
|
|
int opened_font_counter;
|
|
int mode;
|
|
|
|
dword source_buf_start, source_buf_end, source_buf_cap;
|
|
|
|
// a single input byte expands up to ~30 bytes of markup: grow the buffer instead of
|
|
// guessing its size. Every piece written at once is shorter than 256 bytes.
|
|
void SourceBufReserve()
|
|
{
|
|
dword used = source_buf_end - source_buf_start;
|
|
dword room = source_buf_cap - used;
|
|
IF (room > 256) RETURN;
|
|
source_buf_cap += source_buf_cap;
|
|
source_buf_start = realloc(source_buf_start, source_buf_cap);
|
|
source_buf_end = source_buf_start + used;
|
|
}
|
|
|
|
void SourceBufAdd(dword _mode, src)
|
|
{
|
|
IF (_mode) mode = _mode;
|
|
|
|
SourceBufReserve();
|
|
strcpy(source_buf_end, src);
|
|
source_buf_end += strlen(source_buf_end);
|
|
|
|
IF (strstr(src, "</font>")) opened_font_counter--;
|
|
IF (strstr(src, "<font ")) opened_font_counter++;
|
|
}
|
|
|
|
void CloseAllOpenedFonts(dword _mode)
|
|
{
|
|
WHILE (opened_font_counter) SourceBufAdd(_mode, "</font>");
|
|
}
|
|
|
|
void ShowSource(dword _bufdata, _in_bufsize)
|
|
{
|
|
dword i;
|
|
bool activate_script_mode = false;
|
|
|
|
opened_font_counter=0;
|
|
mode = TEXT;
|
|
source_buf_cap = _in_bufsize * 2;
|
|
source_buf_cap += 4096;
|
|
source_buf_start = malloc(source_buf_cap);
|
|
source_buf_end = source_buf_start;
|
|
|
|
SourceBufAdd(TEXT, "<html><head><title>View Source</title></head><body><pre>");
|
|
|
|
for (i=_bufdata; i<_bufdata+_in_bufsize; i++) switch (DSBYTE[i])
|
|
{
|
|
CASE '<':
|
|
IF (!strncmp(i+1,"!--", 3)) SourceBufAdd(COMMENT, "<font color=#bbb><");
|
|
else IF (SCRIPT == mode) {
|
|
IF (!strncmp(i+1,"/script>", 8)) {
|
|
CloseAllOpenedFonts(NULL);
|
|
SourceBufAdd(TAG, "<font color=#00f><");
|
|
}
|
|
ELSE SourceBufAdd(NULL, "<");
|
|
}
|
|
ELSE IF (COMMENT == mode) {
|
|
SourceBufAdd(NULL, "<");
|
|
}
|
|
ELSE IF (TEXT == mode) {
|
|
IF (!strncmp(i+1,"script", 6)) activate_script_mode = true;
|
|
SourceBufAdd(TAG, "<font color=#00f><");
|
|
}
|
|
break;
|
|
case '>':
|
|
IF (TAG == mode) && (activate_script_mode) {
|
|
activate_script_mode = false;
|
|
SourceBufAdd(SCRIPT, "></font><font color=#994500>");
|
|
}
|
|
ELSE IF (VALUE == mode) CloseAllOpenedFonts(TEXT);
|
|
ELSE IF (COMMENT == mode) && (!strncmp(i-2,"--", 2)) {
|
|
SourceBufAdd(TEXT, ">");
|
|
CloseAllOpenedFonts(TEXT);
|
|
}
|
|
ELSE IF (COMMENT == mode) || (SCRIPT == mode) SourceBufAdd(NULL, ">");
|
|
ELSE IF (TAG == mode) SourceBufAdd(TEXT, "></font>");
|
|
BREAK;
|
|
case '&':
|
|
SourceBufAdd(NULL, "&");
|
|
BREAK;
|
|
case '\"':
|
|
case '\'':
|
|
IF (TAG == mode) SourceBufAdd(VALUE, "<font color=#F301F2>"");
|
|
ELSE IF (VALUE == mode) SourceBufAdd(TAG, ""</font>");
|
|
ELSE SourceBufAdd(NULL, """);
|
|
BREAK;
|
|
default:
|
|
SourceBufReserve();
|
|
DSBYTE[source_buf_end] = DSBYTE[i];
|
|
source_buf_end++;
|
|
}
|
|
DSBYTE[source_buf_end] = 0;
|
|
LoadInternalPage(source_buf_start, source_buf_end-source_buf_start);
|
|
free(source_buf_start);
|
|
}
|