Chromium offers two ways for an end-user to view the source code of a web page: 1) the Developer Tools, and 2) The longstanding
view-source viewer. Of these, the Developer Tools have received almost all of the attention over the last decade, but in this post I want to take a quick look at the older
To get to the View Page Source feature, you can use the the
Ctrl+U keyboard shortcut, the View page source context menu item, or add
view-source: prefix before a URL in the omnibox. No matter what mechanism you use, you’ll get a new tab containing a simple view of the original source code of the page, not the current document’s DOM (which may have been extensively modified by script or the user).
Over the years, I’ve landed a few fixes to the View-Source code, including security fixes and user-experience fixes (e.g. support for rendering Dark Mode). The feature doesn’t get a lot of love, but its implementation is interesting. Why?
First, let’s start with the URL. Chromium uses a
BrowserURLHandler to rewrite all URLs with a
view-source: prefix by stripping off the prefix; a VirtualUrl is set on the navigation entry so the user continues to see the
view-source prefix in the omnibox, even as the renderer uses the inner url as the source location:
If the user tries to use
view-source against an unsupported scheme like
If the user invokes View page source on a given document, the WebContents’
ViewSource() function takes the current document’s URL, slaps a
view-source: prefix on the front, massages a few things, and opens the resulting URL in a new tab.
Most interestingly, View Source is implemented as a mode for a Document loaded inside Blink– you simply call
SetIsViewSource(true) on the Document, and then the ComputeDocumentType sets things up such that the
CreateDocument() function creates a
HTMLViewSourceDocument instead of a plain
HTMLDocument. The ViewSource document uses a simpler parser and it does not do much beyond adding markup to display basic color highlighting on HTML elements and their attributes. The resulting “source-formatted” HTML is displayed as text to the user.
Generally, products try not to expose multiple features to achieve the same task, especially when they use different code to do it. For a while, the View-Source viewer had some unique features that justified its existence; e.g. it integrated with the XSS Auditor to mark blocks of code that the Auditor had deemed reflected XSS attacks:
However, the XSS Auditor was removed more than two years ago. Similarly, many years ago, a site could link directly to a
view-source URL (e.g. a HTML tutorial website might do this), but that capability was removed in 2016 for security reasons.
Nowadays, the viewer offers a subset of the features of the Developer Tools’
Sources tab. The
Sources tab offers several cool features, including Pretty Print, red-underlines for script errors, and the ability to switch between all of the sources used by the currently loaded page:
Elements tab is different than both the
Sources tab and the
At this point, you might naturally wonder why the old viewer still exists.
Part of the answer is “Well, it’s been there forever, and doesn’t cost too much to maintain.” It’s been proposed that perhaps the
CTRL+U shortcut should just open the Developer Tools’
Sources tab. However, there are some non-obvious reasons that the old viewer continues to live on:
- For Chromium on Android1, adding the
view-sourceprefix in the omnibox is the only convenient way to view source without first tethering your device to a DevTools instance running on a desktop PC.
HTMLViewSourceDocumentcode that makes up the bulk of the feature cannot be deleted because the default XML rendering view depends upon it.
If the user navigates to an XML file that lacks an XSLT, the XML parser calls
GetDocument()->SetIsViewSource(true);which results in the browser rendering the plain XML as a document tree:
May the Source be with you!
1 Unfortunately, Chromium on iOS doesn’t support either
view-source or the Developer Tools. If the iOS browser syncs a
view-source url from another platform, the prefix is simply stripped off.