Bravo is an experiment in explaining the Open Web Platform. It does this by defining the lowest-level set of interoperable APIs needed to describe the behavior of everything else.
Since Web Platform APIs are largely expressed in terms of JavaScript, and since JavaScript is the only interoperable turing-complete language which is part of the Web Platform, Bravo attempts to define a minimal set of JavaScript APIs necessary for bootstrapping the rest of the system.
These APIs, the process model, and other primitives developed along the way are being designed with an eye towards multiple independent implementations and eventual standardization. This isn't about exposing one browser's internals, but rather about identifying the smallest vocabulary of features which all browsers must implement in order to host web content today.
Suppose you want to know how to build, run, and contribute to the experimental codebase, eh? This initial experiment is bootstrapped on top of Chromium, so you'll need a compiler, a beefy box, an some free time.
7 Easy steps (that may take a long time):
- Grab a chromium checkout. Some find that the git submodule flow is faster, but any method should work.
cd src && git clone https://github.com/slightlyoff/bravo
git apply --check bravo/chromium.patch
# if clean, proceed, else ping for helpgit apply bravo/chromium.patch
git runhooks
orbuild/chromium_gyp
to include Bravo in the build- Build the Content Shell , e.g.
ninja -C out/Release content_shell
- Drive your freshly minted build to any bravo content you happen to have/find, e.g. on OS X:
out/Release/Content\ Shell.app/Contents/MacOS/Content\ Shell \ --enable-logging --v=1 \ http://example.com/test.bravo
Patches are only accepted from Chromium Contributors. If you're not yet a Chromium Contributor, please submit a CLA or CCLA and let us know about it with PR's.
Code health guidelines are straightforward: this is experimental, but to the greatest extent possible, we use Chromium style. When in doubt, ask.
Bravo, conceptually, is the lowest level of the web platform. To a web developer, that means that everything that's a "bravo API" is something that can't be reasonable self-hosted in JavaScript and which they shouldn't ever expect to be pluggable.
From an implementation perspective, bravo defines the interfaces to JavaScript for system-provided services. We are defining these APIs as we go and bootstrapping on top of the Pepper C API in the Chromium prototype.
Eventually all Bravo APIs (which should not resemble Pepper APIs) will be candidates for standardization. The runtime language -- JavaScript -- is already a web standard.
Libraries built on top of Bravo may implement other standards (such as HTML, DOM, etc.) or provide alternative forms which reduce legacy baggage.
To write Bravo content, it must be served with Content-Type: application/bravo
. The examples/
directory includes a .htaccess
file which shows how to enable this in Apache.
The simplest thing that can possibly invoke bravo is data:application/bravo,main(b){b.log('oh hai')}
.
All Bravo APIs are plumbed through the main
function of the script. Also, all bravo scripts run in strict mode by default.
Bravo, as a result of it's current patch-in mechanism for building with Chrome, isn't as tightly integrated as one might otherwise expect. It does integrate directly with the Content Shell application, but since integrating with Chrome would be a more audacious patch (and therefore more brittle), we've omitted it for now. Luckily you can still run Bravo content in full-blown Chrome if you launch it the right way.
To do this, first build Chrome (or use Canary). Make sure you have also built the content_shell
target (which will build and copy the right Bravo files to the right places). Next, start Chrome from the command line and pass in the ``--register-pepper-plugins="..."` flag. Here's how it might look on OS X:
out/Release/Chromium.app/Contents/MacOS/Chromium \ --register-pepper-plugins="out/Release/ppGoogleBravoPluginChrome.plugin/Contents/MacOS/ppGoogleBravoPluginChrome;application/bravo"
And on Linux (much terser):
out/Release/chromium \ --register-pepper-plugins="out/Release/plugins/libppGoogleBravoPluginChrome.so;application/bravo"
The simplest way to debug Bravo is to launch it via Chromium and attach GDB to to the plugin process. E.g., on OS X:
out/Debug/Chromium.app/Contents/MacOS/Chromium \ --ppapi-startup-dialog \ --no-sandbox \ --register-pepper-plugins="out/Debug/ppGoogleBravoPluginChrome.plugin/Contents/MacOS/ppGoogleBravoPluginChrome;application/bravo"
The --ppapi-startup-dialog
ensures that starting the plugin will send a message to stdout when navigating to Bravo content like:
[...:ERROR:child_process.cc(130)] Ppapi (29489) paused waiting for debugger to attach. Send SIGUSR1 to unpause.
From there, simply attach GDB to the PID listed in the message (in this case 29489) to continue. Huzzah.