Short: Web browser with JS + HTML mail client Author: Juen/APX+NAH+R3D (Pawel Nowak) Uploader: biuro cdlabel info (Pawel Nowak) Type: comm/www Version: 1.3.0 Architecture: m68k-amigaos; ppc-amigaos; ppc-morphos; ppc-powerup; ppc-warpup; i386-aros Amelinium 1.3.0 - web browser AND mail client for classic Amiga =============================================================== Support me: http://juen.in/support Always new version here: http://juen.in A browser AND a mail client. The archive holds two programs that share one rendering engine, so a message with HTML and CSS looks the same in your inbox as a page does in the browser: Amelinium - the web browser Emalinium - the mail client (POP3 / IMAP / SMTP). It is not a plain-text reader: a message is laid out by the SAME engine as a web page. Requirements: - bsdsocket.library v4+ (works with IMPBOX bsdsocket.library!) - AmiSSL v5 for HTTPS support (without that still http:// sites works fine) - On AROS you need NEITHER of the two: the AROS builds carry their own TCP through the system and TLS 1.2 / 1.3 built into the executable, so HTTPS works with nothing else installed. - On AmigaOS 4 (PowerPC) it is the same as on 68k: bsdsocket from the system and AmiSSL v5 for HTTPS. - On a PPC card in a classic Amiga (Blizzard PPC / CyberStorm PPC under OS 3.x) the PowerUP (_PUP) and WarpOS (_WOS) builds carry their own TLS 1.2 / 1.3, like the AROS ones, so HTTPS needs no AmiSSL. The PowerUP builds set up their own stack. The WarpOS builds cannot, and need a BIGGER STACK than the shell gives by default: stack 600000 (from Shell, once per shell) STACK=600000 (in the icon's Tool Types, for Workbench) With less than 256 KB a WarpOS build says so and exits instead of stopping halfway through a deep page. The AROS builds (all four: i386, i386 ABI v0, x86_64 and aarch64) need NO extra library at all - not AmiSSL, and nothing to copy into LIBS:. Only the AROS system itself and its bsdsocket.library. Their TLS (1.2 and 1.3) is BUILT INTO the executable, so the download is one file and there is no library drawer to install. Why: AmiSSL has no AROS release at all. What ships for Amiga is m68k HUNK code, and an AROS system loads ELF - so the choice was a built-in TLS or no https at all on that machine. Third-party code in the AROS and PPC-card builds: Mbed TLS 3.6.7 (https://www.trustedfirmware.org/projects/mbed-tls/) is compiled into the AROS, PowerUP (_PUP) and WarpOS (_WOS) executables, unmodified. It is dual-licensed Apache-2.0 OR GPL-2.0-or-later - you may take it under either. The full text is in mbedtls-LICENSE.txt next to this readme. The 68k and AmigaOS 4 builds do not contain it; they use AmiSSL. !! HTTPS is encrypted but the server's CERTIFICATE IS NOT VERIFIED - i do not check who is on the other end. Treat it as protection against passive eavesdropping, not against an attacker who can redirect your traffic. The same applies to Emalinium's mail passwords. Builds: - Amelinium - 68000 (works on all Amigas, slowest) - Amelinium_020 - 68020+ - Amelinium_040 - 68040 WITH FPU (not 68EC040/68LC040) - Amelinium_060 - 68060 WITH FPU, fastest (not 68EC060/68LC060) - Amelinium_low - AmigaOS 1.3 (Kickstart 34+). No images, no downloads and NO MENU BAR - so no settings, bookmarks, tabs or About. - Amelinium_020_JS - 68020+ with built-in JavaScript - Amelinium_040_JS - 68040 WITH FPU, with built-in JavaScript - Amelinium_060_JS - 68060 WITH FPU, with built-in JavaScript - Emalinium - the mail client (any 68020+) The 040 and 060 builds use the maths coprocessor, so they need a full 68040 or 68060. On a 68EC040, 68LC040, 68EC060 or 68LC060 - the versions sold without a coprocessor - use Amelinium_020 or Amelinium_020_JS, which never use one. This only changes how fast JavaScript runs; page layout uses no floating point at all. Like any 68040/68060 program, they also need the CPU's own 68040.library or 68060.library in LIBS: - it supplies the instructions the chip leaves to software. - Amelinium_AROS_i386 - AROS on i386 (32-bit x86 PC), with JavaScript - Amelinium_AROS_x86_64 - AROS on x86_64 (64-bit PC, ABI v11), with JavaScript - Amelinium_AROS_aarch64 - AROS on 64-bit ARM (Raspberry Pi 3/4/5), with JavaScript - Amelinium_AROS_i386_v0 - AROS ABI v0 on i386 - the classic 32-bit line from axrt.org, with JavaScript. ABI v0 and ABI v1 are DIFFERENT systems: take the file that matches the AROS you installed. - Emalinium_AROS_i386 - the mail client on AROS i386 (ABI v1) - Emalinium_AROS_x86_64 - the mail client on AROS x86_64 (ABI v11) - Emalinium_AROS_aarch64 - the mail client on AROS 64-bit ARM - Emalinium_AROS_i386_v0 - the mail client on AROS ABI v0 (i386) - Amelinium_OS4 - AmigaOS 4.x on PowerPC - Emalinium_OS4 - the mail client on AmigaOS 4.x (PowerPC) - Amelinium_PUP - PowerUP: a PPC card in a classic Amiga (Blizzard PPC / CyberStorm PPC under OS 3.x). With JavaScript and HTTPS. Needs no AmiSSL - TLS is built in. - Emalinium_PUP - the mail client on the same PowerUP cards - Amelinium_MOS - MorphOS (PowerPC), with JavaScript and HTTPS. Needs no AmiSSL - TLS is built in. A young target, so it may not be perfect yet. - Emalinium_MOS - the mail client on MorphOS - Amelinium_WOS - WarpOS on the same PPC cards (Blizzard PPC / CyberStorm PPC under OS 3.x). With JavaScript and HTTPS. Needs no AmiSSL - TLS is built in. A young target, so it may not be perfect yet. - Emalinium_WOS - the mail client on WarpOS Known issues: - JavaScript: in the _JS builds. DOM scripting works, and so do jQuery, Prototype, script.aculo.us and Lightbox - including a jQuery packed with the Dean Edwards packer. Very heavy applications (youtube.com, the Cloudflare "checking your browser" page) load but can take minutes, and the Cloudflare check does not complete yet. A page whose scripts do a great deal of work will be slow: the interpreter is not fast, and that is the honest limit. - : scripts can draw on it (shapes, lines, text, gradients, shadows, pictures) and read its pixels back, but the canvas itself is not shown on the page yet - its space stays empty. - rotate() / skew() / matrix() are parsed but not drawn (translate() and scale() are) - Some pages may still render incorrectly - please report them - Slow on 68000, usable on 68030+ (faster from cache) If the browser will not start after an update: The update keeps the previous program next to it as .old, so rename that back over and you are running the old version again. Up to 1.1.1 an update download that stalled could be installed even though it was incomplete, which leaves a file the system cannot load; from 1.1.2 the download is checked and a broken one is refused. Command line: Amelinium [URL] [options] -screen WxH[xD] open an own screen of that size, skipping the mode requester - e.g. `-screen 1024x768x24` on an RTG card or `-screen 1280x512` on AGA. Picks the deepest mode the size offers when D is left out. This is the quickest way to a usable window on a big screen. -aga 640x512 8-bitplane PAL screen, no requester -wb open on the Workbench screen -js run page scripts everywhere, ignoring the per-site list. By default scripts are OFF until you allow a site, because one advertising bundle can exhaust the machine's memory. -ttf use TrueType fonts, downloading them first if they are not in PROGDIR:ttfonts yet. Same as the `ttf` toolbar button, but usable from a script or an icon. -proxy-host H -proxy-port P send everything through an HTTP proxy The same settings are available from the icon's Tool Types: URL, PROXYHOST, PROXYPORT, AGA, WB. Keyboard shortcuts: - Up/Down - scroll - Shift+Up/Down - page scroll - Space - page down - Backspace - page up - PageUp/PageDown - page up / down (PC-style keyboards) - Home/End - top / bottom of page - Amiga = / - - zoom in / out (also on the Page menu) - Esc - stop loading / stop a runaway script / close - F5 - reload - Amiga-C/X/V - copy / cut / paste: the form field you are typing in, the text you selected on the page, or the URL bar - Amiga-T / W - new tab / close tab (also on the Tabs menu) - Ctrl+click - open link in a background tab - Middle-click - open link in a background tab (3-button mouse) - Shift+click - open link in a new tab and go there - Amiga-B / F - back / forward - Amiga-H - home page - Amiga-L - jump to the address bar (selects what is there, so you can just type the next address) - Amiga-G - go to the address in the bar - Amiga-S - save this page - Amiga-/ - find on page - Amiga-. - random page - Amiga-? - about Pictures: GIF, JPEG, PNG, BMP and ICO are decoded on the Amiga, by the browser itself. Decoded pictures are cached on disk, so a second visit paints them without decoding again. !! SVG, WebP and AVIF FILES cannot be decoded here - there is no code on this machine that reads them. (An written directly into the page is different: Amelinium draws that itself and nothing leaves the machine.) Those files go out to a PUBLIC RASTERISER (images.weserv.nl), which converts them to PNG and sends that back. The address of the picture therefore leaves your machine and reaches a third party, which is worth knowing: it is the price of seeing an icon set that a modern site ships as SVG. Everything else is fetched straight from the site. Turning images off in the Settings menu stops both. Video: In the 040 and 060 builds and in the AROS, AmigaOS 4 and PPC-card builds, a with an MP4 file (H.264 picture, AAC sound) plays: click the picture or the triangle on the player bar to start, click again to pause, click the groove to jump. Sound goes through Paula, or through AHI when chosen in Settings -> Sound output. The picture is decoded in the background and shown as often as the machine manages - Settings -> Video playback chooses how often it tries, and "Key frames only" (the default) costs least. The 68000 and 020 builds do not play video. A YouTube watch address (youtube.com/watch?v=..., youtu.be/...) opens in Amelinium's own player page, because the player on youtube.com itself is far too heavy to be usable here. Settings -> Video quality chooses 144p (the default), 240p, 360p or sound only; a smaller picture decodes much faster. In the builds with JavaScript, 144p and 240p play in full, fetched the way YouTube's own embedded player fetches them - this runs YouTube's player code, which is downloaded once (about 2 MB) and again whenever YouTube changes it. Without JavaScript (Amelinium_040, Amelinium_060) a long film comes as 360p whatever you choose, and the page says so. The page links back to the original youtube.com page as well. WWW -> Video -> "YouTube search (Invidious)" opens a search page that renders without JavaScript. Opening one of its videos asks whether to play it in Amelinium's own player. !! Playing a YouTube video asks YouTube's servers for the stream, and the search page is run by a third party (inv.nadeko.net) - so what you look for and what you watch reaches them. Nothing is sent until you open such a page. PDF: In the builds with JavaScript a PDF file opens in a built-in viewer, like in Firefox: a toolbar with Previous / Next, the page number, zoom and Download stays at the top, and pages are drawn as you scroll to them. The viewer is pdf.js and lives in the pdfjs drawer next to the program - keep that drawer with the browser. Without it, and in the builds without JavaScript, a PDF is saved to disk instead (the status bar says why). WWW -> PDF lists Amiga user guides (A500 to A4000, CD32) from Aminet. A PDF page is drawn by JavaScript, so it takes a while on a slow machine. Fonts: Amelinium reads TrueType fonts ITSELF - it opens the .ttf file, reads the glyph outlines and rasterises them with its own scanline renderer. That path needs no FPU, no maths libraries and no external library at all, so TrueType text works on every Amiga from a plain 68000 upwards. It is on by default whenever the font files are present; the TT button turns it off. The AA button switches edge smoothing, which needs a truecolor screen - on a palette screen there is nothing to blend with, so the button is greyed. A site's own fonts are used too, when it offers them as TrueType through @font-face - that is how icon fonts draw real symbols instead of empty boxes. Each file is fetched once into the ttfonts drawer and reused on later visits. Web fonts are frequently SUBSETS: a font served for a Latin page often carries no Greek, no Cyrillic and no Polish letters, so any character the site's font does not have is taken from a built-in face instead of being left blank. Only that character changes face, the rest of the word keeps the site's font. Acknowledgments: Liberation Fonts (Red Hat, SIL OFL 1.1) - metric-compatible Arial / Times / Courier replacements. DejaVu Sans (DejaVu Fonts project, Bitstream Vera license) - used when CSS names Verdana or Tahoma; matches their wider metrics where Liberation Sans (Arial-metric) would be too narrow. Noto Emoji (Google, SIL OFL 1.1) - monochrome emoji font. AmiSSL by Oliver Roberts - TLS for HTTPS. stb_image (public domain) - PNG/GIF decoding. TJpgDec by ChaN (BSD-style, 2021) - tiny JPEG decoder with scale-on-decode (1/2, 1/4, 1/8). http://elm-chan.org/fsw/tjpgd/ Replaces stb_image for JPEG - same input, half the RAM and much faster on oversized photo thumbnails. Amiga Core Fonts for the Web (Amiga Information Center, 2000) - bitmap fallback when TT is unavailable. Helix AAC decoder (RealNetworks, RPSL 1.0) - decodes the AAC soundtrack of an MP4 movie. Present only in the 040 and 060 executables and on AROS / PPC / OS4; the 68000 and 020 ones do not carry it. Sources: github.com/pschatzmann/arduino-libhelix libavc H.264 decoder (The Android Open Source Project, originally by Ittiam Systems; Apache-2.0) - decodes the picture of an MP4 movie. Present in the same executables as the Helix decoder. License text: libavc-LICENSE.txt next to this readme. Sources: github.com/ittiam-systems/libavc minimp3 by lieff (public domain, CC0) - plays MP3 internet radio; same executables as the Helix decoder. github.com/lieff/minimp3 pdf.js 3.11.174 by Mozilla (Apache 2.0) - the PDF viewer of the JavaScript builds, in the pdfjs drawer with its LICENSE file. github.com/mozilla/pdf.js History: Recorded from 1.1.0 onwards. Earlier releases were not kept this way. 1.3.0 The biggest changes first: - PDF files open in a built-in viewer (pdf.js) in the JavaScript builds; WWW -> PDF lists Amiga user guides from Aminet. - Frames () run their own scripts, are drawn from what those scripts build, and talk to the page with postMessage. - has a working 2D drawing context (shapes, text, gradients, shadows, reading pixels back); the canvas itself is not shown yet. - Emoji have their own font (Noto Emoji) instead of empty boxes. - Sound can go through AHI as well as Paula (Settings -> Sound output). - JavaScript is faster (function calls and arithmetic 10-30% on a 68040, timers no longer wait for the screen tick) and far closer to Chrome: fetch(), XMLHttpRequest, async generators, Trusted Types, many Web APIs. - CSS: :has(), colours in oklch()/lab()/color() (Tailwind 4), , srcset sizes, min()/max()/clamp() with percentages, and many layout fixes found by comparing random sites with Chrome. All changes: - JavaScript: pages sent with Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy are cross-origin isolated like in other browsers (crossOriginIsolated, SharedArrayBuffer, performance.now() with 5 microsecond steps, 100 elsewhere); Atomics is available; ArrayBuffer gained byteLength, resize, transfer and detached. - JavaScript: navigator.storage.getDirectory() gives a working private file system (files and folders kept in memory for the session, writable streams, sync access handles in workers). - JavaScript: toString() of object and class methods, getters, setters and async functions returns their source text like other browsers. - JavaScript: Error.stack of a script written inside the page counts lines and columns from the start of the page (not of the script), columns past 65535 no longer wrap, and calls through o[key]() point where Chrome does. - JavaScript: canvas measureText() returns a TextMetrics object whose fields are prototype getters, like in other browsers. - JavaScript: DOM interfaces inherit from their parent interfaces as in the standard (MouseEvent from UIEvent, Comment from CharacterData, FileReader from EventTarget and so on), and every interface prototype has its own constructor property. - Emoji are drawn and measured with their own font (Noto Emoji, fetched with the other TrueType fonts) instead of an empty box, also in canvas measureText() and fillText(); emoji sequences joined with ZWJ (families, couples) are one picture, and characters beyond U+FFFF are no longer replaced by "?". - JavaScript: style.setProperty() ignores a priority other than "important" and a value carrying "!important", like other browsers; getPropertyPriority() exists, and the style attribute changed from a script reads back as "name: value;" pairs. - JavaScript: performance entries carry the Server-Timing metrics the server sent (serverTiming with PerformanceServerTiming objects), for the page, frames and fetched resources. - HTML comments are now part of the page for scripts (comment nodes, as in other browsers), and a short comment such as "" no longer hides the text that follows it. - JavaScript: constructors such as URL, FormData, Headers and DOMException report their real names. - JavaScript: TextEncoder and TextDecoder work like in other browsers: encodeInto(), the encoding names (latin1, utf-16 and the others), the fatal and ignoreBOM options, decoding a stream in pieces, and the TextEncoderStream and TextDecoderStream classes. - JavaScript: elements created by scripts are proper HTMLLinkElement objects, and getComputedStyle() of an element that is not in the page answers with empty values, as in other browsers. - JavaScript: writing to a WritableStream or TransformStream is queued like in other browsers, so the stream code runs in the right order instead of inside write(). - JavaScript: element properties have the right types and defaults (draggable, spellcheck and translate are true/false, and report numbers, scripts created by a script are async), and getComputedStyle() reflects styles a script just added, also inside frames. Setting innerText turns line breaks into . - JavaScript: text drawn on a keeps its true edge smoothing, so pixels read back with getImageData() match other browsers more closely. - JavaScript: Object.getOwnPropertyNames() of a Proxy around a function lists the function's own properties, and performance.memory reports exact numbers on web pages, as in other browsers. - JavaScript: matchMedia() returns a proper MediaQueryList, the browser's own bookkeeping attributes are no longer visible to page scripts, and nonce attributes are hidden as in other browsers when the page sends a Content-Security-Policy header. - JavaScript: each frame numbers its setTimeout()/setInterval() timers on its own, and clearTimeout() in a frame no longer cancels the page's timers. - JavaScript: navigator.plugins and navigator.mimeTypes are proper PluginArray and MimeTypeArray objects. - JavaScript: requestAnimationFrame() and requestIdleCallback() number their callbacks on their own and animation frames get a high-resolution timestamp, as in other browsers. - JavaScript: Date.parse() and new Date("...") accept the same date formats as other browsers (for example "2020-12-1", "Dec 1 999" or "12/1/2020 10:00 PM"). - JavaScript: structuredClone() copies dates, regular expressions, maps, sets, typed arrays, errors and cyclic objects like other browsers and reports DataCloneError for things that cannot be copied; Object(5n), BigInt.prototype methods and JSON.stringify() with BigInt behave as specified. - JavaScript: crypto.getRandomValues() and crypto.randomUUID() no longer use up the numbers a page gets from Math.random(). - JavaScript: canvas drawing casts shadows (shadowBlur, shadowColor, shadowOffsetX/Y). - JavaScript: adding a frame from a script no longer runs pending promise callbacks in the middle of that script. - JavaScript: each frame has its own eval(), so code evaluated through a frame's eval() runs in that frame (needed by Cloudflare checks). - JavaScript: frames with a srcdoc attribute load that content (they used to stay empty). - JavaScript: Array methods called on a string, such as Array.prototype.map.call("abc", f), work as in other browsers. - JavaScript: TextEncoder.encode() returns a Uint8Array and a Blob made of binary data keeps the bytes instead of the text "1,2,3". - Downloads from itch.io work again: the purchase page no longer runs the browser out of memory (a large canvas used to cost hundreds of megabytes), so the download page loads with its styles and the Download buttons start the file as before. - JavaScript: typed arrays over a million elements are created (an invalid length now throws RangeError), canvas.toDataURL() produces a compressed PNG quickly, and JSON.stringify of a typed array gives an object like other browsers. - JavaScript: getBoundingClientRect() of an inline element includes an empty inline-block or ::after{content:""} inside it, and its height is the height of its text, not of an image or box placed in it. - JavaScript: performance.timing and the navigation entry report the real phases of loading a page (DNS, connection, request, response, DOMContentLoaded, load), performance.now() counts from the start of the navigation, and DOMContentLoaded handlers run before load handlers; " ".repeat() no longer gives an empty string for long results. - JavaScript: Function.prototype.bind can be taken and called as a value (Function.prototype.bind.call(f, ...)), Object.getPrototypeOf works on numbers and strings, RegExp flags/source/compile, the regexp symbol methods, Symbol.description, the remaining well-known symbols, isWellFormed/toWellFormed and getYear/setYear exist, and built-in objects list their own properties in the same order as other browsers. - JavaScript: timers and inter-frame messages no longer wait for the 1/10 second screen tick, so scripts that chain zero-delay timeouts or talk between frames run far faster; nested timers keep the standard 4 ms minimum. - Internet radio: Radio Kiss Morava added to WWW menu -> Radio. - JavaScript: strict mode, class static members and private fields, super, destructuring from strings, Sets and generators and into object properties, and several smaller fixes to objects, Map and JSON.parse. - JavaScript: promises accept "thenable" objects such as the ones jQuery and many libraries return (the result used to arrive as the object itself), and error types (TypeError, RangeError...) are told apart correctly; AggregateError added. - JavaScript: dates - years beyond 9999, month overflow in setMonth, Date() called as a function and invalid dates in JSON follow the standard. - Layout: nested rows on Bootstrap pages (.row inside .row) get their full width and spacing, and getComputedStyle() reports real widths and heights in pixels. - Layout: a box beside a float may let its margin overlap the float, as in other browsers (code blocks on Bootstrap pages were too narrow). - Stylesheets whose media list spans several lines are loaded (w3.org lost its layout), and matchMedia() answers like the stylesheet does. - Old Internet Explorer style hacks (`* html ...`) are ignored as in other browsers (they broke layouts such as eff.org). - CSS rules such as `.row:nth-child(2) .item` or `li:first-child span` (a structural condition on an ancestor) are applied instead of skipped. - JavaScript: spreading sets, strings and generators into function calls, Map and Set built from any iterable, and matchAll() results work. - JavaScript: SVG elements written in the page have their proper types (SVGRectElement, SVGPathElement...), so getBBox() works on them, including exact bounds of paths, curves and arcs; getElementsByTagName() with the name of a custom or SVG element no longer returns every element. - Layout: form fields and buttons that a stylesheet turns into table cells (Bootstrap 3 search boxes) stay ordinary inline fields, as in other browsers. - Layout: a fieldset's legend sits on its top border with a gap in the frame, as in other browsers (it used to sit inside the box), and fieldsets get the standard default frame and spacing. - Stylesheets: class names, ids and attribute values are case-sensitive on modern pages, as in other browsers (a rule for .myRow no longer styles class="myrow"); old pages without a doctype keep the lenient matching, now also in querySelector() and getElementsByClassName(). - Forms: the label of an input button stays on one line and a width given to the button is kept; an input of type button without a value is empty, not "Button". A written inside the page body no longer moves into the head. - Layout: the grid shorthand with auto-flow (grid: auto / auto-flow 200px) works, so product carousels and tile rows on shop themes are laid out side by side instead of in one long column. - Layout: images sized in percent (width: 100%) no longer force their column or box to the picture's full size; two equal columns stay equal and boxes around such images shrink to the space available. - Layout: a (charts, games, drawings) takes up its space on the page as in other browsers (300x150 by default, or the size it states) instead of collapsing to nothing; its content is not drawn yet. - Style: rules using :popover-open, and negated states such as :not(:disabled), :not(:checked) or :not(:popover-open), now apply; menus that are hidden until opened no longer show up on the page, and a rule for an open popover no longer hits closed ones. - Layout: a height written as calc() with a percentage in an element's own style attribute (height: calc(100% - 20px)) now resolves against its container instead of turning into a fixed 100 pixel minimum, and margin: calc(...) 0 there no longer puts the same margin on all sides. - Layout: an image that has not loaded yet (or uses a placeholder) keeps the proportions its width and height attributes give it, so pictures scaled down with max-width no longer collapse or stretch before they arrive; aspect-ratio also survives a max-width limit, and a box with a set height and aspect-ratio takes its width from the ratio. - Pages opened from disk: a picture whose file is missing now shows its alternative text, as it does for a missing picture on the web, instead of an empty box of the picture's size. - Style: a rule for menu items three levels deep (for example "nav ul ul li a") no longer also hits the top-level items, which made every entry of such a menu as wide as its drop-down. - JavaScript: background page requests (XMLHttpRequest) now finish after the script that sent them has continued, as in other browsers, and a request that cannot reach its server reports an error instead of an empty success - pages that retry or fall back on failure now do so. - JavaScript: page requests with very long addresses (over 1024 characters) are no longer cut short. - JavaScript: scripts can read every response header of their page requests (getResponseHeader), with the same cross-site limits as other browsers, and pictures created by scripts inside a frame now load. - JavaScript: scripts inside a frame see the Crypto and SubtleCrypto interfaces, like scripts on the page. - JavaScript: error messages read like in other browsers, and several mistakes now raise an error as they should (setting a property on null, 'in' or 'instanceof' on a non-object, spreading a number, destructuring null, calling a string method on null). - JavaScript: XMLHttpRequest offers the full standard set of properties and constants, including responseType "json" and "arraybuffer". - JavaScript: XMLHttpRequest reports its progress step by step and passes a proper event object to its handlers, and buffers made by the engine are real ArrayBuffers. - JavaScript: has a 2D drawing context. Scripts can draw rectangles, lines, curves, circles, gradients and text, clip and blend, copy pictures and other canvases onto it, and read the pixels back; a canvas is still not shown on screen. - A PNG picture whose data is damaged but whose header is fine now counts as loaded, with its size and transparent pixels, as in other browsers. - JavaScript: fetch() works properly. Every answer used to arrive with status 0 and an empty body, and a failed connection was reported as an answer instead of an error; responses now carry their real status, status text, headers and body, a body can be read once, and a network failure rejects with "Failed to fetch", as in other browsers. - JavaScript: code run through eval() no longer reads its own names from memory that was already released - this caused random wrong names, "is not a constructor" errors and crashes on heavy pages. - JavaScript: reading a variable that was never declared now throws ReferenceError ("x is not defined") instead of quietly giving undefined, and several other errors are now thrown where every browser throws them (String.fromCodePoint with an invalid value, a prototype chain that would loop, "caller" and "callee" in strict code). - JavaScript: XMLHttpRequest statusText is the server's own phrase ("Unauthorized"), not always "OK". - JavaScript: FontFace and document.fonts follow the CSS Font Loading rules: asking for a local font that is not installed now fails the way it does in other browsers, instead of claiming every font exists. - JavaScript: navigator.storage, navigator.permissions, getGamepads, getBattery, speechSynthesis, Notification, BroadcastChannel, screen.orientation and navigator.gpu now exist, answering honestly for this machine (no gamepads, no voices, no GPU, mains power). - JavaScript: Trusted Types (trustedTypes, policies, TrustedHTML and TrustedScript). A frame whose Content-Security-Policy requires them now refuses eval() and new Function() on plain strings, as other browsers do; innerHTML accepts a TrustedHTML value. - Layout: stretched flex items take the height of their row even when their content is taller, and overflow: clip no longer lets a flex item shrink below its content. - Layout: absolutely positioned boxes with top, bottom and auto margins are centred vertically; grid columns no longer grow to fit an item that has min-width: 0; :not() with several structural conditions works; CSS rules that combine an attribute test with :not(#id), or an ancestor written as #id.class, apply exactly where they should. - Movies: picture and sound stay in step - the picture ran about a tenth of a second ahead of the sound, more on AmigaOS 4. - Fixed: a very long text page (one text block over 64 KB, such as a whole manual in one ) was cut short, and its later lines were drawn over the top of the page. - Frames () run their own scripts and talk to the page with postMessage, as security checks and embedded widgets need. - YouTube: the cookie consent window fits the screen, its text scrolls to the end and its buttons show their labels. - YouTube: the cookie consent choice is saved, search results appear, and the YouTube logo and channel pictures show. - Pictures that a page's own scripts add or change are loaded now, with the load events pages wait for (thumbnails on YouTube and on many modern sites stayed empty before). - Fixed: a symbol such as a bullet could turn into odd characters where a page lets long words break anywhere. - JavaScript: text built piece by piece in a loop (s += x) is much faster, and very long results no longer come out cut short. - JavaScript: regular expressions match repeats longer than 511 characters (long addresses and texts failed to match before). - JavaScript: new Image() and new Audio() create real elements; images that scripts create report complete only once loaded. - Fixed: a script copying a promise, Map or similar built-in object (as YouTube does) could crash the browser a while later. - JavaScript: IntersectionObserver behaves as in other browsers, so pages no longer load their own slower replacement for it. - YouTube: the cookie consent window has its white background (its text was drawn straight over the page). - Fixed: a style sheet that a script adds to a page with no style sheet of its own had no effect. - YouTube: icons show (logo, menu, buttons, list markers) - scripts now see the contents of SVG pictures, and arcs in SVG paths are drawn as real curves. - Fixed: an element hidden with an invalid opacity value (as YouTube sets it) stays visible, as in other browsers. - A scrolling box inside a window that stays in place (position: fixed, as in most dialogs) now scrolls its content, not just its scrollbar. - Clicks reach boxes that a page positions freely (absolute, fixed) also right after the page has changed them. - Layout: percentage heights inside CSS grids, icons mirrored with scale, var()var() written without a space. - JavaScript: many fixes to text with non-English letters, number formatting, Intl, element scroll positions, getBoundingClientRect inside scrolled boxes, and custom elements (the building blocks of YouTube and similar sites). - JavaScript: localStorage and sessionStorage accept the short form (localStorage.key = value, localStorage.key) and list stored keys; MessageChannel messages arrive without timer delay, so pages built with React respond faster; constants really are constant; Proxy objects work with for-in, JSON and property descriptors; Object.keys() of built-in objects and of the window lists the same as in other browsers; SVG text elements report character positions. - Layout: text set in fractional font sizes (16.5px) gets its proper line height; percentage table columns are measured from the table width; flex carousels wider than 32767 pixels are laid out correctly; a closed stays closed even when a style sheet sets display on its content; text is laid out like in other browsers (on one line, not scrolling). - Style: flex-basis with calc(), grid rows in fr units inside a grid of automatic height (including collapsed 0fr accordions), and width or max-width written with min(), max() or clamp() and one or more percentages (Elementor background videos no longer shrink to nothing). - Style: !important now also wins for widths and heights in percent, calc() or auto, and for percentage padding and max-width; several selector forms (".item:last-child:after", a class written after :not(), long sibling names, "!important" rules with two ancestors) apply exactly where they should; getComputedStyle() answers for every property. - Style: rules meant for forced colors, high contrast, inverted colors or HDR screens no longer apply on an ordinary screen (GitHub links were drawn in the wrong colour). - Scrolling: pages whose content scrolls inside the body while the page itself does not (Google News) can be scrolled with the main scrollbar, wheel and keys. - Frames show the content their own scripts build; frames created inside other frames and frames loaded from blob: addresses work. - JavaScript: lists such as querySelectorAll(), children, childNodes, form.elements and attributes are proper NodeList, HTMLCollection and NamedNodeMap objects with item(), namedItem() and forEach(); classList, URLSearchParams, FormData and Headers can be looped over (YouTube). - JavaScript: Math.sin, cos, tan, atan2, cbrt, log2 and their relatives give exactly the results other browsers give (sin of very large numbers and even of Math.PI came out different before). - JavaScript: Date.now() and performance.now() tick in fractions of a millisecond and agree with each other. - JavaScript: many smaller additions so pages see a standard browser: CSS.supports(), screen and window sizes from the real screen, performance.memory, location and history as proper objects, element types reported correctly, and requests to other sites send only the site name as referrer, as other browsers do. - A page that builds an empty frame (about:blank) and puts pictures or links into it no longer stops the whole browser with an "insert volume about" requester; such addresses are resolved against the page, as in other browsers. - JavaScript: array methods (push, map, filter, join...) work on reactive arrays such as those of Vue 3 applications; they used to return empty or wrong results. - JavaScript: Promise.withResolvers() and Promise.try(), URL.canParse() and URL.parse(); new URL() rejects an address that is not a URL, and event.eventPhase reports the real phase of an event. - itch.io downloads now start in time on a 68020 with JIT as well: the page no longer fetches its background picture again at every layout check, and JavaScript timers keep running while the window is inactive. - JavaScript runs faster: function calls, variable access and simple arithmetic are roughly 10-30% quicker on a 68040, and canvas drawing (charts, games) is several times faster. - Layout closer to other browsers: !important inside style="", takes its image from the matching , width/height attributes only on elements that allow them, , , chained child selectors (.a>.b>.c) and tag-qualified ancestors (header.x .y), auto margins of grid and flex items, wrapping flex rows (Bootstrap columns), fixed elements inside transformed ones, rem sizes set by a later stylesheet, container units (cqw) and percentages inside calc(). - SVG text: a font-size attribute is honoured, and text lengths measured by scripts match other browsers. - JavaScript: mouse events carry the same fields as in other browsers (pointer events, coordinates), and mouse movement over a frame reaches the scripts of that frame. - JavaScript: a form submitted by a script uses its own method (POST), history.replaceState() changes the page address, canvas measureText() gives fractional widths, and objects used as property keys, permission queries and many smaller details behave as in other browsers. - JavaScript: error objects, built-in constructors (Map, Promise, typed arrays need "new"), Element/HTMLElement/HTMLDocument/CSSStyleDeclaration prototypes and the order of onclick-style handlers versus addEventListener now match other browsers; Uint8Array() called without "new" no longer crashes the engine. - JavaScript: every frame has its own DOM prototypes and constructors; event, screen and element properties live on their interface prototypes as in other browsers; a frame's window size follows its (width/height and style); document.styleSheets lists the rules of
) was cut short, and its later lines were drawn over the top of the page. - Frames () run their own scripts and talk to the page with postMessage, as security checks and embedded widgets need. - YouTube: the cookie consent window fits the screen, its text scrolls to the end and its buttons show their labels. - YouTube: the cookie consent choice is saved, search results appear, and the YouTube logo and channel pictures show. - Pictures that a page's own scripts add or change are loaded now, with the load events pages wait for (thumbnails on YouTube and on many modern sites stayed empty before). - Fixed: a symbol such as a bullet could turn into odd characters where a page lets long words break anywhere. - JavaScript: text built piece by piece in a loop (s += x) is much faster, and very long results no longer come out cut short. - JavaScript: regular expressions match repeats longer than 511 characters (long addresses and texts failed to match before). - JavaScript: new Image() and new Audio() create real elements; images that scripts create report complete only once loaded. - Fixed: a script copying a promise, Map or similar built-in object (as YouTube does) could crash the browser a while later. - JavaScript: IntersectionObserver behaves as in other browsers, so pages no longer load their own slower replacement for it. - YouTube: the cookie consent window has its white background (its text was drawn straight over the page). - Fixed: a style sheet that a script adds to a page with no style sheet of its own had no effect. - YouTube: icons show (logo, menu, buttons, list markers) - scripts now see the contents of SVG pictures, and arcs in SVG paths are drawn as real curves. - Fixed: an element hidden with an invalid opacity value (as YouTube sets it) stays visible, as in other browsers. - A scrolling box inside a window that stays in place (position: fixed, as in most dialogs) now scrolls its content, not just its scrollbar. - Clicks reach boxes that a page positions freely (absolute, fixed) also right after the page has changed them. - Layout: percentage heights inside CSS grids, icons mirrored with scale, var()var() written without a space. - JavaScript: many fixes to text with non-English letters, number formatting, Intl, element scroll positions, getBoundingClientRect inside scrolled boxes, and custom elements (the building blocks of YouTube and similar sites). - JavaScript: localStorage and sessionStorage accept the short form (localStorage.key = value, localStorage.key) and list stored keys; MessageChannel messages arrive without timer delay, so pages built with React respond faster; constants really are constant; Proxy objects work with for-in, JSON and property descriptors; Object.keys() of built-in objects and of the window lists the same as in other browsers; SVG text elements report character positions. - Layout: text set in fractional font sizes (16.5px) gets its proper line height; percentage table columns are measured from the table width; flex carousels wider than 32767 pixels are laid out correctly; a closed stays closed even when a style sheet sets display on its content; text is laid out like in other browsers (on one line, not scrolling). - Style: flex-basis with calc(), grid rows in fr units inside a grid of automatic height (including collapsed 0fr accordions), and width or max-width written with min(), max() or clamp() and one or more percentages (Elementor background videos no longer shrink to nothing). - Style: !important now also wins for widths and heights in percent, calc() or auto, and for percentage padding and max-width; several selector forms (".item:last-child:after", a class written after :not(), long sibling names, "!important" rules with two ancestors) apply exactly where they should; getComputedStyle() answers for every property. - Style: rules meant for forced colors, high contrast, inverted colors or HDR screens no longer apply on an ordinary screen (GitHub links were drawn in the wrong colour). - Scrolling: pages whose content scrolls inside the body while the page itself does not (Google News) can be scrolled with the main scrollbar, wheel and keys. - Frames show the content their own scripts build; frames created inside other frames and frames loaded from blob: addresses work. - JavaScript: lists such as querySelectorAll(), children, childNodes, form.elements and attributes are proper NodeList, HTMLCollection and NamedNodeMap objects with item(), namedItem() and forEach(); classList, URLSearchParams, FormData and Headers can be looped over (YouTube). - JavaScript: Math.sin, cos, tan, atan2, cbrt, log2 and their relatives give exactly the results other browsers give (sin of very large numbers and even of Math.PI came out different before). - JavaScript: Date.now() and performance.now() tick in fractions of a millisecond and agree with each other. - JavaScript: many smaller additions so pages see a standard browser: CSS.supports(), screen and window sizes from the real screen, performance.memory, location and history as proper objects, element types reported correctly, and requests to other sites send only the site name as referrer, as other browsers do. - A page that builds an empty frame (about:blank) and puts pictures or links into it no longer stops the whole browser with an "insert volume about" requester; such addresses are resolved against the page, as in other browsers. - JavaScript: array methods (push, map, filter, join...) work on reactive arrays such as those of Vue 3 applications; they used to return empty or wrong results. - JavaScript: Promise.withResolvers() and Promise.try(), URL.canParse() and URL.parse(); new URL() rejects an address that is not a URL, and event.eventPhase reports the real phase of an event. - itch.io downloads now start in time on a 68020 with JIT as well: the page no longer fetches its background picture again at every layout check, and JavaScript timers keep running while the window is inactive. - JavaScript runs faster: function calls, variable access and simple arithmetic are roughly 10-30% quicker on a 68040, and canvas drawing (charts, games) is several times faster. - Layout closer to other browsers: !important inside style="", takes its image from the matching , width/height attributes only on elements that allow them, , , chained child selectors (.a>.b>.c) and tag-qualified ancestors (header.x .y), auto margins of grid and flex items, wrapping flex rows (Bootstrap columns), fixed elements inside transformed ones, rem sizes set by a later stylesheet, container units (cqw) and percentages inside calc(). - SVG text: a font-size attribute is honoured, and text lengths measured by scripts match other browsers. - JavaScript: mouse events carry the same fields as in other browsers (pointer events, coordinates), and mouse movement over a frame reaches the scripts of that frame. - JavaScript: a form submitted by a script uses its own method (POST), history.replaceState() changes the page address, canvas measureText() gives fractional widths, and objects used as property keys, permission queries and many smaller details behave as in other browsers. - JavaScript: error objects, built-in constructors (Map, Promise, typed arrays need "new"), Element/HTMLElement/HTMLDocument/CSSStyleDeclaration prototypes and the order of onclick-style handlers versus addEventListener now match other browsers; Uint8Array() called without "new" no longer crashes the engine. - JavaScript: every frame has its own DOM prototypes and constructors; event, screen and element properties live on their interface prototypes as in other browsers; a frame's window size follows its (width/height and style); document.styleSheets lists the rules of