A Proposal for Rich Interactive Content Hypertext (RICH)

Motivation

The Internet forums and blogs today mainly consist of static text and images. Although rich, interactive contents can be made with HTML5/CSS/JavaScript technologies, most Internet users do not possess related programming skills. Sites like Google Map, Facebook or Twitter let you embed their contents in an iframe, but it’s their contents, not yours.

The proposal for Rich Interactive Content Hypertext (RICH) attempts to bridge the gap: those who code may write “RICH players”, and everyone can create rich contents with the players.

NOTE: The idea had been described in our earlier article, Twincl: A New Attempt at “Rich Forum”. We decided to make it open, so more Internet users and websites may benefit from (and join!) the collaborative efforts.

Idea

The core idea is simple:

  1. A content creator describes a piece of rich content in plain text (a RICH snippet).
  2. A coder writes code hosted elsewhere (a RICH player) which can present the rich content in a sandboxed iframe.
  3. A RICH-enabled content platform (a RICH client, such as a blogging/publishing platform or an Internet forum) allows content creators to embed RICH snippets in the contents. The RICH client and the RICH player communicate with each other using window.postMessage.

1. RICH Snippets

A RICH snippet looks like this:

> name1=... name2=...        <== attributes for item 1
xx                           <== data block for item 1
yyy
...
zzzz

> name1=... name2=...        <== attributes for item 2
aaa                          <== data block for item 2
bbb

RICH Format

A RICH snippet is a piece of multi-line text. It consists of a single or multiple items, where each item consists of an attribute line and a data block.

  1. An attribute line starts with a greater-than symbol >, followed by zero or multiple name-value pairs, each preceded by a single space. An attribute line also ends the data block of the previous item, if any.
    • The format of a name-value pair is name=value (unquoted) or name="value" (quoted), preceded by an optional asterisk *. If an asterisk * is present, the attribute applies to every item of the snippet, otherwise it only applies to the current one.
    • The case-insensitive name consists of letters, digits, - or _, and must start with a letter.
    • An unquoted value consists of letters, digits, - or _. A quoted value consists of non-quote characters or escaped quote \".
  2. A data block consists of a single or multiple lines of plain text. Each line cannot start with a greater-than symbol >. The leading and trailing empty lines of a data block are ignored.

Let’s see some examples and demonstration.

Example #1: Simple quiz

simple-quiz RICH snippet is just, well, a simple quiz. It looks like this:

> answer="Alpha Centauri"
What is the closest star system to our Solar System?

> choice=2
Which planet is bigger than the others?
- Mars
- Earth
- Venus

The simple-quiz player is a tiny webpage (1.6KB compressed) hosted on Google Cloud Storage. Here is a live interactive quiz you can play with:

As you can see, with the simple-quiz RICH player, anyone can add quizzes to a post in a breeze!

Example #2: Tic-tac-toe

With the HTML5 canvas, graphics are made easy. Here is a tic-tac-toe RICH snippet:

oox
.x.
o..

You can play Tic-tac-toe in normal or fullscreen mode here:

The tic-tac-toe player itself is not very useful, but is a good demonstration of graphical RICH players and the client-player interaction. The player consists of two small files hosted on GitHub project pages. The source code is put on github.com/arthurtw/tic-tac-toe for your reference.

Example #3: Go game quiz

The last example we present here is a player for Go game quiz. We built it on top of Jan Prokop’s WGo.js library. The data format used by go-quiz player is Smart Game Format, a popular format to store Go game records.

Here is a live Go game quiz:

Give it a try if you know the Go game rules!

2. RICH Players

A RICH player is executed within a sandboxed iframe of a RICH client webpage. It communicates with the parent window using window.postMessage method. The compact window.RICH=window.RICH||{version:"1",origin:"*"...} script in the player code is a tiny messaging library.

Upon window.onload event, the player sends an init command to the parent, and shall receive a RICH snippet to render. There is also a screen command to set the iframe height or fullscreen mode. More commands may be added in the future.

To implement a RICH player, you need to a) include the RICH library, and b) invoke RICH.init().

a. Include the RICH Library

To include the RICH player messaging library, please paste these lines to your JavaScript code:

window.RICH=window.RICH||{version:"1",origin:"*",_c:0,init:function(cb){RICH.
send({command:"init"},cb)},send:function(m,cb){var id=m._id=++RICH._c; m._ver
=RICH.version;if(cb){var ln=function(m){var o=m.data;if(o&&o._id===id){r();cb
(o.data)}};var r=function(){window.removeEventListener("message",ln)};window.
addEventListener("message",ln);setTimeout(r,3e4)}window.parent.postMessage(m,
RICH.origin)}};

Or you can include this line in your HTML:

<script src="//storage.googleapis.com/twincl-rich/1/player.min.js"></script>

Here is the un-minified version for your reference: https://storage.googleapis.com/twincl-rich/1/player.js

b. Invoke RICH.init

Upon window.onload event, the player should invoke RICH.init with a callback function to receive a RICH snippet object to render:

RICH.init(function (result) {
  // Initialize and render
});

The result object contains the parsed RICH snippet to render. It has the following fields:

  • item - the first item in the snippet, which has these fields:
    • data - the item data defined in the data block (the text below the attribute line > ...)
    • other fields - the item attributes defined in the attribute line
  • items - all items in the snippet (an array); it can also be referenced by items.x, where x is the item’s label defined in its label attribute (i.e. > label=x ...)
  • lang - the lang attribute of the parent window’s html; use this for i18n support

Note that when specifying item attributes in the attribute line of the snippet, users may prepend an asterisk * to the attribute name to specify a global attribute. Global attributes apply to all items, e.g. > *global-attr=value1 local-attr="value 2" ....

RICH Messaging API

RICH.init(callback)

Send an init command to the parent window.

RICH.send(message, callback)

Send a message to the parent window. The message object must contain a command field to indicate the command type. The optional callback function will be called upon receiving response from the parent window. Its parameter is the received result object.

RICH Messaging Commands

"init"

The initialization command. The response contains the parsed RICH snippet object.

"ping"

The dummy ping command. The response contains no result object.

"screen"

The screen size command. The fields are:

  • command: "screen"
  • height: set the iframe’s height attribute
  • width: set the iframe’s width attribute
  • full: enter fullscreen mode
  • normal: exit fullscreen mode

Future enhancement

This proposal is just an initial version. It might be expanded further. For example, the player can also be an “editor” for the user to edit RICH content interactively, then it saves the content back to the client through the new "save" command.

RICH Player Development

The simple-quiz and tic-tac-toe players are good reference implementations. To develop a new RICH player on Twincl site, please refer to the player development guide for details. Other sites might have different development processes.

Additional notes:

  • window.localStorage can be used for state persistence/transfer across multiple rendering sessions of the same player.
  • The player should be lightweight and mobile-friendly, if possible.

RICH Player Registration

To execute a RICH player, you only need its URL. A centralized registry is not required. However, you may register your RICH player on twincl.com/rich/player, so Twincl users can use it and people can find it more easily.

Note: Twincl site is a RICH-enabled forum/blogging website. To join the site, just sign in using your Google or Facebook account.

3. RICH Clients

A RICH client, or a RICH-enabled content platform, should:

  • a) use a sandboxed iframe (sandbox="allow-scripts allow-same-origin") to execute the RICH player,
  • b) attach a message event listener to window, and
  • c) handle player commands ("init", "ping" and "screen") properly.

Here is a sample RICH client on GitHub for your reference:

https://arthurtw.github.io/rich-client/

It’s a small static webpage. You can adapt it for your content platform or website. In the future, it might turn into a formal JavaScript library.

Conclusion

There can be numerous new RICH players for different domains (music, finance, science, games, to name a few). For example, a coder who loves Rubik’s Cube may decide to write a Rubik’s Cube player, then all Rubik’s Cube enthusiasts can use the player to discuss Rubik’s Cube moves nicely. The best thing about a RICH player is once it’s written, all users can create great contents with the player on any RICH-enabled content platform.

If you like the idea, please help spread it and/or join the efforts for a nicer, more collaborative Internet!

0 comment Comment