This specification defines the widget URI scheme that is used to address resources inside an packaged/installed Web Application. It is intended to be used with applications running is a packaged container (e.g., a [[ZIP]] container, or a [[!WIDGETS]] package) or similar sand boxed local file system.

Introduction

Widget URIs are synthetic URIs that serve two purposes:

An example of a widget URIs is:

widget://c13c6f30-ce25-11e0-9572-0800200c9a66/index.html

Example of usage

Assuming the synthesized document's address [HTML] is widget://c13c6f30-ce25-11e0-9572-0800200c9a66/index.html#example.


<!doctype html>
<script>
//Example using HTML's Location object
var loc =  window.location; 
console.log(loc.protocol ===  "widget:"); //true 
console.log(loc.host     ===  "c13c6f30-ce25-11e0-9572-0800200c9a66"); //true 
console.log(loc.href     ===  "widget://c13c6f30-ce25-11e0-9572-0800200c9a66/index.html"); //true 
console.log(loc.origin   ===  "widget://c13c6f30-ce25-11e0-9572-0800200c9a66"); //true 
console.log(loc.pathname === "/index.html"); //true 
console.log(loc.hash     === "#example"); //true 
console.log(loc.port     === ""); //true

This example shows a widget URI being resolved in [[!HTML5]].


var img = document.createElement("img");

//the following setter triggers HTML's resolve algorithm 
img.src = "example.gif"; 

//and the expected output: 
console.log(img.src === "widget://c13c6f30-ce25-11e0-9572-0800200c9a66/example.gif") //true

//Append the image to the document
document.body.appendChild(img); 
</script>

This example shows a resource within a package being retrieved over [[XMLHTTPREQUEST]].


function process(data) {
 // process the resulting data 
}

function handler() {
 if(this.readyState == 4 && this.status == 200) {
		var text = this.responseText;
		var json = JSON.parse(text) 
		process(json); 	
 } else if (this.readyState == 4 && this.status != 200) {
      // fetched the wrong page or there was an error...
 }
}

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handler;
xhr.open("GET", "playlist.json");
xhr.send();

There is one class of products that can claim conformance to this specification: a user agent.

User agent

A user agent is an implementation an implementation of this specification that is able to synthesize widget URIs as well as dereference them.

Syntax of Widget URIs

A widget URI is an [[!URI]] that:

A widget URI reference is one that:

Synthesizing a widget URI

When synthesizing a widget URI, a user agent MUST are normalized the URI in accordance with chapter 5.3.2. "Syntax-Based Normalization" of [[!RFC3987]].

Authority Component

The authority is a unique string which can be heuristically generated upon demand such that the probability that two are alike is small, and which is hard to guess. The authority component is said to be opaque, meaning that the authority component has a syntax as defined by [[!RFC3987]] but that the authority component is devoid of semantics. 

We strongly is RECOMMENDED using a [UUID] as the as the value of the authority . 

Query Component

The query component, when present, contains data that complements the path component in identifying a resource within a package.

Dereferencing and retrieval

This section describes how a user agent is supposed to respond requests to retrieve resources from a widget URI. The purpose is to make responses "look and feel" as much as possible like regular HTTP requests.

To dereference a widget URI to a file in a widget package a user agent MUST apply the rules for dereferencing a widget URI.

The rules for dereferencing a widget URI are as follows:

  1. If the request is not a GET request, return a 501 Not Implemented response and terminate this algorithm.
  2. If the URI uses the scheme 'widget', but is not a valid widget URI, return a 400 Bad Request response and terminate this algorithm.
  3. If the URI uses the scheme 'widget', but the authority does not match the one assigned to this package, return a 403 Not Allowed response and terminate this algorithm (i.e., prevent inter-widget content access).
  4. If the user agent implements [[!Widgets]] (for the purpose of internationalization):
    1. Let potential-file be the result of running the rule for finding a file within a widget package using the path component as its parameter.
  5. Otherwise,
    1. Let path be the path to the file being sought by the user agent.
    2. Let potential-file be the result of attempting locate the file at path
  6. If potential-file is not found, return a 404 Not Found response.
  7. If retrieving potential-file results in a error (e.g., the file is corrupt), return a 500 Internal Server Error with an optional message describing the error in the response body.
  8. Let content-type be the result of applying the rule for identifying the media type of a file using potential-file as an argument.
  9. Return a 200 OK response, with the value of content-type as the Content-Type header, and with potential-file as the response body.

Acknowledgments

The following people were instrumental in producing this specification:

Art Barstow, Thomas Roessler, Larry Masinter, Marcin Hanclik, Mark Baker, and Jere Kapyaho.

URI vs IRI?

This section is non-normative.

Throughout this specification, wherever the term URI [[!URI]] is used, it can be replaced interchangeably with the term IRI [[!RFC3987]]. All widget URIs are IRIs, but the term URI is more common and was therefore preferred for readability.