Files
LeencyandBurer 145ac1ad7b Webview 4.0 (#14)
Рендеринг:
- Новый движок вместо 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>
2026-09-27 09:45:21 +03:00

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>&lt;");
else IF (SCRIPT == mode) {
IF (!strncmp(i+1,"/script>", 8)) {
CloseAllOpenedFonts(NULL);
SourceBufAdd(TAG, "<font color=#00f>&lt;");
}
ELSE SourceBufAdd(NULL, "&lt;");
}
ELSE IF (COMMENT == mode) {
SourceBufAdd(NULL, "&lt;");
}
ELSE IF (TEXT == mode) {
IF (!strncmp(i+1,"script", 6)) activate_script_mode = true;
SourceBufAdd(TAG, "<font color=#00f>&lt;");
}
break;
case '>':
IF (TAG == mode) && (activate_script_mode) {
activate_script_mode = false;
SourceBufAdd(SCRIPT, "&gt;</font><font color=#994500>");
}
ELSE IF (VALUE == mode) CloseAllOpenedFonts(TEXT);
ELSE IF (COMMENT == mode) && (!strncmp(i-2,"--", 2)) {
SourceBufAdd(TEXT, "&gt;");
CloseAllOpenedFonts(TEXT);
}
ELSE IF (COMMENT == mode) || (SCRIPT == mode) SourceBufAdd(NULL, "&gt;");
ELSE IF (TAG == mode) SourceBufAdd(TEXT, "&gt;</font>");
BREAK;
case '&':
SourceBufAdd(NULL, "&amp;");
BREAK;
case '\"':
case '\'':
IF (TAG == mode) SourceBufAdd(VALUE, "<font color=#F301F2>&quot;");
ELSE IF (VALUE == mode) SourceBufAdd(TAG, "&quot;</font>");
ELSE SourceBufAdd(NULL, "&quot;");
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);
}