Полная поддержка table
Базовый CSS
Рисуется теперь только видимая область (сильно уменьшает расход памяти)
Параллельная загрузка изображений в 16 потоков
Кэш картинок на /tmp0/1/cache
Выделение и копирование текста
Поиск по странице
ПКМ на картинке -> Можно сохранить
UPD:
Поддержка куки
Поддержка самбита форм по GET и POST: текстовое поле, чекбокс, радиобокс
Можно изменить размер шрифта
Обновлены встроенные страницы
Меню: добавлен пункт "Открыть в NetSurf"
Тулбар: добавлена кнопка открытия папки загрузки
Бинарник 22 КБ => 52 КБ, потому нужно будет освобождать место в IMG.
Полная поддержка table
Базовый CSS
Рисуется теперь только видимая область (сильно уменьшает расход памяти)
Параллельная загрузка изображений в 16 потоков
Кэш картинок на /tmp0/1/cache
Выделение и копирование текста
Поиск по странице
ПКМ на картинке -> Можно сохранить
UPD:
Поддержка куки
Поддержка самбита форм по GET и POST: текстовое поле, чекбокс, радиобокс
Можно изменить размер шрифта
Обновлены встроенные страницы
Меню: добавлен пункт "Открыть в NetSurf"
Тулбар: добавлена кнопка открытия папки загрузки
Бинарник 22 КБ => 52 КБ, потому нужно будет освобождать место в IMG.
The old TWB renderer is replaced by an engine that builds a DOM, applies
CSS, lays the page out into fragments and paints only what is visible.
Engine (browser/engine):
- DOM builder with scoped closing tags, entity decoding in text and
attributes, raw text for script/style/textarea, <noscript> shown
- CSS: <style>, style="" and <link rel=stylesheet> (local, cached or
downloaded), custom properties and var(), @media walking, descendant
and child selectors, class/id in any case, :link, :visited,
:first-child, :last-child; colors, fonts, text-align, white-space,
width, max-width, height (as a minimum), margins with auto and
negative values, padding, borders, float, display incl. table parts,
vw units
- Layout: inline lines with baseline images and icons, <pre>, lists,
<nav> menus in a row, tables with colspan/rowspan and percent columns,
display:table with or without rows, floats with or without a width,
float:right, centred blocks, flex rows (flex-grow, basis, wrap, gap,
justify-content, auto margins, align-items)
- position:absolute / fixed and flex each sit behind a switch in
style.h (css_abspos off, css_flex on); text parked off-page or in a
1px clipped box stays hidden either way
- Paint into a viewport canvas, text selection, find on page, hit
testing, link hover
Browser:
- images load in a separate downloader process ("dl -i"), the image
cache lives in /tmp0/1/Cache and survives a restart
- Ctrl+A/C stay inside a focused edit box, right click on a selection
offers Copy, view source works, file:// addresses, history and cache
keep the real address instead of the proxied one, the built-in error
page keeps its charset, DuckDuckGo Lite is the default search
- URLs with spaces are escaped, a slash in an unquoted attribute no
longer closes the tag
dl: filename= without quotes, hidden mode "-i", no double free of the
content buffer.
Test pages for each area are in browser/tests.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
- the updater downloads WebView.com from builds.kolibrios.org/ci/latest
- test page is laid out as a two column table
- Russian error page: a short framed box, tethering over USB as the
easiest way online, a link to the list of supported network cards
- a line break after the logo on the start page
- build.bat no longer writes into a local floppy image and starts QEMU
- editbox_icons, help_en/help_ru and highlight_c.h are not used by the
new engine and are removed
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
The kernel can deliver a pending mouse event before the first redraw,
while the menu window is not defined and so cannot be the active one.
The active-window check then closed the menu at once whenever the mouse
moved during startup. Mouse events are now skipped until the first
DefineAndDrawWindow.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
- ch/ex units: ch in width/max-width follows the element's font glyph width
- parser adds an implied <tr> for cells straight in <table>, and an implied
<td> for content straight in <tr>/<table>
- <center> and align=center centre child tables
- docs/ROADMAP.md brought up to date
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
1. browser/engine/style.h:310, stack overflow from any page css_match_compound copies a selector fragment into char part[128] with no length cap, while CSSRULE::add passes selectors of up to ~250 characters. It smashes lc[256], the saved registers and the return address.
2. browser/engine/engine.h:243, Reparse() runs on an unbuilt DOM
The dom.nodes guard present in hit.h:13 and engine_restore_tab is missing here. F12 or Ctrl+Tab on a still loading tab makes dom.n(0) write through a null node and then walk a garbage child index.
3. browser/show_src.h:39, output buffer undersized 5x malloc(bufsize*5), but one input byte can expand to 26 (" in TAG mode); markup made of short tags expands ~11x. Ctrl+U corrupts the heap. This PR also shrank the allocation by passing WB1.bufsize.
4. browser/engine/layout.h:849, pointer held across a realloc v = dom.attr(_idx, "src") points into the dpool arena; the next two place_string() calls can reallocate it, and v is then passed to a third call. Every other attribute read in this file copies into a local buffer first.
5. browser/engine/engine.h:359 and image_url, one byte past the end strncpy in lib/strings.h writes len bytes plus a terminator, but the buffers are declared char path[URL_SIZE]. style_link_sheet (style.h:1125) gets this right with URL_SIZE + 1.
Functional bugs
6. browser/engine/style.h:360, wrong subject in long selectors np is pinned at 8 but the subject is taken as parts[np-1], so a selector with 9 or more compounds matches its 8th part instead of its last. The rule lands on the wrong nodes.
7. browser/WebView.c:192, text selection navigates away
No break after if (mouse.up) sel_end();, and lib/mouse.h restores key on the up event, so EventClickLink fires. Releasing the button over an <a> after selecting text destroys the selection and loads the link.
8. browser/cache.h:164, two windows wipe each other's cache remove_orphans() deletes every wv_* file missing from this process's index. Ctrl+N and -new bypass the single instance check and the index is only written on exit, so the second instance deletes files the first one's dl children are still writing.
9. browser/WebView.c:864, image download progress never draws DrawProgress() returns on !http.transfer, but images are now fetched by an external dl -i after http.hfree() has already cleared it. The http_get_type==IMG branches here and in HandleRedirect are dead code.
10. browser/engine/paint.h:104, clipped icons smear src += 4 sits after the continue, so a skipped pixel does not consume the source. A <kosicon> near the canvas edge drifts diagonally instead of clipping cleanly.
Resources and performance
11. browser/engine/layout.h:1606, string arena grows without bound
Every layout pass appends fresh copies to dpool; measure_block and flex_measure roll back frags.count but not dpool.used. Resizing a window on a page with a long list doubles the arena until it runs out of memory. This is also what makes finding 4 reachable.
12. browser/engine/layout.h:1494, oversized table allocation cf_first/cf_end/cf_h are sized R * MAXCOLS (64) although ncols is known at line 1359. A 2000x3 table takes 1.5 MB instead of 72 KB.
13. browser/engine/engine.h:449, style_all() runs twice per tab switch engine_restore_tab() calls style_all(), and both callers (tabs.h:157, tabs.h:179) immediately follow with Reparse(), which calls it again and re-reads every linked stylesheet.
## Critical: memory corruption
**1. `browser/engine/style.h:310`, stack overflow from any page**
`css_match_compound` copies a selector fragment into `char part[128]` with no length cap, while `CSSRULE::add` passes selectors of up to ~250 characters. It smashes `lc[256]`, the saved registers and the return address.
**2. `browser/engine/engine.h:243`, `Reparse()` runs on an unbuilt DOM**
The `dom.nodes` guard present in `hit.h:13` and `engine_restore_tab` is missing here. F12 or Ctrl+Tab on a still loading tab makes `dom.n(0)` write through a null node and then walk a garbage child index.
**3. `browser/show_src.h:39`, output buffer undersized 5x**
`malloc(bufsize*5)`, but one input byte can expand to 26 (`"` in TAG mode); markup made of short tags expands ~11x. Ctrl+U corrupts the heap. This PR also shrank the allocation by passing `WB1.bufsize`.
**4. `browser/engine/layout.h:849`, pointer held across a realloc**
`v = dom.attr(_idx, "src")` points into the `dpool` arena; the next two `place_string()` calls can reallocate it, and `v` is then passed to a third call. Every other attribute read in this file copies into a local buffer first.
**5. `browser/engine/engine.h:359` and `image_url`, one byte past the end**
`strncpy` in `lib/strings.h` writes `len` bytes plus a terminator, but the buffers are declared `char path[URL_SIZE]`. `style_link_sheet` (`style.h:1125`) gets this right with `URL_SIZE + 1`.
## Functional bugs
**6. `browser/engine/style.h:360`, wrong subject in long selectors**
`np` is pinned at 8 but the subject is taken as `parts[np-1]`, so a selector with 9 or more compounds matches its 8th part instead of its last. The rule lands on the wrong nodes.
**7. `browser/WebView.c:192`, text selection navigates away**
No `break` after `if (mouse.up) sel_end();`, and `lib/mouse.h` restores `key` on the up event, so `EventClickLink` fires. Releasing the button over an `<a>` after selecting text destroys the selection and loads the link.
**8. `browser/cache.h:164`, two windows wipe each other's cache**
`remove_orphans()` deletes every `wv_*` file missing from this process's index. Ctrl+N and `-new` bypass the single instance check and the index is only written on exit, so the second instance deletes files the first one's `dl` children are still writing.
**9. `browser/WebView.c:864`, image download progress never draws**
`DrawProgress()` returns on `!http.transfer`, but images are now fetched by an external `dl -i` after `http.hfree()` has already cleared it. The `http_get_type==IMG` branches here and in `HandleRedirect` are dead code.
**10. `browser/engine/paint.h:104`, clipped icons smear**
`src += 4` sits after the `continue`, so a skipped pixel does not consume the source. A `<kosicon>` near the canvas edge drifts diagonally instead of clipping cleanly.
## Resources and performance
**11. `browser/engine/layout.h:1606`, string arena grows without bound**
Every layout pass appends fresh copies to `dpool`; `measure_block` and `flex_measure` roll back `frags.count` but not `dpool.used`. Resizing a window on a page with a long list doubles the arena until it runs out of memory. This is also what makes finding 4 reachable.
**12. `browser/engine/layout.h:1494`, oversized table allocation**
`cf_first/cf_end/cf_h` are sized `R * MAXCOLS` (64) although `ncols` is known at line 1359. A 2000x3 table takes 1.5 MB instead of 72 KB.
**13. `browser/engine/engine.h:449`, `style_all()` runs twice per tab switch**
`engine_restore_tab()` calls `style_all()`, and both callers (`tabs.h:157`, `tabs.h:179`) immediately follow with `Reparse()`, which calls it again and re-reads every linked stylesheet.
Memory safety:
- css_match_compound: cap selector parts at part[] size (stack overflow)
- Reparse(): do nothing while the tab has no document yet
- view-source: grow the output buffer instead of guessing 5x
- iframe/video placeholder: copy src before place_string() may realloc dpool
- GetAbsoluteActiveURL: sized global buffer instead of a returned stack array
Functional:
- selectors with more than 8 parts keep their real last part as the subject
- releasing a text selection over a link no longer follows the link
- a second WebView window no longer deletes the first one's cache files
- image download progress is drawn again; dead IMG branches removed
- clipped <kosicon> icons no longer smear
Resources:
- layout strings are rolled back each layout and measure pass (dpool growth)
- per-cell table arrays sized by the real column count
- tab switch restyles once, not twice
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
Features:
- forms: text/password/checkbox/radio/select/submit controls, GET and POST
submit (http.post, form-urlencoded, cp866 -> page charset)
- cookies: per-host jar sent with requests, Set-Cookie stored
- toolbar button that opens /tmp0/1/Downloads in Eolite
- <link>/<style> media attribute, #rrggbbaa colours, attribute selectors,
":link"/":any-link" keep their specificity, "}" inside CSS comments
- hex numeric entities, more named/numeric entities, "?" for unknown ones
Fixes from the code review:
- layout: stale blk_y beside floats, lay_skip_width leaking out of floated
tables, ln_rw across inline-blocks, glued runs past the right edge, floats
inside inline-blocks, centering while measuring max-content
- parser: <option> no longer closes <p>+<select>, ">" inside single-quoted
attributes, "}" in comments
- tabs: keyboard switch/close during a load, stale close button after a close,
Ctrl+T with every tab taken, selection on a tab without a document
- first page is opened once (a redraw no longer restarts the fetch), Back and
Forward during a load stop it instead of going one page too far
- form value slots no longer exhausted by radio groups; a form closed inside
a table cell keeps its own controls only
lib: http.post and extra request headers, proxy site escaping (dl uses it),
box_lib edit box field widths, KEY_MODIFIERS, menu reads Form before use.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
1. c--/c--.exe Commit 99cb5e87d re-adds the 1.1 MB binary that a4d502690
deleted on purpose. Unrelated to the browser. Drop the commit.
Memory corruption
2. engine/special.h:111 Scan accepts 9 chars into char special_code[10], then sprintf(#special_code, "#%i", code) writes the decimal form back. � =
"#268435455", 11 bytes. Overflows the stack local.
3. engine/engine.h:557get_absolute_url ends in strncpy(dst, src, URL_SIZE),
which writes URL_SIZE + 1 bytes. Fixed in engine_get_bgimage (529) and style.h:2569; still URL_SIZE in engine_get_image (572), image_url (585), WebView.c:1403, 1412, 1442, 1590.
4. engine/hit.h:82links.active_url holds dpool.buf + offset across events. CheckImgDownloads -> ImgRedraw -> Relayout -> POOL::addn reallocates buf. GetAbsoluteActiveURL() (WebView.c:1545) then navigates to freed memory.
5. WebView.c:259ctx_img_node stores a raw node index. The context menu is a
separate process, so a tab switch or page load can replace dom first. "Save image"
then indexes a smaller arena.
6. engine/style.h:2493css_abs_urls: k = n * URL_SIZE + strlen(_text), n = count of url(. 500 occurrences = 2 MB request per sheet per style_all(). malloc result unchecked before strcpy/memmov.
Functional
7. engine/style.h:1896if (cnt >= 64) break; breaks the scan, not the
collection, so it keeps the first 64 matches, not the most specific. Later rules win
by source order in CSS; on a heavily-classed element they are dropped.
8. WebView.c:386case TAB_CLOSE_ID calls EventTabClose without if (http.transfer) StopLoading();. EventCloseActiveTab (tabs.h:192) and middle
click both have it. Arriving page lands in the newly active tab.
9. tabs.h:200 Switch blocked on http.transfer but not img_loading. img_queue, img_slot_idx, prbar, img_queue_gen still describe the old page, so CheckImgDownloads relayouts the new tab and mixes the queues. Same in EventTabClose.
10. WebView.c:861EventOpenNewTab ignores tab.add() returning false at TABS_MAX and calls OpenPage on the current tab. EventNewBlankTab (tabs.h:225)
and EventViewSource (WebView.c:1091) check first.
11. engine/layout.h:2118measure_block restores every line variable except ln_rw, and inline_block (905) calls it before saving s_rw at 915. line_open()
zeroes ln_rw, so right = blk_x + blk_w - ln_rw (909) ignores a float:right on
the same line.
Performance
12. engine/paint.h:312memopen("ICONS18", ...) per icon drawn, never closed.
200 <kosicon> = 200 syscalls per repaint, refcount grows for the process lifetime.
Open once at startup.
13. engine/form.h:643form_submit_url calls form_owner() per node, and form_owner (111-144) scans backwards over the node list. Repeated by form_has_secret (247) and form_click (302). Quadratic in page size.
14. engine/style.h:2581style_all re-reads and re-parses every <link> from
disk (read_file + css_abs_urls copy + css_parse_sheet). Called from ParseHtml, Reparse (tab switch, F12, zoom), Relayout on @media change (engine.h:257), ImgRedraw per arriving sheet. Cache the parsed rules per document.
Notes
15. lib/keyboard.h:111KEY_MODIFIERS defined, no users.
## Blocking
**1. `c--/c--.exe`** Commit `99cb5e87d` re-adds the 1.1 MB binary that `a4d502690`
deleted on purpose. Unrelated to the browser. Drop the commit.
## Memory corruption
**2. `engine/special.h:111`** Scan accepts 9 chars into `char special_code[10]`, then
`sprintf(#special_code, "#%i", code)` writes the decimal form back. `�` =
"#268435455", 11 bytes. Overflows the stack local.
**3. `engine/engine.h:557`** `get_absolute_url` ends in `strncpy(dst, src, URL_SIZE)`,
which writes URL_SIZE + 1 bytes. Fixed in `engine_get_bgimage` (529) and
`style.h:2569`; still URL_SIZE in `engine_get_image` (572), `image_url` (585),
`WebView.c:1403, 1412, 1442, 1590`.
**4. `engine/hit.h:82`** `links.active_url` holds `dpool.buf + offset` across events.
`CheckImgDownloads` -> `ImgRedraw` -> `Relayout` -> `POOL::addn` reallocates `buf`.
`GetAbsoluteActiveURL()` (`WebView.c:1545`) then navigates to freed memory.
**5. `WebView.c:259`** `ctx_img_node` stores a raw node index. The context menu is a
separate process, so a tab switch or page load can replace `dom` first. "Save image"
then indexes a smaller arena.
**6. `engine/style.h:2493`** `css_abs_urls`: `k = n * URL_SIZE + strlen(_text)`,
`n` = count of `url(`. 500 occurrences = 2 MB request per sheet per `style_all()`.
`malloc` result unchecked before `strcpy`/`memmov`.
## Functional
**7. `engine/style.h:1896`** `if (cnt >= 64) break;` breaks the scan, not the
collection, so it keeps the first 64 matches, not the most specific. Later rules win
by source order in CSS; on a heavily-classed element they are dropped.
**8. `WebView.c:386`** `case TAB_CLOSE_ID` calls `EventTabClose` without
`if (http.transfer) StopLoading();`. `EventCloseActiveTab` (`tabs.h:192`) and middle
click both have it. Arriving page lands in the newly active tab.
**9. `tabs.h:200`** Switch blocked on `http.transfer` but not `img_loading`.
`img_queue`, `img_slot_idx`, `prbar`, `img_queue_gen` still describe the old page, so
`CheckImgDownloads` relayouts the new tab and mixes the queues. Same in
`EventTabClose`.
**10. `WebView.c:861`** `EventOpenNewTab` ignores `tab.add()` returning false at
`TABS_MAX` and calls `OpenPage` on the current tab. `EventNewBlankTab` (`tabs.h:225`)
and `EventViewSource` (`WebView.c:1091`) check first.
**11. `engine/layout.h:2118`** `measure_block` restores every line variable except
`ln_rw`, and `inline_block` (905) calls it before saving `s_rw` at 915. `line_open()`
zeroes `ln_rw`, so `right = blk_x + blk_w - ln_rw` (909) ignores a `float:right` on
the same line.
## Performance
**12. `engine/paint.h:312`** `memopen("ICONS18", ...)` per icon drawn, never closed.
200 `<kosicon>` = 200 syscalls per repaint, refcount grows for the process lifetime.
Open once at startup.
**13. `engine/form.h:643`** `form_submit_url` calls `form_owner()` per node, and
`form_owner` (111-144) scans backwards over the node list. Repeated by
`form_has_secret` (247) and `form_click` (302). Quadratic in page size.
**14. `engine/style.h:2581`** `style_all` re-reads and re-parses every `<link>` from
disk (`read_file` + `css_abs_urls` copy + `css_parse_sheet`). Called from `ParseHtml`,
`Reparse` (tab switch, F12, zoom), `Relayout` on `@media` change (`engine.h:257`),
`ImgRedraw` per arriving sheet. Cache the parsed rules per document.
## Notes
**15. `lib/keyboard.h:111`** `KEY_MODIFIERS` defined, no users.
**16.** Multi-line rationale comments from round 1 remain: `style.h:1009, 1120`,
`layout.h:1725`, `paint.h:26`, `WebView.c:14`.
Features:
- pictures and stylesheets are fetched by threads of WebView (img_thread.h)
instead of "dl -i" processes: no 256 byte url limit, cookies are sent,
stylesheets first and retried, hung threads given up, orphans bounded
- status bar shows the page load: connecting, sending a form, KB received
(of the total when known), images N/M
- CSS: grid (tracks, spans, template areas), calc(), :is()/:where()/:not(),
:nth-*, @supports not, media ranges, transform translate, inset,
min-height/max-height, vw, fractional px/em
- layout: absolute positioning inside blocks and inline boxes, paint order
sort, float carry between blocks, flex order and item alignment
- <details>/<summary>, checkbox and radio painting, <label> targets,
<noscript>, webp twin images, image rescaling to fit
- cache: stylesheets outlive pictures, big pictures dropped once laid out,
evicted sheets are fetched again on a tab switch or font change
- updater downloads straight to /sys/network/WEBVIEW
- tests: calc, checkbox, details, floatcarry, grid, gridareas, iswhere,
minheight, noscript, webp; sitetest.py site smoke test for the test VM
Fixes:
- stack raised: debian.org crashed with the stack running into globals
- content-type compared in lower case (charset=UTF-8)
- redirect buffer sized for get_absolute_url()
lib: collection::swap, ed_select flag for the rewritten box_lib, local path
check requires a disk number ("/cdn-cgi/...", "/hdimages/" are site paths).
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
Features:
- SVG and WebP pictures are fetched through a converter (ini image_converter,
wsrv.nl by default) at the size the page asks for
- CSS: ::before/::after boxes that give their element a height or clear its
floats, calc() with percentages in offsets, min()/max()/clamp(),
background-size in px, aspect-ratio, object-position, max-height in %,
percent heights of definite boxes, text-indent: -9999px logos,
clip: rect() of nothing (sr-only)
- small print (10px and less) drawn in the small font when the page is not
set small all over
- settings: show_css switch
- text fields take their CSS width or size="n" (20 when not given), not 14
characters; an auto table with percent columns grows so its other columns
get their content width (Google's search field)
Fixes:
- picture blend never reads past the picture (page fault scrolling habr.com)
- closing a tab stops its stylesheet and picture downloads too; a middle
click on another tab no longer breaks the load of the active one
- stylesheets and pictures in the cache have their own extensions
- 12 parallel downloads instead of 16
dl: always notifies when a download ends.
lib: CANVAS::DrawBar fills rows with MEMSETD.
Tests: pctheight.htm, slashdot link in showroom.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
Features:
- <i>, <em>, <cite>, <var>, <dfn>, <address> and font-style: italic/oblique
finally lean. The kernel fonts have no italic, so paint.h shears the run
after it is drawn (cv_slant): the plain fonts take one 1px step across the
middle of the line, the doubled pair a step per third. A row is copied from
k pixels further left rather than k to the right, so the room a step frees
fills with what lies before the run instead of keeping the ink it moved
away. SF_ITALIC reached the painter in F_FLAGS all along; nothing read it.
Fixes:
- ImgJobsDump() was the one diagnostic dump not behind #ifdef TESTBUILD, and
img_job_dump is never set: 180 packed bytes of a release build that could
not run.
The rest is size, so that the above fits. The 78 branch "if (pid == CP_*)"
chain in css_apply_decl is a switch, and so is the one in css_pseudo_decl;
form_kind() looks its <input type> up in a table; style_compute() copies the
initial style from style_init[] instead of assigning 42 fields one at a time;
ten streq chains are css_kw() lists; six else-if pairs with the same body are
merged.
177170 -> 176042 bytes, 65805 -> 65516 packed with kpack.
Tests: fonts.htm - the four fonts there are, where font-size switches between
them, and every shape of lean.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
- libHTTP: expose http_msg.flags (HTTP_GOT_ALL_DATA) in _http
- dl: a connection lost mid-download is an error, the cut file is not saved
- webview: a cut page shows "Connection lost" and is not cached
- webview images: only complete answers are cached, failed urls are not
refetched, natural <img> size kept in the node, slot kind fixed at start
- webview: remove the History menu item and WebView:history page
- CSS/form fixes, CANVAS_LEAN to leave unused canvas methods out
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
c-- evaluates left to right with no operator precedence, so "k + _w * 4" was
compiled as "(k + _w) * 4". k is already in bytes, so cv_slant() copied 3 * k
bytes too many: up to 6 pixels past the run, and past the canvas buffer itself
on the last row.
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
1. browser/tabs.h:232, "open in new tab" replaces the current page when the bar is full
Raised in round 2, still open. TAB::add() returns false without doing anything when count == TABS_MAX (tabs.h:26), and EventOpenNewTab() ignores that:
The author knows the behaviour: EventViewSource (WebView.c:1101) and EventNewBlankTab (tabs.h:241) both guard with T_NO_FREE_TAB and carry comments
saying why ("with every tab taken EventOpenNewTab() loads into the current one"). Two
call sites have no guard: WebView.c:869, reached by a middle click on a link and by
"Open in new tab", and WebView.c:380, a URL handed over by another instance.
2. browser/WebView.c:1131, Update browser skips the whole shutdown
The close button does case 1: ImgJobsCancelAll(); cache2_save(); ExitProcess();
(WebView.c:399). EventUpdateBrowser() does EventOpenDownloader(#update_param); ExitProcess(); and nothing else. img_thread.h states that ExitProcess() "ends this
thread only" and that the workers "must not go on", so the fetch threads survive the
window, keep sockets open and keep writing wv_* files, and the session's cache index is
never saved.
3. browser/const.h:44 and :96, Update browser lost its checks and its target update_param is now "<url>|/sys/network/WEBVIEW". The implementation it replaced
(git show 6713e2858^:browser/WebView.c) downloaded to /tmp0/1/Downloads, compared get_file_size(#program_path) with the new file, refused a truncated download, said
"already up to date" when the sizes matched, copied over #program_path (the file the
running copy was started from), reported a failed copy, then saved the cache and
restarted itself. All of that is gone: the new build is written to a fixed path that need
not be the running one, with no size check and no message of any kind.
4. browser/engine/form.h:814, an iconv descriptor per form submit, and no way to close it iconv_open is called on every submit of a non-cp866 page and the result kept in fq_cd. lib/obj/iconv.h imports only iconv_open and iconv: there is no iconv_close binding
at all, so the descriptor cannot be released without adding the import first.
5. browser/WebView.c:989, view source runs the tail of the load twice LoadInternalPage() calls ShowSource(), and ShowSource() calls LoadInternalPage()
again (show_src.h:98). The inner call runs the whole tail; control then returns to the
outer one, which runs it again. _http::hfree() has no guard on transfer
(lib/obj/http.h:150-154), so the second pass calls http_free stdcall (0). GetImg()
returns at once because a source page has no pictures or sheets, and the second PageLoaded() only rewrites the status, so the null free is the whole of it.
6. browser/WebView.c:1390, Save image with no address EventImageOpen() (1384) and EventImageCopyUrl() (1399) both start with if (!ctx_img_url[0]) return;. EventImageSave() does not, and runs RunProgram("/sys/network/dl", "-e ") on an <img> whose address could not be resolved.
7. browser/WebView.c:1322, the find box keeps a stale scroll and selection EventFindClose() zeroes flags, size and pos but leaves offset, shift and shift_old. notes/notes.c:200-201 is the same situation done fully: offset = shift = shift_old = 0; cl_curs_x = cl_curs_y = 0.
Performance
8. browser/WebView.c:1410, the find bar is rebuilt on every hovered link DrawStatusBar() discards _msg and calls DrawFindBar() whenever find_visible is
set. hit.h:95-101 fires on every change of the hovered link, so crossing a link-dense
page with the find bar open re-runs DefineHiddenButton three times, two raised buttons
and a full edit_box_draw per link, and the hovered URL is never shown.
Notes
9. browser/engine/style.h:5718, read_file(cache2.path.get(cache2.cur), #data, #size)
is the one place that does not follow the file's own rule of hoisting a call out of
another call's arguments. The generated code is correct here (the inner result is pushed
before anything else touches EAX), so this is about keeping the convention, not a defect.
10. browser/settings.h:9, the new search_engine default https://lite.duckduckgo.com/lite/?q= is never reached on a stock system: the shipped app.ini sets search_engine=http://wiby.me/?q= and an ini key wins over the code
default. It also disagrees with it, and the https form works only because the same file
sets proxy_address=http://proxy.kolibrios.org/?site= (img_job_url() refuses https
without a proxy). Either update the OS-side app.ini with it or keep the code default on
http.
11. browser/engine/style.h, style_init[100] spans offsets 0..399, the old NODE_SIZE. This commit grew the node to 408 and put N_IMGW/N_IMGH at 400 and 404,
outside every range style_compute() copies, which is right for structural fields. A style field added past 399 would silently stop being reset.
12. The multi-line comments carrying implementation rationale are still there
(cache.h:70, WebView.c:10, paint.h:165, engine.h:420, cookies.h:1). That
belongs in the commit message.
## Correctness
**1. `browser/tabs.h:232`, "open in new tab" replaces the current page when the bar is full**
Raised in round 2, still open. `TAB::add()` returns false without doing anything when
`count == TABS_MAX` (`tabs.h:26`), and `EventOpenNewTab()` ignores that:
```
void EventOpenNewTab(dword _url)
{
tab.add();
OpenPage(_url);
```
The author knows the behaviour: `EventViewSource` (`WebView.c:1101`) and
`EventNewBlankTab` (`tabs.h:241`) both guard with `T_NO_FREE_TAB` and carry comments
saying why ("with every tab taken EventOpenNewTab() loads into the current one"). Two
call sites have no guard: `WebView.c:869`, reached by a middle click on a link and by
"Open in new tab", and `WebView.c:380`, a URL handed over by another instance.
**2. `browser/WebView.c:1131`, Update browser skips the whole shutdown**
The close button does `case 1: ImgJobsCancelAll(); cache2_save(); ExitProcess();`
(`WebView.c:399`). `EventUpdateBrowser()` does `EventOpenDownloader(#update_param);
ExitProcess();` and nothing else. `img_thread.h` states that `ExitProcess()` "ends this
thread only" and that the workers "must not go on", so the fetch threads survive the
window, keep sockets open and keep writing `wv_*` files, and the session's cache index is
never saved.
**3. `browser/const.h:44` and `:96`, Update browser lost its checks and its target**
`update_param` is now `"<url>|/sys/network/WEBVIEW"`. The implementation it replaced
(`git show 6713e2858^:browser/WebView.c`) downloaded to `/tmp0/1/Downloads`, compared
`get_file_size(#program_path)` with the new file, refused a truncated download, said
"already up to date" when the sizes matched, copied over `#program_path` (the file the
running copy was started from), reported a failed copy, then saved the cache and
restarted itself. All of that is gone: the new build is written to a fixed path that need
not be the running one, with no size check and no message of any kind.
**4. `browser/engine/form.h:814`, an iconv descriptor per form submit, and no way to close it**
`iconv_open` is called on every submit of a non-cp866 page and the result kept in `fq_cd`.
`lib/obj/iconv.h` imports only `iconv_open` and `iconv`: there is no `iconv_close` binding
at all, so the descriptor cannot be released without adding the import first.
**5. `browser/WebView.c:989`, view source runs the tail of the load twice**
`LoadInternalPage()` calls `ShowSource()`, and `ShowSource()` calls `LoadInternalPage()`
again (`show_src.h:98`). The inner call runs the whole tail; control then returns to the
outer one, which runs it again. `_http::hfree()` has no guard on `transfer`
(`lib/obj/http.h:150-154`), so the second pass calls `http_free stdcall (0)`. `GetImg()`
returns at once because a source page has no pictures or sheets, and the second
`PageLoaded()` only rewrites the status, so the null free is the whole of it.
**6. `browser/WebView.c:1390`, Save image with no address**
`EventImageOpen()` (`1384`) and `EventImageCopyUrl()` (`1399`) both start with
`if (!ctx_img_url[0]) return;`. `EventImageSave()` does not, and runs
`RunProgram("/sys/network/dl", "-e ")` on an `<img>` whose address could not be resolved.
**7. `browser/WebView.c:1322`, the find box keeps a stale scroll and selection**
`EventFindClose()` zeroes `flags`, `size` and `pos` but leaves `offset`, `shift` and
`shift_old`. `notes/notes.c:200-201` is the same situation done fully:
`offset = shift = shift_old = 0; cl_curs_x = cl_curs_y = 0`.
## Performance
**8. `browser/WebView.c:1410`, the find bar is rebuilt on every hovered link**
`DrawStatusBar()` discards `_msg` and calls `DrawFindBar()` whenever `find_visible` is
set. `hit.h:95-101` fires on every *change* of the hovered link, so crossing a link-dense
page with the find bar open re-runs `DefineHiddenButton` three times, two raised buttons
and a full `edit_box_draw` per link, and the hovered URL is never shown.
## Notes
**9. `browser/engine/style.h:5718`**, `read_file(cache2.path.get(cache2.cur), #data, #size)`
is the one place that does not follow the file's own rule of hoisting a call out of
another call's arguments. The generated code is correct here (the inner result is pushed
before anything else touches EAX), so this is about keeping the convention, not a defect.
**10. `browser/settings.h:9`**, the new `search_engine` default
`https://lite.duckduckgo.com/lite/?q=` is never reached on a stock system: the shipped
`app.ini` sets `search_engine=http://wiby.me/?q=` and an ini key wins over the code
default. It also disagrees with it, and the https form works only because the same file
sets `proxy_address=http://proxy.kolibrios.org/?site=` (`img_job_url()` refuses https
without a proxy). Either update the OS-side app.ini with it or keep the code default on
http.
**11. `browser/engine/style.h`**, `style_init[100]` spans offsets 0..399, the old
`NODE_SIZE`. This commit grew the node to 408 and put `N_IMGW`/`N_IMGH` at 400 and 404,
outside every range `style_compute()` copies, which is right for structural fields. A
*style* field added past 399 would silently stop being reset.
**12.** The multi-line comments carrying implementation rationale are still there
(`cache.h:70`, `WebView.c:10`, `paint.h:165`, `engine.h:420`, `cookies.h:1`). That
belongs in the commit message.
- scrolling (wheel, scroll bar, keys) moves the canvas and paints only the
band that came into view (paint_scroll)
- form controls take the page's width, height and padding (control_fit);
value="" shows the placeholder
- vertical-align: super / sub, text sits on an inline-block's baseline
- @media min/max-height against the window height
- margin-right in percent, z-index on flex/grid items, absolute boxes with
a px height, "width: auto; height: 100%" pictures
- transparent border colours, alpha edges over an empty canvas
- the hovered link no longer overwrites the find bar, ExitBrowser()
stops the image threads on every exit path
- shorter comments in cache.h, cookies.h, WebView.c
Assisted-by: Claude Opus 5 <noreply@anthropic.com>
- Short forms C--: IF ELSE WHILE FOR RETURN BREAK CONTINUE SWITCH CASE GOTO instead of lowercase ≈ −1360
- DSDWORD/DSBYTE instead of ESDWORD/ESBYTE (KolibriOS uses flat segments; the es: prefix is unnecessary) ≈ −170
- dom.n/attr/ntype/nfirst/nnext/nparent/ntext became standard functions dom_n(...), without passing 'this' ≈ −150
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Полная поддержка table
Базовый CSS
Рисуется теперь только видимая область (сильно уменьшает расход памяти)
Параллельная загрузка изображений в 16 потоков
Кэш картинок на /tmp0/1/cache
Выделение и копирование текста
Поиск по странице
ПКМ на картинке -> Можно сохранить
UPD:
Поддержка куки
Поддержка самбита форм по GET и POST: текстовое поле, чекбокс, радиобокс
Можно изменить размер шрифта
Обновлены встроенные страницы
Меню: добавлен пункт "Открыть в NetSurf"
Тулбар: добавлена кнопка открытия папки загрузки
Бинарник 22 КБ => 52 КБ, потому нужно будет освобождать место в IMG.
The old TWB renderer is replaced by an engine that builds a DOM, applies CSS, lays the page out into fragments and paints only what is visible. Engine (browser/engine): - DOM builder with scoped closing tags, entity decoding in text and attributes, raw text for script/style/textarea, <noscript> shown - CSS: <style>, style="" and <link rel=stylesheet> (local, cached or downloaded), custom properties and var(), @media walking, descendant and child selectors, class/id in any case, :link, :visited, :first-child, :last-child; colors, fonts, text-align, white-space, width, max-width, height (as a minimum), margins with auto and negative values, padding, borders, float, display incl. table parts, vw units - Layout: inline lines with baseline images and icons, <pre>, lists, <nav> menus in a row, tables with colspan/rowspan and percent columns, display:table with or without rows, floats with or without a width, float:right, centred blocks, flex rows (flex-grow, basis, wrap, gap, justify-content, auto margins, align-items) - position:absolute / fixed and flex each sit behind a switch in style.h (css_abspos off, css_flex on); text parked off-page or in a 1px clipped box stays hidden either way - Paint into a viewport canvas, text selection, find on page, hit testing, link hover Browser: - images load in a separate downloader process ("dl -i"), the image cache lives in /tmp0/1/Cache and survives a restart - Ctrl+A/C stay inside a focused edit box, right click on a selection offers Copy, view source works, file:// addresses, history and cache keep the real address instead of the proxied one, the built-in error page keeps its charset, DuckDuckGo Lite is the default search - URLs with spaces are escaped, a slash in an unquoted attribute no longer closes the tag dl: filename= without quotes, hidden mode "-i", no double free of the content buffer. Test pages for each area are in browser/tests. Assisted-by: Claude Opus 5 <noreply@anthropic.com>Critical: memory corruption
1.
browser/engine/style.h:310, stack overflow from any pagecss_match_compoundcopies a selector fragment intochar part[128]with no length cap, whileCSSRULE::addpasses selectors of up to ~250 characters. It smasheslc[256], the saved registers and the return address.2.
browser/engine/engine.h:243,Reparse()runs on an unbuilt DOMThe
dom.nodesguard present inhit.h:13andengine_restore_tabis missing here. F12 or Ctrl+Tab on a still loading tab makesdom.n(0)write through a null node and then walk a garbage child index.3.
browser/show_src.h:39, output buffer undersized 5xmalloc(bufsize*5), but one input byte can expand to 26 ("in TAG mode); markup made of short tags expands ~11x. Ctrl+U corrupts the heap. This PR also shrank the allocation by passingWB1.bufsize.4.
browser/engine/layout.h:849, pointer held across a reallocv = dom.attr(_idx, "src")points into thedpoolarena; the next twoplace_string()calls can reallocate it, andvis then passed to a third call. Every other attribute read in this file copies into a local buffer first.5.
browser/engine/engine.h:359andimage_url, one byte past the endstrncpyinlib/strings.hwriteslenbytes plus a terminator, but the buffers are declaredchar path[URL_SIZE].style_link_sheet(style.h:1125) gets this right withURL_SIZE + 1.Functional bugs
6.
browser/engine/style.h:360, wrong subject in long selectorsnpis pinned at 8 but the subject is taken asparts[np-1], so a selector with 9 or more compounds matches its 8th part instead of its last. The rule lands on the wrong nodes.7.
browser/WebView.c:192, text selection navigates awayNo
breakafterif (mouse.up) sel_end();, andlib/mouse.hrestoreskeyon the up event, soEventClickLinkfires. Releasing the button over an<a>after selecting text destroys the selection and loads the link.8.
browser/cache.h:164, two windows wipe each other's cacheremove_orphans()deletes everywv_*file missing from this process's index. Ctrl+N and-newbypass the single instance check and the index is only written on exit, so the second instance deletes files the first one'sdlchildren are still writing.9.
browser/WebView.c:864, image download progress never drawsDrawProgress()returns on!http.transfer, but images are now fetched by an externaldl -iafterhttp.hfree()has already cleared it. Thehttp_get_type==IMGbranches here and inHandleRedirectare dead code.10.
browser/engine/paint.h:104, clipped icons smearsrc += 4sits after thecontinue, so a skipped pixel does not consume the source. A<kosicon>near the canvas edge drifts diagonally instead of clipping cleanly.Resources and performance
11.
browser/engine/layout.h:1606, string arena grows without boundEvery layout pass appends fresh copies to
dpool;measure_blockandflex_measureroll backfrags.countbut notdpool.used. Resizing a window on a page with a long list doubles the arena until it runs out of memory. This is also what makes finding 4 reachable.12.
browser/engine/layout.h:1494, oversized table allocationcf_first/cf_end/cf_hare sizedR * MAXCOLS(64) althoughncolsis known at line 1359. A 2000x3 table takes 1.5 MB instead of 72 KB.13.
browser/engine/engine.h:449,style_all()runs twice per tab switchengine_restore_tab()callsstyle_all(), and both callers (tabs.h:157,tabs.h:179) immediately follow withReparse(), which calls it again and re-reads every linked stylesheet.Blocking
1.
c--/c--.exeCommit99cb5e87dre-adds the 1.1 MB binary thata4d502690deleted on purpose. Unrelated to the browser. Drop the commit.
Memory corruption
2.
engine/special.h:111Scan accepts 9 chars intochar special_code[10], thensprintf(#special_code, "#%i", code)writes the decimal form back.�="#268435455", 11 bytes. Overflows the stack local.
3.
engine/engine.h:557get_absolute_urlends instrncpy(dst, src, URL_SIZE),which writes URL_SIZE + 1 bytes. Fixed in
engine_get_bgimage(529) andstyle.h:2569; still URL_SIZE inengine_get_image(572),image_url(585),WebView.c:1403, 1412, 1442, 1590.4.
engine/hit.h:82links.active_urlholdsdpool.buf + offsetacross events.CheckImgDownloads->ImgRedraw->Relayout->POOL::addnreallocatesbuf.GetAbsoluteActiveURL()(WebView.c:1545) then navigates to freed memory.5.
WebView.c:259ctx_img_nodestores a raw node index. The context menu is aseparate process, so a tab switch or page load can replace
domfirst. "Save image"then indexes a smaller arena.
6.
engine/style.h:2493css_abs_urls:k = n * URL_SIZE + strlen(_text),n= count ofurl(. 500 occurrences = 2 MB request per sheet perstyle_all().mallocresult unchecked beforestrcpy/memmov.Functional
7.
engine/style.h:1896if (cnt >= 64) break;breaks the scan, not thecollection, so it keeps the first 64 matches, not the most specific. Later rules win
by source order in CSS; on a heavily-classed element they are dropped.
8.
WebView.c:386case TAB_CLOSE_IDcallsEventTabClosewithoutif (http.transfer) StopLoading();.EventCloseActiveTab(tabs.h:192) and middleclick both have it. Arriving page lands in the newly active tab.
9.
tabs.h:200Switch blocked onhttp.transferbut notimg_loading.img_queue,img_slot_idx,prbar,img_queue_genstill describe the old page, soCheckImgDownloadsrelayouts the new tab and mixes the queues. Same inEventTabClose.10.
WebView.c:861EventOpenNewTabignorestab.add()returning false atTABS_MAXand callsOpenPageon the current tab.EventNewBlankTab(tabs.h:225)and
EventViewSource(WebView.c:1091) check first.11.
engine/layout.h:2118measure_blockrestores every line variable exceptln_rw, andinline_block(905) calls it before savings_rwat 915.line_open()zeroes
ln_rw, soright = blk_x + blk_w - ln_rw(909) ignores afloat:rightonthe same line.
Performance
12.
engine/paint.h:312memopen("ICONS18", ...)per icon drawn, never closed.200
<kosicon>= 200 syscalls per repaint, refcount grows for the process lifetime.Open once at startup.
13.
engine/form.h:643form_submit_urlcallsform_owner()per node, andform_owner(111-144) scans backwards over the node list. Repeated byform_has_secret(247) andform_click(302). Quadratic in page size.14.
engine/style.h:2581style_allre-reads and re-parses every<link>fromdisk (
read_file+css_abs_urlscopy +css_parse_sheet). Called fromParseHtml,Reparse(tab switch, F12, zoom),Relayouton@mediachange (engine.h:257),ImgRedrawper arriving sheet. Cache the parsed rules per document.Notes
15.
lib/keyboard.h:111KEY_MODIFIERSdefined, no users.16. Multi-line rationale comments from round 1 remain:
style.h:1009, 1120,layout.h:1725,paint.h:26,WebView.c:14.Features: - pictures and stylesheets are fetched by threads of WebView (img_thread.h) instead of "dl -i" processes: no 256 byte url limit, cookies are sent, stylesheets first and retried, hung threads given up, orphans bounded - status bar shows the page load: connecting, sending a form, KB received (of the total when known), images N/M - CSS: grid (tracks, spans, template areas), calc(), :is()/:where()/:not(), :nth-*, @supports not, media ranges, transform translate, inset, min-height/max-height, vw, fractional px/em - layout: absolute positioning inside blocks and inline boxes, paint order sort, float carry between blocks, flex order and item alignment - <details>/<summary>, checkbox and radio painting, <label> targets, <noscript>, webp twin images, image rescaling to fit - cache: stylesheets outlive pictures, big pictures dropped once laid out, evicted sheets are fetched again on a tab switch or font change - updater downloads straight to /sys/network/WEBVIEW - tests: calc, checkbox, details, floatcarry, grid, gridareas, iswhere, minheight, noscript, webp; sitetest.py site smoke test for the test VM Fixes: - stack raised: debian.org crashed with the stack running into globals - content-type compared in lower case (charset=UTF-8) - redirect buffer sized for get_absolute_url() lib: collection::swap, ed_select flag for the rewritten box_lib, local path check requires a disk number ("/cdn-cgi/...", "/hdimages/" are site paths). Assisted-by: Claude Opus 5 <noreply@anthropic.com>Correctness
1.
browser/tabs.h:232, "open in new tab" replaces the current page when the bar is fullRaised in round 2, still open.
TAB::add()returns false without doing anything whencount == TABS_MAX(tabs.h:26), andEventOpenNewTab()ignores that:The author knows the behaviour:
EventViewSource(WebView.c:1101) andEventNewBlankTab(tabs.h:241) both guard withT_NO_FREE_TABand carry commentssaying why ("with every tab taken EventOpenNewTab() loads into the current one"). Two
call sites have no guard:
WebView.c:869, reached by a middle click on a link and by"Open in new tab", and
WebView.c:380, a URL handed over by another instance.2.
browser/WebView.c:1131, Update browser skips the whole shutdownThe close button does
case 1: ImgJobsCancelAll(); cache2_save(); ExitProcess();(
WebView.c:399).EventUpdateBrowser()doesEventOpenDownloader(#update_param); ExitProcess();and nothing else.img_thread.hstates thatExitProcess()"ends thisthread only" and that the workers "must not go on", so the fetch threads survive the
window, keep sockets open and keep writing
wv_*files, and the session's cache index isnever saved.
3.
browser/const.h:44and:96, Update browser lost its checks and its targetupdate_paramis now"<url>|/sys/network/WEBVIEW". The implementation it replaced(
git show 6713e2858^:browser/WebView.c) downloaded to/tmp0/1/Downloads, comparedget_file_size(#program_path)with the new file, refused a truncated download, said"already up to date" when the sizes matched, copied over
#program_path(the file therunning copy was started from), reported a failed copy, then saved the cache and
restarted itself. All of that is gone: the new build is written to a fixed path that need
not be the running one, with no size check and no message of any kind.
4.
browser/engine/form.h:814, an iconv descriptor per form submit, and no way to close iticonv_openis called on every submit of a non-cp866 page and the result kept infq_cd.lib/obj/iconv.himports onlyiconv_openandiconv: there is noiconv_closebindingat all, so the descriptor cannot be released without adding the import first.
5.
browser/WebView.c:989, view source runs the tail of the load twiceLoadInternalPage()callsShowSource(), andShowSource()callsLoadInternalPage()again (
show_src.h:98). The inner call runs the whole tail; control then returns to theouter one, which runs it again.
_http::hfree()has no guard ontransfer(
lib/obj/http.h:150-154), so the second pass callshttp_free stdcall (0).GetImg()returns at once because a source page has no pictures or sheets, and the second
PageLoaded()only rewrites the status, so the null free is the whole of it.6.
browser/WebView.c:1390, Save image with no addressEventImageOpen()(1384) andEventImageCopyUrl()(1399) both start withif (!ctx_img_url[0]) return;.EventImageSave()does not, and runsRunProgram("/sys/network/dl", "-e ")on an<img>whose address could not be resolved.7.
browser/WebView.c:1322, the find box keeps a stale scroll and selectionEventFindClose()zeroesflags,sizeandposbut leavesoffset,shiftandshift_old.notes/notes.c:200-201is the same situation done fully:offset = shift = shift_old = 0; cl_curs_x = cl_curs_y = 0.Performance
8.
browser/WebView.c:1410, the find bar is rebuilt on every hovered linkDrawStatusBar()discards_msgand callsDrawFindBar()wheneverfind_visibleisset.
hit.h:95-101fires on every change of the hovered link, so crossing a link-densepage with the find bar open re-runs
DefineHiddenButtonthree times, two raised buttonsand a full
edit_box_drawper link, and the hovered URL is never shown.Notes
9.
browser/engine/style.h:5718,read_file(cache2.path.get(cache2.cur), #data, #size)is the one place that does not follow the file's own rule of hoisting a call out of
another call's arguments. The generated code is correct here (the inner result is pushed
before anything else touches EAX), so this is about keeping the convention, not a defect.
10.
browser/settings.h:9, the newsearch_enginedefaulthttps://lite.duckduckgo.com/lite/?q=is never reached on a stock system: the shippedapp.inisetssearch_engine=http://wiby.me/?q=and an ini key wins over the codedefault. It also disagrees with it, and the https form works only because the same file
sets
proxy_address=http://proxy.kolibrios.org/?site=(img_job_url()refuses httpswithout a proxy). Either update the OS-side app.ini with it or keep the code default on
http.
11.
browser/engine/style.h,style_init[100]spans offsets 0..399, the oldNODE_SIZE. This commit grew the node to 408 and putN_IMGW/N_IMGHat 400 and 404,outside every range
style_compute()copies, which is right for structural fields. Astyle field added past 399 would silently stop being reset.
12. The multi-line comments carrying implementation rationale are still there
(
cache.h:70,WebView.c:10,paint.h:165,engine.h:420,cookies.h:1). Thatbelongs in the commit message.