Review of Web Application Manifest Format and Management APIs

Hi Anant,  
Here is a quick review of the "Web Application Manifest Format and Management APIs" proposal.  


On Saturday, 12 May 2012 at 20:37, Marcos Caceres wrote:

>  
> Web Application Manifest Format and Management APIs
>  
>  
> Abstract
>  
> This document specifies a JSON based format to describe installable web applications. In addition, a set of JavaScript APIs are described that allow web content to trigger installation of such applications, as well as manage them on behalf of the user.
>  
>  
> 1. App Manifest
>  
> An application manifest is a JSON file describing an installable web application.
Should be:
An application manifest is a [HTTP] resource served with the <a ...>app-mainfest content type</a>.

It is recommended that the manifest be encoded as UTF-8.
> This JSON file consists of a top-level object and several properties.



Should be:
The manifest consists of…

Probably best not to speak of "files" as these are coming from the server (and might be completely auto generated).  

> 1.2 Properties
>  
> Mandatory Properties
>  
> name: The name of the web application in the default locale. Maximum length is 128 characters.
It's not clear why would this be limited to 128 characters? Also, what happens if the size is exceeded?
> description: A short description of the web application in the default locale. Maximum length is 1024 characters.



As above.

> default_locale: [Mandatory only if "locales" property is set]. The locale of the top-level name and description.


Why not just take the first locale encountered?

> Optional Properties
>  
> launch_path: The path within the web application's origin that is loaded when the application is launched
What happens if the "path" redirects? Are HTTP responses honoured?
> icons: A map of icon sizes to URIs of the icons (which may be absolute or data URIs).


Why not just use HTML's icons?  
> Icons must be square.


Why? and what if they are not square? Seems like a fairly platform specific restriction?
> developer: Information about the developer of the application, suitable for display.
> name: The name of the developer.
> url: A URL pointing to the developer's website
> locales: A map of locale specific overrides of data contained in the manifest. Each locale key is keyed on a locale tag [RFC4646], and contains a sparse representation of the manifest.


I think you mean a "Language-Tag"? What happens if it's not a language tag? What happens if it's a "*"?  
> Any field in the locales property will override the corresponding property in the manifest. The locales, installs_allowed_from, and default_locale CANNOT be overridden.


By the author or by the runtime?
> If the locales property is set, the default_locale must also be set.


What happens if it's not set? What happens if only locale data is set?
> installs_allowed_from: An array of origins that are allowed to trigger installation of this application. This field allows the developer to restrict installation of their application to specific sites. If the value is omitted, installs are allowed from any site.


How are origins parsed?  
> version: A string that represents the version of this manifest. The User-Agent does not interpret this value in any way and is opqaue to everyone


Typo: opqaue > opaque  
> but the application itself. The field is provided to help the developer deal with various update cases, which will be discussed in following sections.


This was not discussed.  
> screen_size: This object may contain the min_height and min_width properties that describe the minimum height and width (in pixels) the application needs in order to render correctly. Interpretation of these values is left up to the runtime and/or app store.



How does this play with CSS and media queries in particular? What's the use case?
> required_features: This array consists of a set of values that describes the mandatory features the application needs in order to run correctly. A full list of valid values is TBD.


Interested to see what could be listed here… this is the area of greatest interop concern, IMO (hopefully it won't be needed at all, as it's only really useful on extension/proprietary platforms).
> orientation: This value defines the orientation at which the application will initially start. Can be one of "portrait", "landscape", "portrait-secondary" or "landscape-secondary".


Could this be handled on a "per page" basis using CSS device adaption?
http://dev.w3.org/csswg/css-device-adapt/#the-lsquoorientationrsquo-descriptor

> The options suffixed with "-secondary" imply a 180 degree rotation from the options without the suffix, for instance, holding the phone upside down (but still in a manner where width < height), implies the "portrait-secondary" orientation. If this field had a valid value, the runtime will not change the orientation of the view rendering the application even if the device is turned.
> fullscreen: This value is set to "true" or "false" to describe whether the runtime should launch the application in fullscreen mode.


There also a relationship here to CSS View Mode Media Feature:
http://www.w3.org/TR/view-mode/
> 1.3 Serving Manifests
>  
> An application manifest must be served from the same origin that the application itself is served from.
What happens if it is not?
> There must only be one application per origin.


what if there are more?

(Note that you are mixing conformance requirements for authors and UAs… please avoid that or make it clear who you are aiming your conformance requirements at… putting authoring requirements into specs are not idea, IMO; better do describe what they user agent is supposed to do)
> When served as a static file, it is recommended that the manifest be stored with the extension .webapp. The manifest must be served with a Content-Type header of application/x-web-app-manifest+json.


The above is a statement of fact. It is a web-app manifest. (hope people won't get confused with Appcache manifest…)
> It is recommended that manifests be served over SSL.


>  
> 2. Application Records
>  
> Applications are represented by a JavaScript object that is accessible to web content.
>  
> interface AppObject {
> readonly attribute DOMString origin;


What's the use case? isn't this just "window.location.origin"?
> readonly attribute Object manifest;


> readonly attribute DOMString installOrigin;
> readonly attribute unsigned long installTime;



What's the use case?
> readonly attribute Object parameters;
> EventTarget launch ();
> EventTarget uninstall ();



EventTarget is usually used as an abstract class… so this should really be:
AppObject : EventTarget{
void launch();
void unistall();  
[TreatNonCallableAsNull] attribute Function? oninstall;
[TreatNonCallableAsNull] attribute Function? onuninstall;

}

> };
> Attributes
>  
> installOrigin of type DOMString, readonly
> The origin of the page from which the application was installed.
> installTime of type unsigned long, readonly
> Time in milliseconds since epoch at which the application was installed.


Can this be useful to launch an attack ("oh, I see you have the old unpatched version…. muahahah!")? What would a developer do with this info?
> manifest of type Object, readonly
> A JavaScript object as returned by JSON.parse invoked on the manifest.


What happens if this results in an error?
> origin of type DOMString, readonly
> The origin of the application, represented by a FQDN.


please expand the abbreviation.
> parameters of type Object, readonly
> Parameters that were provided at install time.



Not sure where these parameters came from? Where they URL params?
> Methods
>  
> launch
> Launches this application (behaviour is runtime dependent).


Bit confused… isn't the application already running? Or is this whole API exposed in some other execution context (e.g., some kind of application control page)?
> No parameters.
> Return type: EventTarget
> uninstall
> Uninstalls this application. This call is available to privileged callers only.
> No parameters.
> Return type: EventTarget
>  
> 3. Application Registry
>  
> A privileged caller is a web page that has been explicitely authorized by the user to manage applications on their behalf. Such privileged origins also have access to the AppRegistry interface as described below.
>  
> interface AppRegistry : Navigator {
> EventTarget install (DOMString manifestUrl, [Optional] Object parameters);
> EventTarget getSelf ();
> EventTarget getInstalled ();


As above.
> attribute EventListener oninstall;
> attribute EventListener onuninstall;


For the above two, I think you probably want:
[TreatNonCallableAsNull] attribute Function? xxxx

(note that Function may change)

> };
> Attributes
>  
> oninstall of type EventListener
> This value may be set to a function that will be invoked when an application is installed. The only argument to this function will be the AppObject of the application that was installed. This attribute can be set by priveleged callers only.


you should specify this as a WebIDL callback…

callback SomeNameCB = void (AppObject appObj);

> onuninstall of type EventListener
> This value may be set to a function that will be invoked when an application is uninstalled. The only argument to this function be the AppObject of the application that was uninstalled. This attribute can be set by privileged callers only.


as above:
[TreatNonCallableAsNull] attribute SomeNameCB? uninstall


> Methods
>  
> getInstalled
> Retrives application records for all applications that have been installed so far. This call is available to privileged callers only.




What's a privileged caller? Also, if this is a getter, then it should be an attribute. Only use getXXX() for async getters.
> No parameters.
> Return type: EventTarget
> getSelf
> Retrieves the application record for the origin from which the call is made.


As above. This should just be an attribute called "self". Still not sure what this is though? or what it is used for?

> No parameters.
> Return type: EventTarget
> install
> Triggers the installation of an application as specified by the manifest at manifestUrl. The User-Agent must fetch the manifest from the provided URL, verify that it is valid, and then ask for permission from the user to allow installation to proceed.


The rules for verifying the validity and what to do when it is not valid are not defined.
> The User-Agent must also persist the parameters provided (if any) which may later be retrived from the AppObject representing this application.

These are URL parameters?

> The user may choose to whitelist certain origins to allow them to install applications without any permission prompts.
> Parameter Type Nullable Optional Description
> manifestUrl DOMString ✘ ✘
> parameters Object ✘ ✘
> Return type: EventTarget
> Application Events
>  
> Most of the methods described above return an EventTarget object to which success and error handlers may be attached using standard DOM methods like addEventListener or attributes like onsuccess and onerror.
This pattern seems weird. Or maybe I'm not getting it. Example would be great here.

> interface AppEventError {
> const unsigned short PERMISSION_DENIED = 1;
> const unsigned short MANIFEST_URL_ERROR = 2;
> const unsigned short NETWORK_ERROR = 3;
> const unsigned short MANIFEST_PARSE_ERROR = 4;
> const unsigned short INVALID_MANIFEST = 5;


WebIDL says not to do the above:
http://www.w3.org/TR/WebIDL/#idl-constants
> readonly attribute short code;
> };


Maybe just use a DOMError from DOM4 or DOMException?
> Attributes
>  
> code of type short, readonly
> This value is set to one of the constants defined in this interface.
> Constants
>  
> INVALID_MANIFEST of type unsigned short
> The manifest was able to be parsed but contains invalid values.
> MANIFEST_PARSE_ERROR of type unsigned short
> The manifest could not be parsed.
> MANIFEST_URL_ERROR of type unsigned short
> The manifest could not be found at the given location.
> NETWORK_ERROR of type unsigned short
> The manifest could not fetched from the given location at this time.
> PERMISSION_DENIED of type unsigned short
> Installation was denied (by user or UA).



> interface AppEventTarget : EventTarget {
> attribute EventListener onsuccess;
> attribute EventListener onerror;



See other example I gave… should be defined as a callback… though this whole AppEventTarget thing seems strange.
> void addEventListener (DOMString event, EventListener e);
> void removeEventListener (DOMString event, EventListener e);
> readonly attribute Object result;
> };

I would be better if this followed a more standard programming pattern found in other Web platform interfaces.
> Attributes
>  
> onerror of type EventListener
> May be set to an error handler.
> onsuccess of type EventListener
> May be set to a success handler.
> result of type Object, readonly
> The type and value of result depends on the operation for which this EventTarget was returned. If an onerror is fired, this value will be set to AppEventError. When getSelf() and getInstalled() succeed, ths value will be set to an array of AppObjects.

instead of returning "object", see WebIDL union types:

http://www.w3.org/TR/WebIDL/#idl-union


Hope that helps,
Marcos  



--  
Marcos Caceres
http://datadriven.com.au

Received on Saturday, 12 May 2012 23:33:19 UTC