Skip to content

Instantly share code, notes, and snippets.

@dglazkov
Last active August 29, 2015 13:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dglazkov/5398136596f15e472332 to your computer and use it in GitHub Desktop.
Save dglazkov/5398136596f15e472332 to your computer and use it in GitHub Desktop.
HTML as Custom Elements

Obsolete Now at https://github.com/dglazkov/html-as-custom-elements

#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 childrenChanged callback, which is enqueued whenever the list of element's children changes. There could be other callbacks as well.

##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 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 rest of the elements either require no additional behavior or are trivially implementable using Custom Element callbacks.

TODO: Keep refining elements and looking for special APIs.

##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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment