Skip to content

Northstar Browser 1.0.6

Latest

Choose a tag to compare

@andreasrosdal andreasrosdal released this 31 Jul 17:15

Northstar Browser 1.0.6

Northstar is a web browser, written from scratch in C, focused on supporting the HTML and CSS standards.
The browser runs on Linux, macOS and Windows.

Northstar is free software, licensed under the GNU General Public License, version 3 or later.

https://nordstjernen.org/

Also see https://github.com/nordstjernen-web/nordstjernen which is based on Northstar Browser.

image

Northstar 1.0.6

A minimalist web browser written from scratch in C, with no upstream
browser engine. This release is mostly about running real sites: the
layout, CSS and DOM gaps that kept pages like lichess, chess.com, bbc.com
and Hacker News from rendering correctly are closed, and the text and
cascade paths were rebuilt around caches that make a page load
substantially faster.

HIGHLIGHTS

  • Text is laid out through ns-pango, a Pango fork carried as a subproject,
    which adds the process-wide shaping cache Pango has no place for. Layout
    time falls 25% on a text-heavy page and 38% on a table-heavy one.
    Shaping results are unchanged and verified byte-identical across a
    corpus covering RTL, bidi, CJK, small-caps and font features.
  • The CSS cascade indexes :is() and :where() subjects and stops allocating
    per selector test. On a page built to exercise this the initial cascade
    falls 52% and the whole headless run 16%; the css and dom test subset
    gains 826 subtest passes from tests that previously ran out of time.
  • Grid is largely rebuilt: named lines, min-content and max-content
    tracks, tracks in any length unit, correct intrinsic widths for a grid
    container, and area-placed items that honour align-items.
  • Web Audio actually renders. OfflineAudioContext used to resolve a buffer
    of zeros; oscillators, gain, compressor, biquad, delay, wave shaping and
    buffer playback are now implemented in the engine.
  • Relative colour syntax, the color() function, and one shared scanner for
    all six colour functions.

LAYOUT AND CSS

  • Grid items can be placed on named lines; a line named in the track list
    used to be dropped, so grid-column: main resolved to nothing.
  • min-content and max-content grid tracks size to their content instead of
    stretching like auto.
  • A grid track can be measured in any length unit. Unreadable tracks were
    silently dropped, shifting every remaining track one place left.
  • A grid container's min-content and max-content widths are the sum of its
    columns, not the width of its widest item.
  • A grid item placed by area name is aligned to its row and stretches by
    default.
  • A single flex line is as tall as the container says, rather than growing
    to the tallest item.
  • align-items: baseline and align-self: baseline work instead of falling
    through to flex-start.
  • An inline-block, inline-flex or inline-grid sits on the text baseline by
    the baseline of its own last line box, as CSS 2.1 requires.
  • Flex and grid items measure intrinsic sizes in the font they will
    actually be drawn in, so web-font text no longer wraps mid-phrase.
  • An absolutely positioned box with width: auto gets a real shrink-to-fit
    width, measured by shaping the text rather than guessed at 0.65em per
    character.
  • A percentage inside min(), max() and clamp() resolves against the box
    rather than the viewport.
  • border-radius: 50% paints a circle. Percentage radii were treated as
    pixels and calc() radii dropped; elliptical corners now work.
  • Relative colour syntax is implemented, including calc() over a channel
    keyword, and the color() function parses across nine colour spaces.
  • One scanner now serves all six colour functions, rejecting the malformed
    forms that used to parse and accepting colours split across lines.
  • CSS tokenization closes an open function at end of input, so setting an
    unterminated value no longer swallows the rest of an inline style.
  • Table cells default to vertical-align: middle, as every browser's
    user-agent sheet does.
  • An image is drawn inside its own borders, padding and margin instead of
    from the margin-box origin.
  • An SVG with a viewBox but no width or height is fitted to the 300x150
    default object size instead of being rasterised square and stretched.
  • Dynamic :has() selectors update after class, attribute and child-list
    mutations; the selector-invalidation test subset gains 311 subtests.
  • hypot() returns a length, overflowing integer calculations clamp, large
    numbers no longer serialize in exponent notation, and 3D transforms keep
    their Z component.

DOM, CSSOM AND JAVASCRIPT

  • getComputedStyle resolves every property it enumerates. It listed 218
    properties and returned the empty string for 126 of them.
  • document.styleSheets includes linked sheets with their href and rules.
    One test page went from 13 reachable rules to 1895.
  • The DOM insertion methods run the insertion steps, so a script inserted
    through append, before, replaceWith and friends executes and a custom
    element gets its connectedCallback.
  • AbortSignal is a real interface object, so signal instanceof AbortSignal
    answers instead of throwing. MessagePort gains the same in the window.
  • Event-listener objects follow the Web IDL callback-interface algorithm.
  • Checkbox and radio activation follows HTML's pre-activation and
    canceled-activation steps; three focused tests move from 52/80 to 80/80.
  • CSSStyleSheet.insertRule() and deleteRule() enforce their arguments, and
    addRule()/removeRule() work; that interface test moves from 8/17 to 17/17.
  • Computed position values are normalized, and transform-origin and
    perspective-origin serialize as lengths.
  • Shorthands through the CSSOM: overflow, gap, grid-area and the
    four-value shorthands no longer silently drop the declaration.
  • A dialog opened from script renders, and a modal one is centred.
  • A finished keyframe animation keeps the value animation-fill-mode says
    it should, so an opacity: 0 plus fade-forwards no longer stays invisible.
  • A mouse or pointer event carries the window it was dispatched in;
    UIEvent.view used to be null everywhere.
  • A positioned box answers the pointer in the layer it paints in, so a
    fixed high z-index overlay is clickable.
  • An that paints nothing hands the pointer to what is under it.
  • An SVG font-size attribute survives the cascade.
  • Instantiating a module through the WebAssembly JS API runs the start
    section and nothing else, which is what Emscripten modules expect.
  • OfflineAudioContext renders audio instead of silence, with a real node
    graph behind it.
  • Workers get the APIs the polyfills already implement; thirteen globals
    differed between a worker and the window. A worker also shares the
    storage partition of the page that started it, so IndexedDB works there.

NETWORKING

  • A page on an origin that does not speak QUIC no longer stalls for the
    whole connect timeout. Requests ask for HTTP/2 and are upgraded to
    HTTP/3 through the alt-svc cache. Acid3 loads in 2.2 seconds instead of
    15.5. NS_FORCE_HTTP3=1 still asks for HTTP/3 outright.

PERFORMANCE

  • Text shaping is cached a word at a time rather than a run at a time, and
    a paragraph's items are cached too. Over a 200 KB page, shape-cache
    misses fall from 5265 to 155, HarfBuzz drops from 28.6% of the process
    to 1.5%, and layout goes from 159 ms to 112 ms.
  • Line, word and sentence breaks are cached. The whole headless page load
    runs 5.75% fewer instructions; the text engine alone 20% fewer.
  • The text caches are sharded sixteen ways, taking four-thread throughput
    from about 79 000 to about 98 000 layouts/s.
  • An IndexedDB write no longer walks the origin's whole storage directory
    on every put.
  • The font metrics behind the ex, ch, cap and ic units are measured once
    per font rather than once per length.

USER INTERFACE

  • prefers-color-scheme reports what the desktop is actually wearing, and
    the internal pages gain the dark half they never had.
  • An error page appears whenever a navigation has nothing to render, not
    only for https:// failures.
  • The status line clears when the pointer leaves a link and when a load
    finishes, and floats over the page only while it has something to say.
  • The toolbar reports the page zoom, with steps at 90, 100, 110, 125, 150.
  • Back and forward are green, reload is blue, and a red stop button
    appears while a page is loading.
  • The bookmark button shows whether the page is bookmarked; Escape closes
    the find bar; the title bar no longer doubles the product name.
  • Escape in the address bar restores the URL of the page on screen.
  • The toolbar menu covers New Window, Zoom In, Zoom Out, Reset Zoom, Full
    Screen, History and the two save entries, each naming its shortcut.
  • The title bar is shorter, giving the page the height back.
  • A single-line text field shows as many characters as its box has room
    for, not as many as its size attribute says.
  • A #fragment stays anchored while the page finishes loading.
  • A popover menu takes the height its items need.
  • about:northstar lists the user agent as a request actually resolves it.
  • The about:start splash is redrawn for the release.

DOCUMENTATION

  • docs/compliance.md records where the engine stands against the HTML and
    CSS specifications, how to reproduce the web-platform-tests scores, and
    the known structural gaps.

KNOWN LIMITATIONS

  • Web Audio renders mono, and AudioParam automation curves are ignored --
    a parameter reads as its current value for the whole render.
  • The stop button ends the loading state and marks the frame stale, but
    does not abort the network request behind it.

DOWNLOADS

northstar-1.0.6-windows-x86_64.zip -- Windows x64, self-contained.
Extract anywhere and run northstar.exe; no installer and no MSYS2
required. 57 MB compressed, 156 MB unpacked.
On Windows 11 you need to right click the .exe file, select properties, and choose "Unblock" or similar.

Windows marks anything downloaded from the internet as blocked, so before extracting, right-click the .zip file, choose Properties, tick "Unblock" at the bottom of the General tab and press OK — doing it on the archive first saves having to repeat it on northstar.exe afterwards, since the mark is copied to every file extracted from a blocked archive.

SHA-256:
c626532e7dc85c8e51ef5aebbc7f26308a3fcd616e81952956e75e30d847a315

  • docs/compliance.md records where the engine stands against the HTML and
    CSS specifications, how to reproduce the web-platform-tests scores, and
    the known structural gaps.

KNOWN LIMITATIONS

  • Web Audio renders mono, and AudioParam automation curves are ignored --
    a parameter reads as its current value for the whole render.
  • The stop button ends the loading state and marks the frame stale, but
    does not abort the network request behind it.