--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/battery/Overview.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,433 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Battery Status API</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
+ <script src='http://respec.specifiction.com/js/profiles/w3c-common.js' class='remove'></script>
+ <script class="remove">
+ var respecConfig = {
+ specStatus: "ED",
+ shortName: "battery-status",
+ //publishDate: "2011-11-29",
+ previousPublishDate: "2011-11-29",
+ previousMaturity: "LC",
+ edDraftURI: "http://dvcs.w3.org/hg/dap/raw-file/tip/battery/Overview.html",
+ lcEnd: "2011-12-20",
+ editors: [
+ { name: "Anssi Kostiainen", company: "Nokia", companyURL: "http://nokia.com/" },
+ { name: "Mounir Lamouri", company: "Mozilla", companyURL: "http://mozilla.org/" }
+ ],
+ inlineCSS: true,
+ noIDLIn: true,
+ extraCSS: ["../ReSpec.js/css/respec.css"],
+ wg: "Device APIs Working Group",
+ wgURI: "http://www.w3.org/2009/dap/",
+ wgPublicList: "public-device-apis",
+ wgPatentURI: "http://www.w3.org/2004/01/pp-impl/43696/status",
+ };
+ </script>
+ </head>
+ <body>
+ <section id="abstract">
+ This specification defines an API that provides information about the
+ battery status of the hosting device.
+ </section>
+
+ <section id="sotd">
+ <p>
+ The functionality described in this specification was initially
+ specified as part of the
+ <a href="http://www.w3.org/TR/system-info-api/">System Information
+ API</a> but has been extracted in order to be more readily available,
+ more straightforward to implement, and in order to produce a
+ specification that could be implemented on its own merits without
+ interference with other, often unrelated, features.
+ </p>
+ </section>
+
+ <section class="informative">
+ <h2>Introduction</h2>
+ <p>
+ The Battery Status API specification defines a means for web
+ developers to programmatically determine the battery status of the
+ hosting device. Without knowing the battery status of a device, a web
+ developer must design the web application with an assumption of
+ sufficient battery level for the task at hand. This means the battery
+ of a device may exhaust faster than desired because web developers are
+ unable to make decisions based on the battery status. Given knowledge
+ of the battery status, web developers are able to craft web content and
+ applications which are power-efficient, thereby leading to improved
+ user experience.
+ </p>
+ <p>
+ The Battery Status API can be used to defer or scale back work when
+ the device is not charging in or is low on battery. An archetype of an
+ advanced web application, a web-based email client, may check the
+ server for new email every few seconds if the device is charging,
+ but do so less frequently if the device is not charging or is low on
+ battery. Another example is a web-based word processor which could
+ monitor the battery level and save changes before the battery runs
+ out to prevent data loss.
+ </p>
+ <p>
+ The following example shows how a web-based email client could check
+ for new emails every ten seconds without knowledge of the battery
+ status:
+ </p>
+ <pre class="example highlight">
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>Email Client</title>
+ <script>
+ var mail = {
+ INTERVAL_DEFAULT: 1000 * 10,
+ interval: null,
+ timer: 0,
+
+ check: function () {
+ console.log('Checking the server for new emails using an interval of ' +
+ (mail.interval / 1000) + ' seconds.');
+ },
+
+ setTimer: function (interval) {
+ if (interval === mail.interval) { return; }
+ if (mail.timer !== 0) { clearTimeout(mail.timer); }
+ if (interval) { mail.timer = setInterval(function () { mail.check(); }, interval); }
+ mail.interval = interval;
+ }
+ };
+
+ window.addEventListener('load', function () {
+ mail.setTimer(!mail.interval ? mail.INTERVAL_DEFAULT : mail.interval);
+ }, false);
+ </script>
+ </head>
+ <body></body>
+ </html>
+
+ </pre>
+ <p>
+ The script will always check for emails every ten seconds, even if the
+ battery level is critically low and the device is not charging.
+ This is an example of poor resource management.
+ </p>
+ <p>
+ Using the <a>BatteryManager</a> interface, the web application is, for
+ example, able to throttle checking for emails if the device is low on
+ battery, stop checking for emails if the battery is critically low and
+ resume normal operation when the battery is charging:
+ </p>
+ <pre class="example highlight">
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>Battery-aware Email Client</title>
+ <script>
+ var mail = {
+ INTERVAL_BATTERY_LOW: 1000 * 60 * 10,
+ INTERVAL_DEFAULT: 1000 * 10,
+ interval: null,
+ timer: 0,
+
+ check: function () {
+ console.log('Checking the server for new emails using an interval of ' +
+ (mail.interval / 1000) + ' seconds.');
+ },
+
+ setTimer: function (interval) {
+ if (interval === mail.interval) { return; }
+ if (mail.timer !== 0) { clearTimeout(mail.timer); }
+ if (interval) { mail.timer = setInterval(function () { mail.check(); }, interval); }
+ mail.interval = interval;
+ }
+ };
+
+ window.addEventListener('load', function () {
+ mail.setTimer(!mail.interval ? mail.INTERVAL_DEFAULT : mail.interval);
+ }, false);
+
+ var battery = navigator.battery;
+
+ battery.addEventListener('dischargingtimechange', function () {
+ if (battery.dischargingTime < 60 * 30 || battery.level < 0.1) {
+ mail.setTimer(mail.INTERVAL_BATTERY_LOW);
+ console.log('30 minutes remaining or level below 10%, checking the server less frequently.');
+ } else if (battery.dischargingTime < 60 * 10 || battery.level < 0.05) {
+ mail.setTimer(null);
+ console.log('10 minutes remaining or level below 5%, stop checking the server.');
+ }
+ }, false);
+
+ battery.addEventListener('chargingchange', function () {
+ if (battery.charging) {
+ mail.setTimer(mail.INTERVAL_DEFAULT);
+ console.log('Battery is charging, checking the server normally.');
+ }
+ }, false);
+ </script>
+ </head>
+ <body></body>
+ </html>
+ </pre>
+ </section>
+
+ <section id="conformance">
+ <p>
+ This specification defines conformance criteria that apply to a single
+ product: the <dfn>user agent</dfn> that implements the
+ interfaces that it contains.
+ </p>
+ <p>
+ Implementations that use ECMAScript to implement the APIs defined in
+ this specification must implement them in a manner consistent with the
+ ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]],
+ as this specification uses that specification and terminology.
+ </p>
+ </section>
+ <section>
+ <h2>Terminology</h2>
+ <p>
+ The <code><a href="http://dev.w3.org/html5/spec/webappapis.html#function">
+ Function</a></code> interface represents a function in the scripting
+ language being used as defined in [[!HTML5]].
+ </p>
+ <p>
+ The concepts <dfn><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">
+ queue a task</a></dfn> and
+ <dfn><a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">
+ fires a simple event</a></dfn> are defined in [[!HTML5]].
+ </p>
+ <p>
+ The terms <dfn> <a href="http://dev.w3.org/html5/spec/webappapis.html#event-handlers">
+ event handlers</a></dfn> and
+ <dfn><a href="http://dev.w3.org/html5/spec/webappapis.html#event-handler-event-type">
+ event handler event types</a></dfn> are defined in [[!HTML5]].
+ </p>
+ </section>
+ <section>
+ <h2>Security and privacy considerations</h2>
+ <p>
+ The API defined in this specification is used to determine the battery
+ status of the hosting device. The information disclosed has minimal
+ impact on privacy or fingerprinting, and therefore is exposed without
+ permission grants. For example, authors cannot directly know if there
+ is a battery or not in the hosting device.
+ </p>
+ </section>
+ <section>
+ <h2><a>NavigatorBattery</a> Interface</h2>
+ <p>
+ The <a>NavigatorBattery</a> interface is exposed on the
+ <code>Navigator</code> object.
+ </p>
+ <div class="idl" title="Navigator implements NavigatorBattery"></div>
+ <dl title="[NoInterfaceObject] interface NavigatorBattery" class="idl">
+ <dt>readonly attribute BatteryManager battery</dt>
+ <dd>
+ The object that exposes the battery status information.
+ </dd>
+ </dl>
+ </section>
+
+ <section>
+ <h2><a>BatteryManager</a> Interface</h2>
+ <dl title="[NoInterfaceObject]
+ interface BatteryManager : EventTarget"
+ class="idl">
+ <dt>readonly attribute boolean charging</dt>
+ <dd>
+ Represents if the system's battery is charging. The attribute MUST be
+ set to false if the battery is discharging, and set to true, if the
+ battery is charging, the implementation is unable to report the
+ state, or there is no battery attached to the system, or otherwise.
+ </dd>
+ <dt>readonly attribute double chargingTime</dt>
+ <dd>
+ Represents the time remaining in seconds until the system's battery
+ is fully charged. The attribute MUST be set to 0, if the battery is
+ full or there is no battery attached to the system, and to the value
+ positive Infinity if the battery is discharging, the implementation
+ is unable to report the remaining charging time, or otherwise.
+ </dd>
+ <dt>readonly attribute double dischargingTime</dt>
+ <dd>
+ Represents the time remaining in seconds until the system's battery
+ is completely discharged and the system is about to be suspended. The
+ attribute MUST be set to the value positive Infinity, if the battery
+ is charging, the implementation is unable to report the remaining
+ discharging time, there is no battery attached to the system, or
+ otherwise.
+ </dd>
+ <dt>readonly attribute double level</dt>
+ <dd>
+ Represents the current battery level scaled from 0 to 1.0. The
+ attribute MUST be set to 0 if the system's battery is depleted and
+ the system is about to be suspended, and to 1.0 if the battery is
+ full, the implementation is unable to report the battery's level,
+ or there is no battery attached to the system.
+ </dd>
+ <dt>[TreatNonCallableAsNull] attribute Function? onchargingchange</dt>
+ <dd>
+ </dd>
+ <dt>[TreatNonCallableAsNull] attribute Function? onchargingtimechange</dt>
+ <dd>
+ </dd>
+ <dt>[TreatNonCallableAsNull] attribute Function? ondischargingtimechange</dt>
+ <dd>
+ </dd>
+ <dt>[TreatNonCallableAsNull] attribute Function? onlevelchange</dt>
+ <dd>
+ </dd>
+ </dl>
+ <p>
+ When a <code>BatteryManager</code> object is created,
+ <code>charging</code> MUST be set to true, <code>chargingTime</code>
+ to 0, <code>level</code> to 1.0 and <code>dischargingTime</code> to
+ the value positive Infinity, if the implementation is unable to report
+ the battery's charging state, charging time, level or remaining time
+ respectively.
+ </p>
+ <p>
+ When the battery charging state is updated, the <a>user agent</a> MUST
+ <a>queue a task</a> which sets the <code>charging</code> attribute's
+ value and <a>fires a simple event</a> named <code>chargingchange</code>
+ at the <a>BatteryManager</a> object.
+ </p>
+ <p>
+ When the battery charging time is updated, the <a>user agent</a> MUST
+ <a>queue a task</a> which sets the <code>chargingTime</code>
+ attribute's value and <a>fires a simple event</a> named
+ <code>chargingtimechange</code> at the <a>BatteryManager</a> object.
+ </p>
+ <p>
+ When the battery discharging time is updated, the <a>user agent</a>
+ MUST <a>queue a task</a> which sets the <code> dischargingTime</code>
+ attribute's value and <a>fires a simple event </a> named
+ <code>dischargingtimechange</code> at the <a>BatteryManager</a> object.
+ </p>
+ <p>
+ When the battery level is updated, the <a>user agent</a> MUST
+ <a>queue a task</a> which sets the <code> level</code> attribute's
+ value and <a>fires a simple event</a> named <code>levelchange</code>
+ at the <a>BatteryManager</a> object.
+ </p>
+ <div class="note">
+ The definition of how often the <code>chargingtimechange</code>,
+ <code>dischargingtimechange</code>, and <code>levelchange</code> events
+ are fired is left to the implementation.
+ </div>
+ <section>
+ <h2>Event handlers</h2>
+ <p>
+ The following are the <a>event handlers</a> (and their corresponding
+ <a>event handler event types</a>) that MUST be supported as
+ attributes by the <a>BatteryManager</a> object:
+ </p>
+ <table class="simple">
+ <thead>
+ <tr>
+ <th>event handler</th>
+ <th>event handler event type</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong><code>onchargingchange</code></strong></td>
+ <td><code>chargingchange</code></td>
+ </tr>
+ <tr>
+ <td><strong><code>onchargingtimechange</code></strong></td>
+ <td><code>chargingtimechange</code></td>
+ </tr>
+ <tr>
+ <td><strong><code>ondischargingchange</code></strong></td>
+ <td><code>dischargingchange</code></td>
+ </tr>
+ <tr>
+ <td><strong><code>onlevelchange</code></strong></td>
+ <td><code>levelchange</code></td>
+ </tr>
+ </tbody>
+ </table>
+ </section>
+ </section>
+
+ <section class="informative">
+ <h2>Examples</h2>
+ <p>
+ This trivial example writes the battery level to the console each time
+ the level changes:
+ </p>
+ <div class="example">
+ <pre class="example highlight">
+ navigator.battery.onlevelchange = function () {
+ console.log(navigator.battery.level);
+ };
+ </pre>
+ </div>
+ <p>
+ Alternatively, the same using the <code>addEventListener()</code>
+ method:
+ </p>
+ <div class="example">
+ <pre class="example highlight">
+ navigator.battery.addEventListener('levelchange', function () {
+ console.log(navigator.battery.level);
+ }, false);
+ </pre>
+ </div>
+ <p>
+ The following example updates the indicators to show the charging
+ state, level and time remaining in minutes:
+ </p>
+ <div class="example">
+ <pre class="example highlight">
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>Battery Status API Example</title>
+ <script>
+ var battery = navigator.battery;
+
+ battery.onchargingchange = function () {
+ document.querySelector('#charging').textContent = battery.charging ? 'charging' : 'not charging';
+ };
+
+ battery.onlevelchange = function () {
+ document.querySelector('#level').textContent = battery.level;
+ };
+
+ battery.ondischargingtimechange = function () {
+ document.querySelector('#dischargingTime').textContent = battery.dischargingTime / 60;
+ };
+ </script>
+ </head>
+ <body>
+ <div id="charging">(charging state unknown)</div>
+ <div id="level">(battery level unknown)</div>
+ <div id="dischargingTime">(discharging time unknown)</div>
+ </body>
+ </html>
+ </pre>
+ </div>
+ </section>
+ <section class="appendix">
+ <h2>Acknowledgements</h2>
+ <p>
+ The group is deeply indebted to Mounir Lamouri, Jonas Sicking, and
+ the Mozilla WebAPI team in general for their invaluable feedback
+ based on prototype implementations. Many thanks to the people behind
+ the System Information API and Device Orientation Event specification
+ for the initial inspiration. Also thanks to the nice folks bringing us
+ the Page Visibility specification, which motivated the editor of this
+ specification to write the introduction chapter discussing some
+ real-world high value use cases that apply equally to this
+ specification. Special thanks to all the participants of the Device
+ APIs Working Group and others who have sent in substantial feedback
+ and comments, and made the Web a better place for everyone by
+ doing so.
+ </p>
+ </section>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/battery/index.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Battery Status API</title>
+ </head>
+ <body>
+ Moved to <a href="http://dvcs.w3.org/hg/dap/raw-file/tip/battery/Overview.html">
+ http://dvcs.w3.org/hg/dap/raw-file/tip/battery/Overview.html</a>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/network-api/index.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,307 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>The Network Information API</title>
+ <meta http-equiv='Content-Type' content='text/html;charset=utf-8' />
+
+<!--
+ <script src='../ReSpec.js/js/respec.js' class='remove'></script>
+-->
+ <script src='http://respec.specifiction.com/js/profiles/w3c-common.js' class='remove'></script>
+ <script class='remove'>
+ var respecConfig = {
+ specStatus: "ED",
+ shortName: "netinfo-api",
+
+ //publishDate: "2012-12-12",
+ previousPublishDate: "2011-06-07",
+ previousMaturity: "ED",
+ edDraftURI: "TBD",
+
+ // if this is a LCWD, uncomment and set the end of its review period
+ // lcEnd: "2009-08-05",
+ extraCSS: ["../ReSpec.js/css/respec.css"],
+ noIDLIn: true,
+
+ editors: [
+ { name: "Mounir Lamouri",
+ company: "Mozilla",
+ companyURL: "http://mozilla.org/" },
+ ],
+ wg: "Device APIs and Policy Working Group",
+ wgURI: "http://www.w3.org/2009/dap/",
+ wgPublicList: "public-device-apis",
+ wgPatentURI: "http://www.w3.org/2004/01/pp-impl/43696/status"
+ };
+ </script>
+ </head>
+
+ <body>
+ <section id='abstract'>
+ The Network Information API provides an interface for web applications to
+ access the underlying connection information of the device.
+ </section>
+
+ <section id='sotd'>
+ <p>
+ The functionality described in this specification was initially specified as part of the
+ <a href='http://www.w3.org/TR/system-info-api/'>System Information API</a> but has been
+ extracted in order to be more readily available, more straightforward to implement, and
+ in order to produce a specification that could be implemented on its own merits without
+ interference with other, often unrelated, features.
+ </p>
+ </section>
+
+ <section class="informative">
+ <h2>Introduction</h2>
+ <p>
+ The Network Information API provides an interface enabling web applications to access the underlying
+ connection information of the device.
+ </p>
+ <p>
+ The following example shows how an image viewer can select a low definition or a high definition image based on the
+ current connection bandwidth:
+ <pre class="example highlight">
+ <!DOCTYPE>
+ <html>
+ <head>
+ <title>Poney viewer</title>
+ </head>
+ <body>
+ <img id='poney' alt="An image showing a poney" title="My precious!">
+ <script>
+ var i = document.getElementById('poney');
+
+ if (navigator.connection.bandwidth > 2) {
+ i.src = "http://example.com/poney_hd.png";
+ } else {
+ i.src = "http://example.com/poney_ld.png";
+ }
+ </script>
+ </body>
+ </html>
+ </pre>
+ </section>
+
+ <section id='conformance'>
+ <p>
+ This specification defines conformance criteria that apply to a single product: the <dfn>user agent</dfn> that
+ implements the interfaces that it contains.
+ </p>
+ <p>
+ Implementations that use ECMAScript to expose the APIs defined in this specification must implement them in a manner
+ consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]].
+ </p>
+ </section>
+
+ <section>
+ <h2>Terminology</h2>
+ <p>
+ The <code><a href="http://dev.w3.org/html5/spec/webappapis.html#function">
+ Function</a></code> interface represents a function in the scripting
+ language being used as defined in [[!HTML5]].
+ </p>
+ <p>
+ The concepts <dfn><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">
+ queue a task</a></dfn> and
+ <dfn><a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">
+ fire a simple event</a></dfn> are defined in [[!HTML5]].
+ </p>
+
+ <p>
+ The terms <dfn> <a href="http://dev.w3.org/html5/spec/webappapis.html#event-handlers">
+ event handlers</a></dfn> and
+ <dfn><a href="http://dev.w3.org/html5/spec/webappapis.html#event-handler-event-type">
+ event handler event types</a></dfn> are defined in [[!HTML5]].
+ </p>
+
+ <p>
+ The concepts of <dfn><a href="http://dev.w3.org/html5/spec/browsers.html#browsing-context">
+ browsing context</a></dfn> and
+ <dfn><a href="http://dev.w3.org/html5/spec/browsers.html#active-document">
+ active document</a></dfn> are defined in [[!HTML5]].
+ </p>
+
+ <p>
+ The concept of document <dfn><a href="http://dev.w3.org/html5/spec/origin-0.html#the-document-s-domain">
+ domain</a></dfn> is defined in [[!HTML5]].
+ </p>
+ </section>
+
+ <section>
+ <h2>Security and privacy considerations</h2>
+ <p>
+ The API defined in this specification is used to determine the connection information
+ of the hosting device. The information disclosed has minimal
+ impact on privacy or fingerprinting, and therefore is exposed without
+ permission grants. For example, authors cannot directly know what kind of connection
+ is actually in use by the hosting device.
+ </p>
+ </section>
+
+ <section>
+ <h2>The <a>NetworkInformation</a> interface</h2>
+ <p>
+ The <a>NetworkInformation</a> interface is exposed on the
+ <code>Navigator</code> object.
+ </p>
+ <div class='idl' title='Navigator implements NetworkInformation'></div>
+ <dl title='[NoInterfaceObject] interface NetworkInformation' class='idl'>
+ <dt>readonly attribute Connection connection</dt>
+ <dd>
+ The object from which connection information is accessed.
+ </dd>
+ </dl>
+ </section>
+
+ <section>
+ <h2>The <a>Connection</a> interface</h2>
+ <p>
+ The <a>Connection</a> interface provides a handle to the device's connection information.
+ </p>
+ <dl title='[NoInterfaceObject]
+ interface Connection : EventTarget' class='idl'>
+ <dt>readonly attribute double bandwidth</dt>
+ <dd>
+ The <a>user agent</a> MUST set the value of the <code>bandwidth</code> attribute to:
+ <ul>
+ <li>0 if the user is currently offline;</li>
+ <li>Infinity if the bandwidth is unknown;</li>
+ <li>an estimation of the current bandwidth in MB/s (Megabytes per seconds) available for communication with the
+ <a>browsing context</a> <a>active document</a>'s <a>domain</a>.
+ </li>
+ </ul>
+ </dd>
+ <dt>readonly attribute boolean metered</dt>
+ <dd>
+ <p>
+ A connection is <dfn>metered</dfn> when the user's connection is subject to a limitation from his Internet Service Provider
+ strong enough to request web applications to be careful with the bandwidth usage.
+ </p>
+ <div class="note">
+ What is a metered connection is voluntarily left to the <a>user agent</a> to judge. It would not be possible to give an exhaustive
+ list of limitations considered strong enough to flag the connection as metered and even if doable, some limitations can be
+ considered strong or weak depending on the context.<br>
+ Examples of metered connections are mobile connections with a small bandwidth quota or connections with a pay-per use plan.
+ </div>
+ <p>
+ The <a>user agent</a> MUST set the value of the <code>metered</code> attribute to true if the connection with the
+ <a>browsing context</a> <a>active document</a>'s <a>domain</a> is <a title='metered'>metered</a> and false otherwise.
+ If the implementation is not able to know the status of the connection or if the user is offline, the value MUST be set to false.
+ </p>
+ <div class="note">
+ If unnable to know if a connection is metered, a <a>user agent</a> could ask the user about the status of his current connection.
+ For example, a preference could let the user define if the mobile connection used on the device is metered.
+ </div>
+ </dd>
+ <dt>[TreatNonCallableAsNull] attribute Function? onchange</dt>
+ <dd></dd>
+ </dl>
+
+ <p>
+ When the <code>Connection</code> changes, the <a>user agent</a> MUST <a>queue a task</a> which updates
+ the <code>Connection</code> properties and <a>fire a simple event</a> named <code>change</code> at the
+ <code>Connection</code> object.
+ </p>
+
+ <p>
+ When the user goes online or offline, in addition to the <code>change</code> event fired on the <code>Connection</code>
+ object, the <a>user agent</a> has to <a>fire a simple event</a> named either <code>online</code> or <code>offline</code>
+ depending on the applicable value, as defined in [[!HTML5]].
+ </p>
+
+ <section>
+ <h2>Event handlers</h2>
+ <p>
+ The following are the <a>event handlers</a> (and their corresponding
+ <a>event handler event types</a>) that MUST be supported as
+ attributes by the <code>Connection</code> object:
+ </p>
+
+ <table class="simple">
+ <thead>
+ <tr>
+ <th>event handler</th>
+ <th>event handler event type</th>
+ </tr>
+ </thead>
+ <tbody>
+
+ <tr>
+ <td><strong><code>onchange</code></strong></td>
+ <td><code>change</code></td>
+ </tr>
+ </tbody>
+ </table>
+ </section>
+ </section>
+
+ <section class='informative'>
+ <h2>Examples</h2>
+ <p>
+ This trivial example writes the connection bandwidth to the console and shows it again each time it is changing:
+ </p>
+ <div class="example">
+ <pre class="example highlight">
+ function show() {
+ console.log(navigator.connection.bandwidth);
+ }
+
+ navigator.connection.addEventListener('change', show, false);
+
+ show();
+ </pre>
+ </div>
+
+ <p>
+ This example shows how an application can prevent automatic polling using the metered attribute:
+ </p>
+ <div class="example">
+ <pre class="example highlight">
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>Conditional polling</title>
+ <script>
+ var gPreviousMetered = navigator.connection.metered;
+ var gIntervalId;
+
+ function poll() {
+ // poll stuff
+ }
+
+ navigator.connection.addEventListener('change', function() {
+ if (gPreviousMetered == navigator.connection.metered) {
+ return;
+ }
+
+ gPreviousMetered = navigator.connection.metered;
+ if (navigator.connection.metered) {
+ gIntervalId = setInterval(poll, 1000);
+ } else {
+ clearInterval(gIntervalId);
+ }
+ }, false);
+
+ // At load time.
+ if (!navigator.connection.metered) {
+ gIntervalId = setInterval(poll, 1000);
+ }
+ </script>
+ </head>
+ <body>
+ <button onclick="poll();">Poll</button>
+ </body>
+ </html>
+ </pre>
+ </div>
+ </section>
+
+ <section class='appendix'>
+ <h2>Acknowledgements</h2>
+ <p>
+ Special thanks to Robin Berjon for his help.
+ </p>
+ </section>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/TODO.txt Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,29 @@
+
+TESTS:
+ ✓ API presence
+ ✓ silent ignore (requires a device that does not support vibration)
+ ✓ simple value
+ ✓ array of values
+ ✓ array with extra parameter (even array)
+ ✓ cancel with 0
+ ✓ cancel with []
+ ✓ cancel with new vibration
+ - do nothing when hidden
+ - cancel when dynamically hidden
+ - reinstate when dynamically shown
+
+
+NOTES:
+• Test using vendor prefix as in
+ http://dvcs.w3.org/hg/webperf/file/25712d0f6bd5/tests/submission/Microsoft/PageVisibility/support/featuredetection.js
+
+• Testing transitions as in
+http://dvcs.w3.org/hg/webperf/file/25712d0f6bd5/tests/submission/Microsoft/PageVisibility/test_tab_switch.htm
+
+• When the visibilitychange event [PAGE-VISIBILITY] is dispatched at the Document, the user agent must run the following steps
+ - If the hidden attribute [PAGE-VISIBILITY] is set to true, the user agent must
+ suppress the vibration produced by running the pre-existing instance of the processing
+ vibration patterns algorithm, if any.
+ - If the hidden attribute [PAGE-VISIBILITY] is set to false, the user agent must
+ restore the vibration produced by running the pre-existing instance of the
+ processing vibration patterns algorithm, if any.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/api-is-present.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: test that the vibrate() method is present (with or without vendor prefix)</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom'/>
+ <meta name='assert' content='Check that the vibrate() method is present.'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ This test checks for the presence of the <code>vibrate()</code> method, taking
+ vendor prefixes into account.
+ </p>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script>
+ test(function () {
+ assert_true(undefined !== BrowserHasFeature(navigator, "vibrate"), "navigator.vibrate exists");
+ }, "vibrate() is present on navigator");
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/cancel-with-0.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: cancel ongoing vibrate() with 0</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <meta name='assert' content='If pattern is 0, cancel the pre-existing instance of the processing vibration patterns algorithm'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate for a short period of time (roughly one
+ second). If it vibrates for a longer time (roughly five seconds, it should feel somewhat long) then
+ the test has failed.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate(5000);
+ setTimeout(function () {
+ navigator.vibrate(0);
+ }, 1000);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/cancel-with-[].html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: cancel ongoing vibrate() with []</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <meta name='assert' content='If pattern is an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate for a short period of time (roughly one
+ second). If it vibrates for a longer time (roughly five seconds, it should feel somewhat long) then
+ the test has failed.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate(5000);
+ setTimeout(function () {
+ navigator.vibrate([]);
+ }, 1000);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/cancel-with-new.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: cancel ongoing vibrate() with a new call to vibrate</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <meta name='assert' content='Cancel the pre-existing instance of the processing vibration patterns algorithm, if any.'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate continuously for a short period of time (roughly one
+ second), then vibrate a series of short bursts. If the initial continuously vibration is longer (roughly five
+ seconds, it should feel somewhat long) or if there is no series of short vibration bursts then the test has
+ failed.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate(5000);
+ setTimeout(function () {
+ navigator.vibrate([200, 200, 200, 200, 200, 200, 200, 200, 200]);
+ }, 1000);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/manifest.txt Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,9 @@
+api-is-present.html Vibration API: test that the vibrate() method is present (with or without vendor prefix) vendor-prefix, dom http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com> Check that the vibrate() method is present.
+cancel-with-0.html Vibration API: cancel ongoing vibrate() with 0 vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com> If pattern is 0, cancel the pre-existing instance of the processing vibration patterns algorithm
+cancel-with-[].html Vibration API: cancel ongoing vibrate() with [] vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com> If pattern is an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm
+cancel-with-new.html Vibration API: cancel ongoing vibrate() with a new call to vibrate vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com> Cancel the pre-existing instance of the processing vibration patterns algorithm, if any.
+pattern-array-extra.html Vibration API: test a pattern array parameter to vibrate() with an extra (even) item vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com> If the length of pattern is even, then remove the last entry in pattern.
+pattern-array.html Vibration API: test a pattern array parameter to vibrate() vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com>
+silent-ignore.html Vibration API: test that calls to vibrate() are silently ignored when the device cannot vibrate vendor-prefix, dom, no-vibrator http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com> If the device does not provide a vibration mechanism, or it is disabled, the user agent must silently ignore any invocations of the vibrate() method.
+simple-array.html Vibration API: test a simple array parameter to vibrate() vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com>
+simple-scalar.html Vibration API: test a simple scalar parameter to vibrate() vendor-prefix, dom, interact http://www.w3.org/TR/vibration/#methods Robin Berjon <mailto:robin@berjon.com>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/pattern-array-extra.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: test a pattern array parameter to vibrate() with an extra (even) item</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <meta name='assert' content='If the length of pattern is even, then remove the last entry in pattern.'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate three times for one second, separated
+ by one second intervals.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate([1000, 1000, 1000, 1000, 1000, 1000]);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/pattern-array.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: test a pattern array parameter to vibrate()</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate three times for one second, separated
+ by one second intervals.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate([1000, 1000, 1000, 1000, 1000]);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/silent-ignore.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: test that calls to vibrate() are silently ignored when the device cannot vibrate</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, no-vibrator'/>
+ <meta name='assert' content='If the device does not provide a vibration mechanism, or it is disabled, the user agent must silently ignore any invocations of the vibrate() method.'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ <strong>This test is only useful on devices that do not have vibration capability</strong>.
+ If your device supports vibration, then <strong>skip</strong> this test. An implementation
+ supporting this API but running on a device that cannot vibrate must silently ignore the
+ call (we test that it doesn't throw).
+ </p>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ test(function () {
+ var ok = false;
+ try {
+ navigator.vibrate(1000);
+ ok = true;
+ }
+ catch (e) {
+ ok = false;
+ }
+ assert_true(ok, "vibrate() should not throw");
+ }, "Calling vibrate does not throw.");
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/simple-array.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: test a simple array parameter to vibrate()</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate continuously for about two seconds, once.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate([2000]);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/submissions/robin/simple-scalar.html Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Vibration API: test a simple scalar parameter to vibrate()</title>
+ <link rel='author' title='Robin Berjon' href='mailto:robin@berjon.com'/>
+ <link rel='help' href='http://www.w3.org/TR/vibration/#methods'/>
+ <meta name='flags' content='vendor-prefix, dom, interact'/>
+ <!--
+ When you review this test, please add
+ <link rel='reviewer' title='Your Name' href='mailto:your-email-address'/>
+ -->
+ <link rel='stylesheet' href='http://w3c-test.org/resources/testharness.css' media='all'/>
+ </head>
+ <body>
+ <h1>Description</h1>
+ <p>
+ After hitting the button below, your device must vibrate continuously for about two seconds, once.
+ </p>
+ <button id='vib'>Vibrate!</button>
+ <div id='log'></div>
+ <script src='http://w3c-test.org/resources/testharness.js'></script>
+ <!-- When this test gets approved, remove a "../" below -->
+ <script src='../../support/feature-detection.js'></script>
+ <script src='../../support/helpers.js'></script>
+ <script>
+ if (supportsVibration()) {
+ document.getElementById("vib").onclick = function () {
+ navigator.vibrate(2000);
+ };
+ }
+ </script>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/support/feature-detection.js Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,94 @@
+
+// 2012-01-27
+// The code below has been stolen from Microsoft's submission tests to the Page Visibility
+// specification. Thanks!
+
+
+// This function returns the value of an API feature if it is defined with one of
+// the known ventor prefixes.
+//
+// Parameters:
+// parent: the object containing the API feature
+// feature: the name of the API feature, this should be a string value
+// isAttribute: set this to true to indicate that this is a constant attribute
+// as opposed to a variable
+function BrowserHasFeature(parent, feature, isAttribute)
+{
+ if (parent[feature] !== undefined)
+ {
+ //feature is defined without a vendor prefix, no further checks necessary
+ return parent[feature];
+ }
+
+ // the feature is not defined without a vendor prefix, so find the vendor prefix, if any,
+ // that it is defined with
+ var prefix = GetVendorPrefix(parent, feature, isAttribute);
+
+ // if prefix is not undefined, then the feature has been found to exist with this prefix
+ if (prefix !== undefined)
+ {
+ var prefixedFeatureName = AppendPrefix(prefix, feature, isAttribute);
+ return parent[prefixedFeatureName];
+ }
+
+ //The feature does not exist.
+ //Callers should check for !==undefined as the feature itself could return
+ //a Bool which would fail a typical if(feature) check
+ return undefined;
+}
+
+// This function returns the vendor prefix found if a certain feature is defined with it.
+// It takes the same parameters at BrowserHasFeature().
+function GetVendorPrefix(parent, feature, isAttribute)
+{
+ //Known vendor prefixes
+ var VendorPrefixes = ["moz", "ms", "o", "webkit"];
+ for (vendor in VendorPrefixes)
+ {
+ //Build up the new feature name with the vendor prefix
+ var prefixedFeatureName = AppendPrefix(VendorPrefixes[vendor], feature, isAttribute);
+ if (parent[prefixedFeatureName] !== undefined)
+ {
+ //Vendor prefix version exists, return a pointer to the feature
+ return VendorPrefixes[vendor];
+ }
+ }
+
+ // if no version of the feature with a vendor prefix has been found, return undefined
+ return undefined;
+}
+
+// This will properly capitalize the feature name and then return the feature name preceded
+// with the provided vendor prefix. If the prefix given is undefined, this function will
+// return the feature name given as is. The output of this function should not be used
+// as an indicator of whether or not a feature exists as it will return the same thing if
+// the inputted feature is undefined or is defined without a vendor prefix. It takes the
+// same parameters at BrowserHasFeature().
+function AppendPrefix(prefix, feature, isAttribute)
+{
+ if (prefix !== undefined)
+ {
+ if (isAttribute)
+ {
+ // if a certain feature is an attribute, then it follows a different naming standard
+ // where it must be completely capitalized and have words split with an underscore
+ return prefix.toUpperCase() + "_" + feature.toUpperCase();
+ }
+ else
+ {
+ //Vendor prefixing should follow the standard convention: vendorprefixFeature
+ //Note that the feature is capitalized after the vendor prefix
+ //Therefore if the feature is window.feature, the vendor prefix version is:
+ //window.[vp]Feature where vp is the vendor prefix:
+ //window.msFeature, window.webkitFeature, window.mozFeature, window.oFeature
+ var newFeature = feature[0].toUpperCase() + feature.substr(1, feature.length);
+
+ //Build up the new feature name with the vendor prefix
+ return prefix + newFeature;
+ }
+ }
+ else
+ {
+ return feature;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/vibration/support/helpers.js Wed Feb 08 13:02:42 2012 -0800
@@ -0,0 +1,13 @@
+
+function supportsVibration () {
+ if (undefined !== BrowserHasFeature(navigator, "vibrate")) {
+ return true;
+ }
+ else {
+ test(function () {
+ assert_true(false, "Vibration API not found");
+ }, "Your user agent does not support the Vibration API.");
+ return false;
+ }
+}
+