/html-as-custom-elements

HTML as Custom Elements

Primary LanguageCSSApache License 2.0Apache-2.0

#HTML as Custom Elements tl;dr: Custom Elements is a bedrock API. We should be able to build all HTML elements with it. ##Runtime Environment It's clear that we're running some sort of code in some special way. Handwaving, we suppose that we have a runtime environment that possesses the following qualities:

  1. There is a strong security boundary between user agent code and author code (writing UA code in C++ is today's solution)
  2. There is a set of lower-level APIs the user agent code needs to implement HTML elements

Digging into how each element is built, let's try to keep track of these lower-level APIs. Look for a special Bedrock section. ##Additional Callbacks To implement HTML elements effectively, Custom Elements may need an additional callbacks, like childrenChanged, which is enqueued whenever the list of element's children changes. We should start with using mutation observers and see how far we get.

##Callback Barriers In the current Custom Elements spec, there's a neat queues-based abstraction that ensures callbacks are invoked consistently and--more importantly--safely. This is accomplished by queueing the callbacks in carefully prescribed order, and then invoking them when we deem it safe.

If you squint and look at it just so, this abstraction looks like a key part of that security boundary I mentioned earlier: it's only necessary to employ for those custom elements whose callbacks we don't trust to always do right thing.

This means that we may have to turn this abstraction into an API that the platform can skip for HTML elements (thus making their callbacks truly synchronous) and use for the author-created ones.

##Who's on First? There is a notion of a browsing context in the HTML spec. It seems like a good candidate for a bedrock API, which should have some pluggable way to initialize Documents. For HTML Documents, this initialization will involve registering all HTML elements before instantiating an HTML Parser.

Bedrock:

  • Browsing context
  • HTML Parser

##What's pre-fetching? Traditionally, rendering engines were able to optimize their performance by looking ahead of the parser, picking out elements that fetch resources, and starting to fetch those resources early. Currently, this is something that's just hard-wired, but it seems valuable to have a more flexible way to inform pre-fetching machinery about attribute values of custom elements that represent resource.

Bedrock:

  • Pre-fetch API.

##The <script> Element The <script> element relies on synchronous callbacks to prepare a script. It will need a few APIs to do its work:

Bedrock:

##The <link> Element The <link> element is fairly straightforward. The attributeChanged, enteredView, and leftView provide all the necessary hooks.

Bedrock:

##The <style> Element The <style> element needs the childrenChanged callback and uses attributeChanged, enteredView, and leftView callbacks.

Bedrock:

  • Parse CSS text into a stylesheet
  • Add stylesheet to the style engine

##The <img>, <video>, and <audio> Elements Implementation of these elements is fairly trivial in terms of Custom Elements, but they invoke a few bedrock APIs.

Bedrock:

  • Some origin API and Policy to help deciding how/whether to load resources
  • Do a potentially CORS-enabled fetch of a resource
  • Some sort of task scheduling/prioritization API
  • A surface primitive, which renders pixels and knows how to size itself relative to the dimensions of the element (likely a style engine primitive)
  • Video engine that ships pixels for each frame to the surface primitive
  • Audio engine

##The <iframe>, <object>, and <canvas> Elements The Custom Element scaffolding is trivial for these elements.

Bedrock:

  • A surface primitive, which renders pixels and knows how to size itself relative to the dimensions of the element (likely a style engine primitive)
  • Some sort of streaming/buffering info API to inform UI.
  • A view into a browsing context primitive for an iframe?
  • Some way to instantiate an NPAPI/PPAPI object and ship pixels from it to the surface primitive

##The <input type="file"> Element Bedrock:

  • Access to file system
  • Privileged events to open file picker?

##Et al.

The detailed work on deconstructing each element is currently tracked in a spreadsheet.

##Where's Bedrock? Based on this exploration, the following bits of flintstone have emerged:

Browsing Context

  • Instantiates new documents in response to navigation requests
  • Holds documents in a history
  • Provides a way to create a View

View

  • A view is a thing that builds a box tree and turns it into pixels.
  • TODO: how to decouple this from DOM?

HTML Parser

Script Runner

  • Create and execute a script

Resource Fetcher

  • Do a potentially CORS-enabled fetch of a resource
  • Pre-fetch API.

Event Loop

  • Some sort of task scheduling/prioritization API
  • Some origin API and Policy to help deciding how/whether to load resources

CSS Parser

  • Parse CSS text into a stylesheet

Style Engine

  • Add stylesheet to a styleengine

Media Query Engine

  • Evaluate media query

Rendering Surface

  • Renders pixels and knows how to size itself relative to the dimensions of the element (likely a style engine primitive)

Video Player

  • Ships pixels for each frame to the surface primitive
  • Some sort of streaming/buffering info API to inform UI.

Audio Player

Installing and running tests

npm install
npm test
// or `npm run watch` to keep karma running in the background