[WebPlatform.org](http://WebPlatform.org) expressed the wish to incorporate
compatibility tables on the website, and provide the compatibility data through
an easy to use API. [testthewebforward.org](http://testthewebforward.org) is
organizing a similar effort to expose the data it's going to collect through
running the [Web Platform W3C test suites](https://github.com/w3c/web-platform-tests).
Standardizing on a data model will help sync both of these efforts and allow
sourcing data from multiple other sources that would adopt this data exchange model.
This document is a counter proposal to Ronald Mansveld's
[original proposal](http://ronaldmansveld.github.io/webplatform-browser-compat/).
Defining a data model is tricky because different data sources have vastly
different types of data. Some of this data is very much factual. For example,
User Agent with UA string `uas` gets a score of `X` out of `Y` running the
test suite `T` for spec `S` on date `t0`. Let's call this *raw data*. While this
data is pretty much non-controversial, it is also not very valuable to the
end-developer. Interpreting this data to conclude that User Agent `A` supports
feature `F` is where the real value lies. Let's call this *interpreted data*.
Ideally, we'd always be storing raw data. Unfortunately, that is not always
possible. The challenge therefore consists in devising data models and
transformation strategies which allow both raw and interpreted data to
co-exist and be used together.
Format
------
The data format is [[JSON]].
User Agent data models
----------------------
### Reference User Agent Parser
Precisely identifying User Agents is a tricky business as camouflaging their true
identity and impersonating others has been among User Agent's
[earliest survival techniques](http://webaim.org/blog/user-agent-string-history/).
Despite it's flaws, User Agent String parsing remains the best technique to
identify browsers for analytics or testing purposes.
Properly parsing a User Agent string is a dirty job and not one that could be
specified easily. With specifying a UA parsing algorithm out of the question, our
second best bet is to standardize on reference UA parser that fits our licensing requirements and doesn't tie us to one programming language:
[`ua-parser`](https://github.com/tobie/ua-parser), the open-source parser extracted
from the [Browserscope](http://www.browserscope.org/) project. It has
[liberal licensing](https://github.com/tobie/ua-parser#license) and is polyglot by
nature: the core of the parser is a
[list of regexes](https://github.com/tobie/ua-parser/blob/master/regexes.yaml) which
can be used to implement the parser in any language that supports regular expressions
and is able to consume [[YAML]] (disclaimer, the editor of this document is also `ua-parser`'s co-maintainer).
Currently, implementations exist in: C#, D, Go, Haskell, Java, JavaScript (node.js), Perl, PHP, Pig, Python, and Ruby.
### Incomplete Version Strings in UserAgentInfo and OperatingSystemInfo
How do we handle incomplete version strings?
Consider `uainfo`, an instance of UserAgentInfo. Its `family` attribute is `"Foo"`;
its `major` attribute, `"8"`; and its `minor` and `patch` attributes are both `null`. For
the sake of argument, imagine we represent this User Agent as the string "Foo 8".
Now consider `Feature` `f` which is determined to be supported by "Foo 8.1", but not by
"Foo 8.0". Do we consider it is supported by "Foo 8" or not?
### The `UserAgent` object
The UserAgentInfo, OperatingSystemInfo and DeviceInfo objects
are usually obtained programmatically by parsing a User Agent string using the
reference UA parser. However, these objects can also be manually authored.
In such cases, their `family`, `brand` and `model` attributes MUST be a possible
output value of the reference UA parser in order for the data set to be
interoperable. So for example, if the reference UA parser identifies
Internet Explorer's family as as `"IE"`, a manually authored UserAgentInfo
object which would identify it as `"MSIE"` would **not** conform.
A list of possible values for the UserAgentInfo, OperatingSystemInfo
and DeviceInfo `family`, `brand` and `model` attributes must be
reverse-engineered from the reference UA parser and maintained.
- DOMString? userAgentString
- The User Agent String.
- UserAgentInfo ua
- Details of the User Agent's family and version number
- OperatingSystemInfo os
- Details of the Operating System the User Agent is running on
- DeviceInfo device
- Details of the Device the User Agent is running on
{
"userAgentString": "Mozilla/5.0 (Linux; Android 4.1.1; SPH-L710 Build/JRO03L) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
"ua": {
"family": "Chrome Mobile",
"major": "18",
"minor": "0",
"patch": "1025"
},
"os": {
"family": "Android",
"major": "4",
"minor": "1",
"patch": "1",
"patchMinor": null
},
"device": {
"brand": "Samsung",
"family": "Galaxy",
"model": "S3"
}
}
### The UserAgentInfo object
If the value of the `family` attribute is `"Other"`, the value of the `major`, `minor` and `patch` attributes MUST be `null`.
If the value of the `major` attribute is `null`, the value of the `minor` and `patch` attributes MUST be `null`.
If the value of the `minor` attribute is `null`, the value of the `patch` attribute MUST be `null`.
- DOMString family = "Other"
- The name of the User Agent
- DOMString? major
- The version sequence's major number
- DOMString? minor
- The version sequence's minor number
- DOMString? patch
- The version sequence's patch number
### The OperatingSystemInfo object
If the value of the `family` attribute is `"Other"`, the value of the `major`, `minor`, `patch` and `minorPatch` attributes MUST be `null`.
If the value of the `major` attribute is `null`, the value of the `minor`, `patch` and `minorPatch` attributes MUST be `null`.
If the value of the `major` attribute is `null`, the value of the `minor`, `patch` and `minorPatch` attributes MUST be `null`.
If the value of the `minor` attribute is `null`, the value of the `patch` and `minorPatch` attributes MUST be `null`.
If the value of the `patch` attribute is `null`, the value of the `minorPatch` attribute MUST be `null`.
- DOMString family = "Other"
- The name of the Operating System
- DOMString? major
- The version sequence's major number
- DOMString? minor
- The version sequence's minor number
- DOMString? patch
- The version sequence's patch number
- DOMString? minorPatch
- The version sequence's minor patch number
### The DeviceInfo object
If the value of the `family` attribute is `"Other"`, the value of the `model` attribute MUST be `null`.
- DOMString? brand
- The device's brand
- DOMString family = "Other"
- The device's family
- DOMString? model
- The device's model
Features
--------
Features are an abstraction that map to specs, their sections or subsections.
### The Feature object
- DOMString url
- The link to this feature's related spec or spec section/subsection
- DOMString name
- The name of this feature
{
"url":"http://www.w3.org/TR/IndexedDB/",
"name":"IndexedDB"
}
{
"url":"http://www.w3.org/TR/html5/embedded-content-0.html#attr-iframe-seamless",
"name":"Seamless iframes"
}
### The SupportLevel Enum
- full
- The Feature is fully supported on that UserAgent
- partial
- The Feature is partially supported on that UserAgent
- none
- The Feature is not supported on that UserAgent
- polyfilled
- The Feature is only supported on that UserAgent when polyfilled
### The FeatureSupport object
- Feature feature
- The corresponding Feature object
- UserAgent userAgent
- The corresponding UserAgent object
- SupportLevel supportLevel
- The level of support for this `feature` on that `userAgent`.