A port of Tim Berners-Lee's original WorldWideWeb web browser from the early 1990s to modern macOS.
Important
This project is in its early stages and, while it does compile and even render basic web pages, there are still a number of features that don't work. Additionally, many of the parsing routines are not safe against untrusted inputs e.g. triggering buffer overflows, so don't log into your bank account with this.
That said, anyone interested is highly encouraged to explore the codebase and hack on it though.
Open WorldWideWeb.xcodeproj
in Xcode, then build and run the WorldWideWeb target.
This should open a browser window displaying the welcome page. To follow a link, double-click it, but be warned: Some of these links point to the internet (info.cern.ch) and while pages served via IPv4 and HTTP/1.1 should work, note that especially more modern pages often cannot be parsed properly.
You can also open a local page via the menu bar (Document
> Open file...
) or by pressing Cmd + O. For an example that the browser can parse, try one of the HTML files from this repo, e.g. Documentation/SourceFiles.html
.
This port is mainly motivated by academic curiosity, specifically learning about the implementation of the first web browser (how HTML rendering works etc.) and the history of the NeXTStep API. The goal is to eventually have a working Cocoa application that stays faithful to the original code and design while adopting modern conventions where they make sense1. This is not a small goal and may even be infeasible given the complexity of the project and potential need to replace or reimplement removed APIs.
While the original NeXTStep API and modern AppKit still share substantial similarities, many things have changed over the last 30 years. The most noticeable difference is perhaps the NS
prefix, which replaced the older NX
prefix. More subtle changes exist too, specifically classes like NSParagraphStyle
or NSText
, which are more encapsulated than back in the NeXTStep days. Although good from a software design standpoint, these differences unfortunately complicate the migration, because much of the original rendering engine (see e.g. the HyperText
class) relies on these internals of NeXTStep's Text
and related classes.
Fortunately, NSTextView
, NSTextStorage
and NSAttributedString
, the classes taking on these responsibilities in modern Cocoa, still map surprisingly well to the NeXTStep API on a conceptual level. Additionally, Cocoa's attributed strings handle many things under the hood that previously had to be done manually, such as merging attribute ranges.
For more information, see issue #2.
Another major hurdle to overcome is the legacy Interface Builder NIB format. This format has changed a few times over the years, from the original NXTypedStream
(see this Python reimplementation) to the modern XML-based XIB format. While Xcode is capable of reading older versions of the XML-based format, the WorldWideWeb.nib
turned out to be too old even for versions of Project Builder, the predecessor of Xcode. Our approach here is to use a custom Python script to convert the legacy NIB to a modern XIB.
More information on this can be found in issue #1.
- https://www.w3.org/People/Berners-Lee/WorldWideWeb.html
- https://worldwideweb.cern.ch/code/
- https://en.wikipedia.org/wiki/WorldWideWeb
This Cocoa port uses a standard Xcode project (WorldWideWeb.xcodeproj
). The source code can be found under WorldWideWeb
and a few helper scripts (e.g. for the NIB-to-XIB conversion) under Scripts
.
A few files that are not really used anymore, but kept around out of historical interest and for reference purposes can be found in the Legacy
folder. This includes the original Makefiles, Project Builder projects and the legacy NIB that we generate the modern XIB from.
Footnotes
-
A specific example of this is the menu bar. On NeXTStep, the main menu (i.e. the root of the menu hierarchy) was displayed as a single menu, while on macOS the "main menu" is actually the menu bar. This subtility results in slightly different conventions, e.g. on macOS it would be very uncommon for the menu bar to contain a menu item that directly represents an action such as "Print" or "Quit" and not a submenu itself. We deal with this by moving the top-level actions into the application menu (i.e. "WorldWideWeb") during the conversion from NIB to XIB. More details and screenshots can be found in #1. ↩