Merge remote-tracking branch 'upstream/gh-pages' into gh-pages

# Conflicts:
#	web-bluetooth/index.html
This commit is contained in:
Jeff Posnick 2015-07-22 13:40:16 -04:00
Родитель ac8e6359aa 764e84088c
Коммит 5f74c32e30
27 изменённых файлов: 573 добавлений и 66 удалений

2
.travis.yml Normal file
Просмотреть файл

@ -0,0 +1,2 @@
language: ruby
script: "bundle exec jekyll build"

Просмотреть файл

@ -1,7 +1,11 @@
<script>
var ChromeSamples = {
log: function() {
document.querySelector('#log').textContent += Array.prototype.join.call(arguments, '') + '\n';
var line = Array.prototype.slice.call(arguments).map(function(argument) {
return typeof argument === 'string' ? argument : JSON.stringify(argument);
}).join(' ');
document.querySelector('#log').textContent += line + '\n';
},
setStatus: function(status) {

Просмотреть файл

@ -0,0 +1,112 @@
<!DOCTYPE html>
<!--
Copyright 2015 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<title>Web App Install Banner: Defer prompt</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/samples/styles/main.css">
<link rel="manifest" href="manifest.json">
</head>
<body>
<h1>Web App Install Banner: Defer prompt of banner sample</h1>
<p>Available in <a href="https://www.chromestatus.com/features/4540065577435136">Chrome 45+ (for Android)</a></p>
<p>The <a href="http://updates.html5rocks.com/2014/11/Support-for-installable-web-apps-with-webapp-manifest-in-chrome-38-for-Android">web app install banner</a> will prompt the user to add your web app to the users home screen.
It will only prompt when a number of criteria have been met:
</p>
<ul>
<li>The app uses a <a href="http://www.html5rocks.com/en/tutorials/service-worker/introduction/">service worker</a></li>
<li>The site is using HTTPS</li>
<li>The app has a manifest declared</li>
<li>The manifest has a <code>short_name</code>, 144 pixel icon and a type of 'image/png'</li>
</ul>
<p>Frequently developers want be able to control when the Add to homescreen prompt is shown to users.
This API and example shows you how you can defer the prompt until a later time, in this case when the
user clicks the button below. If the button below is disabled, Chrome has chosen now is not a good time to
show the prompt.</p>
<button id="btnSave" disabled>Click this to show the prompt</button>
<p>Below you will see the output of the example.</p>
<pre id=output></pre>
<p>For testing we encourage you to force the banner to appear by setting the chrome://flags/#bypass-app-banner-engagement-checks flag.</p>
<p>To see if this example works, come back in another day and you will see the banner.</p>
<script>
window.addEventListener('load', function() {
var outputElement = document.getElementById('output');
var btnSave = document.getElementById('btnSave');
var deferredPrompt;
navigator.serviceWorker.register('service-worker.js', { scope: './' })
.then(function(r) {
console.log('registered service worker');
})
.catch(function(whut) {
console.error('uh oh... ');
console.error(whut);
});
window.addEventListener('beforeinstallprompt', function(e) {
console.log('beforeinstallprompt Event fired');
e.preventDefault();
// Enable the button.
btnSave.removeAttribute('disabled');
// Stash the event so it can be triggered later.
deferredPrompt = e;
return false;
});
btnSave.addEventListener('click', function() {
if (deferredPrompt !== undefined) {
// The user has had a postive interaction with our app and Chrome
// has tried to prompt previously, so let's show the prompt.
deferredPrompt.prompt();
outputElement.textContent = 'Deferred Prompt shown';
// Follow what the user has selected.
deferredPrompt.userChoice.then(function(choiceResult) {
console.log(choiceResult.outcome);
if (choiceResult.outcome == 'dismissed') {
console.log('User cancelled homescreen install');
}
else {
console.log('User added to homescreen');
}
// We no longer need the prompt. Clear it up.
deferredPrompt = null;
});
}
});
});
</script>
</body>
</head>

Двоичные данные
app-install-banner/deferred-banner/launcher-icon-0-75x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
app-install-banner/deferred-banner/launcher-icon-1-5x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
app-install-banner/deferred-banner/launcher-icon-1x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Двоичные данные
app-install-banner/deferred-banner/launcher-icon-2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.5 KiB

Двоичные данные
app-install-banner/deferred-banner/launcher-icon-3x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.2 KiB

Двоичные данные
app-install-banner/deferred-banner/launcher-icon-4x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.9 KiB

Просмотреть файл

@ -0,0 +1,38 @@
{
"name": "App Install Deferred Banner Sample",
"short_name": "App Install Deferred Banner Sample",
"icons": [
{
"src": "launcher-icon-0-75x.png",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "launcher-icon-1x.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "launcher-icon-1-5x.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "launcher-icon-2x.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "launcher-icon-3x.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "launcher-icon-4x.png",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "./index.html",
"display": "standalone"
}

Просмотреть файл

@ -0,0 +1,13 @@
App Install Banner User Response Sample
===
See https://googlechrome.github.io/samples/app-install-banner/useraction-banner/index.html for a live demo.
#### Directions:
* Install Chrome, or another browser that supports Service Workers and manifest
* Visit the site over two separate days.
* Or, more usefully, enable chrome://flags/#bypass-app-banner-engagement-checks
On the second vist, you will see a message on the page that says the user either installed the app or dismissed the banner.

Просмотреть файл

@ -0,0 +1,6 @@
/*
This service worker doesn't actually do anything!
In the real world, you would add support for Offline or the ability to
handle push messages.
*/

Просмотреть файл

@ -42,6 +42,7 @@ limitations under the License.
<li><a href="basic-banner/index.html">Basic Banner Sample</a> - Minimum viable code.</li>
<li><a href="cancelable-banner/index.html">Cancelable Banner Sample</a> - Proactively stop the banner from showing.</li>
<li><a href="useraction-banner/index.html">User action Sample</a> - Understand if the user accepted or dismissed the banner.</li>
<li><a href="deferred-banner/index.html">Deferred prompt Sample</a> - Prompt the user at a developer defined time.</li>
</ul>
<p>Chrome also supports the ability to offer and streamline the install experience of Native Android applications, through the use of 'related_application' data in the manifest.</p>

5
arrows-es6/README.md Executable file
Просмотреть файл

@ -0,0 +1,5 @@
Arrow functions (ES6) Sample
===
See https://googlechrome.github.io/samples/arrows-es6/index.html for a live demo.
Learn more at https://www.chromestatus.com/feature/5047308127305728

79
arrows-es6/index.html Executable file
Просмотреть файл

@ -0,0 +1,79 @@
---
feature_name: ES6 Arrow functions
chrome_version: 45
feature_id: 5047308127305728
---
<h3>Background</h3>
<p>ES6 fat arrow functions have a shorter syntax compared to
function expressions and lexically bind the <code>this</code> value. Arrow functions are always anonymous and effectively turn
<code>function (arguments) { expression }</code> into <code>arguments => expression</code>. If using an expression after an arrow, the return is implicit, so no <code>return</code> is required.</p>
{% include output_helper.html %}
{% capture js %}
'use strict';
// Filter an array for only odd numbers
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// Before...
let es5_odd_numbers = numbers.filter(function(number) {
return number % 2;
});
ChromeSamples.log(es5_odd_numbers);
// After...
let es6_odd_numbers = numbers.filter(number => number % 2);
ChromeSamples.log(es6_odd_numbers);
// Parens are optional depending on the number of arguments:
let square = x => x * x;
ChromeSamples.log(square(10));
let add = (a, b) => a + b;
ChromeSamples.log(add(3,4));
// `return` is implied if using an expression after an arrow.
let developers = [{ name: 'Rob' }, { name: 'Jake' }];
// Before...
let es5_output = developers.map(function(developer) { return developer.name; });
ChromeSamples.log(es5_output);
// After...
let es6_output = developers.map(developer => developer.name);
ChromeSamples.log(es6_output);
// Fat arrows change how `this` is handled.
// Before...
// In ES5, `bind()` or var that = this; are necessary as functions
// create their own `this`. We need to store the parent `this` in
// a variable that can be referenced in the callback or take care
// of binding ourselves.
var counter_es5 = function() {
this.seconds = 0;
var that = this;
setInterval(function() {
that.seconds++;
}, 1000); // or }.bind(this), 1000) and skip that = this
}
var counterA = new counter_es5();
setTimeout(function() {
ChromeSamples.log(counterA.seconds);
}, 1200);
// After...
// ES6 Arrows instead bind `this` to the immediate enclosing
// lexical scope:
let counter_es6 = function() {
this.seconds = 0;
setInterval(() => this.seconds++, 1000);
}
let counterB = new counter_es6();
setTimeout(() => ChromeSamples.log(counterB.seconds), 1200);
{% endcapture %}
{% include js_snippet.html js=js %}

7
index.html Normal file
Просмотреть файл

@ -0,0 +1,7 @@
<!doctype html>
<html>
<head>
<title>Redirecting...</title>
<meta http-equiv="refresh" content="0;URL='https://www.chromestatus.com/features'">
</head>
</html>

6
object-assign-es6/README.md Executable file
Просмотреть файл

@ -0,0 +1,6 @@
Object.assign() (ES6) Sample
===
See https://googlechrome.github.io/samples/object-assign-es6/index.html for a live demo.
<!-- TODO: Replace PLACEHOLDER with the id from the chromestatus.com URL. -->
<!--Learn more at https://www.chromestatus.com/feature/PLACEHOLDER-->

43
object-assign-es6/index.html Executable file
Просмотреть файл

@ -0,0 +1,43 @@
---
feature_name: ES6 Object.assign()
chrome_version: 45
feature_id: REPLACE_ME
---
<h3>Background</h3>
<p><code>Object.assign()</code> copies the values (of all enumerable own properties) from one or more source objects to a target object. It has a signature of <code>Object.assign(target, ...sources)</code>. The target object is the first parameter and is also used as the return value. <code>Object.assign()</code> is useful for merging objects or cloning them shallowly.</p>
{% capture initial_output_content %}
{% endcapture %}
{% include output_helper.html initial_output_content=initial_output_content %}
{% capture js %}
'use strict';
// Merge an object
let first = { name: "Tony" };
let last = { lastName: "Stark" };
let person = Object.assign(first, last);
ChromeSamples.log(person);
// {name: "Tony", lastName: "Stark"}
ChromeSamples.log(first);
// first = {name: "Tony", lastName: "Stark"} as the target also changed
// Merge multiple sources
let a = Object.assign({foo: 0}, {bar: 1}, {baz: 2});
ChromeSamples.log(a);
// {foo: 0, bar: 1, baz: 2}
// Merge and overwrite equal keys
let b = Object.assign({foo: 0}, {foo: 1}, {foo: 2});
ChromeSamples.log(b);
// {foo: 2}
// Clone an object
let obj = { person: "Thor Odinson"};
let clone = Object.assign({}, obj);
ChromeSamples.log(clone);
// {person: "Thor Odinson"}
{% endcapture %}
{% include js_snippet.html js=js %}

Просмотреть файл

@ -0,0 +1,5 @@
Subresource Integrity Sample
===
See https://googlechrome.github.io/samples/subresource-integrity/index.html for a live demo.
Learn more at https://www.chromestatus.com/feature/6183089948590080

Просмотреть файл

@ -0,0 +1,3 @@
#correct {
background-color: #00e300;
}

Просмотреть файл

@ -0,0 +1,3 @@
#incorrect {
background-color: #ff9ca0;
}

Просмотреть файл

@ -0,0 +1,48 @@
---
feature_name: Subresource Integrity
chrome_version: 45
feature_id: 6183089948590080
---
<p>
<a href="http://w3c.github.io/webappsec/specs/subresourceintegrity/">Subresource integrity</a>
defines a mechanism by which a browser can verify that a fetched resource has been delivered
without unexpected manipulation.
<a href="http://w3c.github.io/webappsec/specs/subresourceintegrity/#dfn-integrity-metadata">Metadata</a>
inlined into HTML elements allows the browser to determine whether the resource that was
downloaded matches the resource the page's author expected to download.
</p>
<p>
The current implementation covers only the two elements outlined in the spec:
<code>&lt;script></code> and <code>&lt;link rel="stylesheet"></code> elements.
</p>
<p>
This page attempts to load two local CSS resources. One is linked to with a valid hash, and the
other is linked to with an invalid hash. Browsers that support subresource integrity will
refuse to load the CSS resource with the invalid hash. In a real-world application, this might be
more useful when you are calculating the hash of a third party, remote resource that you do not
control, but local resources are being used for illustrative purposes.
</p>
<p id="correct">
This paragraph is styled via the CSS resource linked to with
<code>&lt;link rel="stylesheet" href="correct_hash.css" integrity="sha256-qvuZLpjL9TNV6yI1kNdGCPnSTrWM6Y0ILEzzyvA9hGY="></code>
Since that uses an <code>integrity</code> attribute that corresponds to the actual hash of the
file, it will be loaded successfully and this paragraph will be green.
<code>cat correct_hash.css | openssl dgst -sha256 -binary | openssl enc -base64 -A</code> was used
to generate the <code>sha256</code> hash value.
</p>
<link rel="stylesheet" href="correct_hash.css" integrity="sha256-qvuZLpjL9TNV6yI1kNdGCPnSTrWM6Y0ILEzzyvA9hGY=">
<p id="incorrect">
This paragraph is styled via the CSS resource linked to with
<code>&lt;link rel="stylesheet" href="incorrect_hash.css" integrity="sha256-OBVIOUSLY_INCORRECT_HASH"></code>
Browsers that support subresource integrity will refuse to load the file, since the
<code>integrity</code> value doesn't correspond to the actual <code>sha256</code> hash of the
file. You'll see an error message logged in the DevTool's console. Browsers that don't support
subresource integrity will, however, load the file, and in those browsers this paragraph will be
pink.
</p>
<link rel="stylesheet" href="incorrect_hash.css" integrity="sha256-OBVIOUSLY_INCORRECT_HASH">

4
web-bluetooth/README.md Executable file → Normal file
Просмотреть файл

@ -1,5 +1,5 @@
Web Bluetooth Sample
====================
Web Bluetooth Samples
=====================
See https://googlechrome.github.io/samples/web-bluetooth/index.html for a live demo.
Learn more at http://www.chromestatus.com/feature/5264933985976320

Просмотреть файл

@ -0,0 +1,70 @@
---
feature_name: Web Bluetooth / Battery Level
chrome_version: 45
feature_id: 5264933985976320
---
<p>The <a href="https://github.com/WebBluetoothCG/web-bluetooth">Web Bluetooth API</a> discovers and communicates with devices over the Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). It is currently only partially implemented in Chrome OS behind the experimental flag <code>chrome://flags/#enable-web-bluetooth</code>.</p>
<p>This sample illustrates the use of the Web Bluetooth API to retrieve battery
information from a nearby Bluetooth Device advertising Battery information with
Bluetooth Low Energy. You may want to try this demo with the BLE Peripheral
Simulator App from the <a target="_blank"
href="https://play.google.com/store/apps/details?id=io.github.webbluetoothcg.bletestperipheral">Google
Play Store</a>.</p>
<button>Get Bluetooth Device's Battery Level</button>
{% capture initial_output_content %}
{% endcapture %}
{% include output_helper.html initial_output_content=initial_output_content %}
{% capture js %}
function onButtonClick() {
'use strict';
log('Requesting Bluetooth Device...');
navigator.bluetooth.requestDevice({filters:[{services:['battery_service']}]})
.then(device => {
log('> Found ' + device.name);
log('Connecting to GATT Server...');
return device.connectGATT();
})
.then(server => {
log('Getting Battery Service...');
return server.getPrimaryService('battery_service');
})
.then(service => {
if (!service) {
throw 'Battery Service not found';
}
log('Getting Battery Level Characteristic...');
return service.getCharacteristic('battery_level');
})
.then(characteristic => {
log('Reading Battery Level...');
return characteristic.readValue();
})
.then(buffer => {
let data = new DataView(buffer);
let batteryLevel = data.getUint8(0);
log('> Battery Level is ' + batteryLevel + '%');
})
.catch(error => {
log('Argh! ' + error);
});
};
{% endcapture %}
{% include js_snippet.html js=js %}
<script>
document.querySelector('button').addEventListener('click', function() {
document.querySelector('#log').textContent = '';
if (!navigator.bluetooth) {
log('Web Bluetooth API is not available.');
log('Please make sure you run Chrome OS M45 and the Web Bluetooth flag is enabled.');
} else {
onButtonClick();
}
});
log = ChromeSamples.log;
</script>

47
web-bluetooth/device-info.html Executable file
Просмотреть файл

@ -0,0 +1,47 @@
---
feature_name: Web Bluetooth / Device Info
chrome_version: 45
feature_id: 5264933985976320
---
<p>The <a href="https://github.com/WebBluetoothCG/web-bluetooth">Web Bluetooth API</a> discovers and communicates with devices over the Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). It is currently only partially implemented in Chrome OS behind the experimental flag <code>chrome://flags/#enable-web-bluetooth</code>.</p>
<p>This sample illustrates the use of the Web Bluetooth API to retrieve basic
device information from a nearby Bluetooth Low Energy Device.</p>
<button>Get Bluetooth Device Info</button>
{% capture initial_output_content %}
{% endcapture %}
{% include output_helper.html initial_output_content=initial_output_content %}
{% capture js %}
function onButtonClick() {
log('Requesting Bluetooth Device...');
navigator.bluetooth.requestDevice({filters:[{services:['generic_access']}]})
.then(device => {
log('> Device Name: ' + device.name);
log('> Device InstanceID: ' + device.instanceID);
log('> Device Paired: ' + device.paired);
log('> Device Class: ' + device.deviceClass);
log('> Device UUIDs: ' + device.uuids.join('\n'+'\x20'.repeat(21)));
})
.catch(error => {
log('Argh! ' + error);
});
};
{% endcapture %}
{% include js_snippet.html js=js %}
<script>
document.querySelector('button').addEventListener('click', function() {
document.querySelector('#log').textContent = '';
if (!navigator.bluetooth) {
log('Web Bluetooth API is not available.');
log('Please make sure you run Chrome OS M45 and the Web Bluetooth flag is enabled.');
} else {
onButtonClick();
}
});
log = ChromeSamples.log;
</script>

Просмотреть файл

@ -1,68 +1,12 @@
---
feature_name: Web Bluetooth
title: Web Bluetooth Samples
chrome_version: 45
feature_id: 5264933985976320
---
<p>The <a href="https://github.com/WebBluetoothCG/web-bluetooth">Web Bluetooth API</a> aims to discover and communicate with devices over the Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). It is currently only partially implemented in Chrome OS behind the experimental flag <code>chrome://flags/#enable-web-bluetooth</code>.</p>
<p>This sample illustrates the use of the Web Bluetooth API to retrieve battery
information from a nearby Bluetooth Device advertising Battery information with
Bluetooth Low Energy. You may want to try this demo with the BLE Peripheral
Simulator App from the <a target="_blank"
href="https://play.google.com/store/apps/details?id=io.github.webbluetoothcg.bletestperipheral">Google
Play Store</a>.</p>
<button>Get Bluetooth Device Battery</button>
{% capture initial_output_content %}
{% endcapture %}
{% include output_helper.html initial_output_content=initial_output_content %}
{% capture js %}
function onButtonClick() {
'use strict';
log('Requesting Bluetooth Device...');
navigator.bluetooth.requestDevice({filters:[{services:['battery_service']}]})
.then(device => {
log('> Found ' + device.name);
log('Connecting to GATT Server...');
return device.connectGATT();
})
.then(server => {
log('Getting Battery Service...');
return server.getPrimaryService('battery_service');
})
.then(service => {
if (!service) throw 'Battery Service not found';
log('Getting Battery Level Characteristic...');
return service.getCharacteristic('battery_level');
})
.then(characteristic => {
log('Reading Battery Level...');
return characteristic.readValue();
})
.then(buffer => {
let data = new DataView(buffer);
let batteryLevel = data.getUint8(0);
log('> Battery Level is ' + batteryLevel + '%');
})
.catch(error => {
log('Argh! ' + error);
});
};
{% endcapture %}
{% include js_snippet.html js=js %}
<script>
document.querySelector('button').addEventListener('click', function() {
document.querySelector('#log').textContent = '';
if (!navigator.bluetooth) {
log('Web Bluetooth API is not available.');
log('Please make sure you run Chrome OS M45 and Web Bluetooth flag is enabled.');
} else {
onButtonClick();
}
});
log = ChromeSamples.log;
</script>
<p>The following samples show you some of the ways that you can use the Web Bluetooth API:</p>
<ul>
<li><a target="_blank" href="battery-level.html">Battery Level</a></li>
<li><a target="_blank" href="device-info.html">Device Info</a></li>
<li><a target="_blank" href="reset-energy.html">Reset Energy</a></li>
</ul>

71
web-bluetooth/reset-energy.html Executable file
Просмотреть файл

@ -0,0 +1,71 @@
---
feature_name: Web Bluetooth / Reset Energy Expended
chrome_version: 45
feature_id: 5264933985976320
---
<p>The <a href="https://github.com/WebBluetoothCG/web-bluetooth">Web Bluetooth API</a> discovers and communicates with devices over the Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). It is currently only partially implemented in Chrome OS behind the experimental flag <code>chrome://flags/#enable-web-bluetooth</code>.</p>
<p>This sample illustrates the use of the Web Bluetooth API to reset energy
expended from a nearby Bluetooth Device advertising Heart Rate with Bluetooth
Low Energy. You may want to try this demo with the BLE Peripheral Simulator
App from the <a target="_blank"
href="https://play.google.com/store/apps/details?id=io.github.webbluetoothcg.bletestperipheral">Google
Play Store</a>.</p>
<button>Reset Energy Expended</button>
{% capture initial_output_content %}
{% endcapture %}
{% include output_helper.html initial_output_content=initial_output_content %}
{% capture js %}
function onButtonClick() {
'use strict';
log('Requesting Bluetooth Device...');
navigator.bluetooth.requestDevice({filters:[{services:['heart_rate']}]})
.then(device => {
log('> Found ' + device.name);
log('Connecting to GATT Server...');
return device.connectGATT();
})
.then(server => {
log('Getting Heart Rate Service...');
return server.getPrimaryService('heart_rate');
})
.then(service => {
if (!service) {
throw 'Heart Rate service not found';
}
log('Getting Heart Rate Control Point Characteristic...');
return service.getCharacteristic('heart_rate_control_point');
})
.then(characteristic => {
log('Writing Heart Rate Control Point Characteristic...');
// Writing 1 is the signal to reset energy expended.
let resetEnergyExpended = new Uint8Array([1]);
return characteristic.writeValue(resetEnergyExpended);
})
.then(value => {
log('> Energy expended has been reset.');
})
.catch(error => {
log('Argh! ' + error);
});
};
{% endcapture %}
{% include js_snippet.html js=js %}
<script>
document.querySelector('button').addEventListener('click', function() {
document.querySelector('#log').textContent = '';
if (!navigator.bluetooth) {
log('Web Bluetooth API is not available.');
log('Please make sure you run Chrome OS M45 and the Web Bluetooth flag is enabled.');
} else {
onButtonClick();
}
});
log = ChromeSamples.log;
</script>