Modernizrを使ってWeb APIの利用可能状況を調べる

# 概要

ブラウザがどのWeb APIを利用できるか（サポートしているか）を、Modernizrがどのようなロジックで検出しているのか調べたときの記録です。
またブラウザ毎にModernizrの検出結果をまとめました。(safariは残念ながらiPhoneの実機を持っていないので調べていません。)


**環境**

* Windows10 Professional
* Modernizr 3.3.1
* PC版ブラウザ
 * Chrome 54
 * Chrome Canary 56 (開発者向け)
 * Firefox 49
 * Fifefox Developer 51 (開発者向け)
 * IE11
 * Edge
* Android版ブラウザ
 * Chrome 54
 * Chrome Canary 56 (開発者向け)
 * Firefox 49
 * Firefox Aurora 51 (開発者向け)

**参考**

* [Modernizr - Documentation] (https://modernizr.com/docs/)
* [GitHub - Modernizr/Modernizr] (https://github.com/Modernizr/Modernizr)

# Web APIの検出結果

## PC版

バージョンは2016年11月10日時点のものです。

|API                  |Chrome(54)|Chrome<br/>Canary(56)|FireFox(49)|FireFox<br/>Developer(51)|IE11   |Edge   |
|:--------------------|:--------:|:-------------------:|:---------:|:-----------------------:|:-----:|:-----:|
|Event Listener       |true      |true                 |true       |true                     |true   |true   |
|Geolocation API      |true      |true                 |*補足A      |*補足A                   |true   |true   |
|History API          |true      |true                 |true       |true                     |true   |true   |
|Notification         |true      |true                 |*補足B      |*補足B                   |false  |true   |
|postMessage          |true      |true                 |true       |true                     |true   |true   |
|ServiceWorker API    |true      |true                 |true       |true                     |false  |false  |
|Touch Events         |false     |false                |false      |false                    |false  |false  |
|Force Touch Events   |false     |false                |false      |false                    |false  |false  |
|File API             |true      |true                 |true       |true                     |true   |true   |
|Local Storage        |true      |true                 |true       |true                     |true   |true   |
|Session Storage      |true      |true                 |true       |true                     |true   |true   |

### 補足A. Geolocation API

現在位置の追跡の設定

|設定    |Chrome(54)|Chrome<br/>Canary(56)|FireFox(49)|FireFox<br/>Developer(51)|IE11   |Edge   |
|:-------|:--------:|:-------------------:|:---------:|:-----------------------:|:-----:|:-----:|
|許可    |true      |true                  |true       |true                     |true   |true  |
|ブロック |true      |true                 |false      |false                    |true   |true   |

* Firefoxは現在位置の追跡の設定をブロックすると`navigator.geolocation`がundefinedになる。

### 補足B. Notification

通知の設定

|設定    |Chrome(54)|Chrome<br/>Canary(56)|FireFox(49)|FireFox<br/>Developer(51)|IE11   |Edge   |
|:-------|:--------:|:-------------------:|:---------:|:-----------------------:|:-----:|:-----:|
|許可    |true      |true                  |true       |true                     |false  |true  |
|ブロック |true      |true                 |false      |false                    |false  |true   |

* Firefoxは通知の設定をブロックすると`window.Notification`がundefinedになる。
* IE11はNotificationをサポートしていない。


## Android版

バージョンは2016年11月10日時点のものです。

|API                  |Chrome(54)|Chrome<br/>Canary(56)|FireFox(49)|FireFox<br/>Aurora(51)|
|:--------------------|:--------:|:-------------------:|:---------:|:--------------------:|
|Event Listener       |true      |true                 |true       |true                  |
|Geolocation API      |true      |true                 |*補足C     |*補足C                 |
|History API          |true      |true                 |true       |true                  |
|Notification         |*補足D    |*補足D                |*補足D     |*補足D                |
|postMessage          |true      |true                 |true       |true                  |
|ServiceWorker API    |true      |true                 |true       |true                  |
|Touch Events         |true      |true                 |true       |true                  |
|Force Touch Events   |false     |false                |false      |false                 |
|File API             |true      |true                 |true       |true                  |
|Local Storage        |true      |true                 |true       |true                  |
|Session Storage      |true      |true                 |true       |true                  |

### 補足C. Geolocation API

現在位置の追跡の設定

|設定    |Chrome(54)|Chrome<br/>Canary(56)|FireFox(49)|FireFox<br/>Aurora(51)|
|:-------|:--------:|:-------------------:|:---------:|:--------------------:|
|許可    |true      |true                 |true       |true                  |
|ブロック |true     |true                  |false     |false                 |

### 補足D. Notification

通知の設定

|設定    |Chrome(54)|Chrome<br/>Canary(56)|FireFox(49)|FireFox<br/>Aurora(51)|
|:-------|:--------:|:-------------------:|:---------:|:--------------------:|
|許可    |true       |true                |true       |true                  |
|ブロック |false     |false               |false      |false                 |


## Event Listener

* [MDN - EventTarget.addEventListener] (https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/eventlistener.js

```js
'addEventListener' in window
```

**API利用可能の判定コード**

```js
if (Modernizr.eventlistener) {
  // supported
} else {
  // not-supported
}
```


## Geolocation API

* [MDN - Geolocation] (https://developer.mozilla.org/ja/docs/Web/API/Geolocation)
* [MDN - Geolocation の利用] (https://developer.mozilla.org/ja/docs/WebAPI/Using_geolocation)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/geolocation.js

```js
'geolocation' in navigator
```

**API利用可能の判定コード**

```js
if (Modernizr.geolocation) {
  // supported
} else {
  // not-supported
}
```

### 現在地の設定

#### PC版Chrome

設定 → プライバシー → コンテンツの設定... → 現在地

![pc_chrome_geo.png](https://qiita-image-store.s3.amazonaws.com/0/22772/3f107af8-e70d-052c-4431-d303904ef48a.png)

#### PC版Firefox

アドレスバーに`about:config`と入力 → `geo.enabled`で検索

![pc_firefox_geo.png](https://qiita-image-store.s3.amazonaws.com/0/22772/6470edb8-c307-ccea-ffe4-b6f18488a935.png)

#### IE11

インターネットオプション → プライバシー → 位置情報

![pc_ie11_geo.png](https://qiita-image-store.s3.amazonaws.com/0/22772/1dbb9dfe-495d-a931-7b46-533bc0ffc7ee.png)

#### Edge

Windows10の設定 → プライバシー → 位置情報

![pc_edge_geo_1.png](https://qiita-image-store.s3.amazonaws.com/0/22772/df1f4ecd-2c86-a4d6-8e5b-134079555858.png)

![pc_edge_geo_2.png](https://qiita-image-store.s3.amazonaws.com/0/22772/6ab5cf41-41f2-c543-ab3a-24a37699ac1f.png)


#### Android版Chrome

設定 → サイトの設定 → 現在地

![sma_chrome_geo.png](https://qiita-image-store.s3.amazonaws.com/0/22772/24cd0798-05f9-4574-8577-74a01b137622.png)

#### Android版Firefox

アドレスバーに`about:config`と入力 → `geo.enabled`で検索

![sma_firefox_geo.png](https://qiita-image-store.s3.amazonaws.com/0/22772/d6d39c74-fccd-8bed-e4ae-262f96d53c57.png)



## History API

* [MDN - History] (https://developer.mozilla.org/ja/docs/Web/API/History)
* [MDN - Window.history] (https://developer.mozilla.org/en-US/docs/Web/API/Window/history)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/history.js

```js
var ua = navigator.userAgent;

if ((ua.indexOf('Android 2.') !== -1 ||
    (ua.indexOf('Android 4.0') !== -1)) &&
     ua.indexOf('Mobile Safari') !== -1 &&
     ua.indexOf('Chrome') === -1 &&
     ua.indexOf('Windows Phone') === -1) {
  return false;
}

return (window.history && 'pushState' in window.history);
```

**API利用可能の判定コード**

```js
if (Modernizr.history) {
  // supported
} else {
  // not-supported
}
```


## Notification

* [MDN - Notification] (https://developer.mozilla.org/ja/docs/Web/API/notification)
* [MDN - Web Notificationsを使用する] (https://developer.mozilla.org/ja/docs/WebAPI/Using_Web_Notifications)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/notification.js

```js
if (!window.Notification || !window.Notification.requestPermission) {
  return false;
}
if (window.Notification.permission === 'granted') {
  return true;
}

try {
  new window.Notification('');
} catch (e) {
  if (e.name === 'TypeError') {
    return false;
  }
}

return true;
```

**API利用可能の判定コード**

```js
if (Modernizr.notification) {
  // supported
} else {
  // not-supported
}
```

### 通知の設定

#### PC版Chrome

設定 → プライバシー → コンテンツの設定... → 通知

![pc_chrome_notice.png](https://qiita-image-store.s3.amazonaws.com/0/22772/d0318a65-3118-f862-ba72-b0d9e74e579f.png)

#### PC版Firefox

アドレスバーに`about:config`と入力 → `dom.webnotifications.enabled`で検索

![pc_firefox_notice.png](https://qiita-image-store.s3.amazonaws.com/0/22772/4f004812-0711-318c-9bc8-c17160c8de34.png)

#### Edge

設定 → 詳細設定 → 通知

![pc_edge_notice.png](https://qiita-image-store.s3.amazonaws.com/0/22772/6601e61f-73b0-d7f3-2e8f-e7a87b2ae40d.png)

#### Android版Chrome

設定 → サイトの設定 → 通知

![sma_chrome_notice.png](https://qiita-image-store.s3.amazonaws.com/0/22772/fa24631f-2ca5-f609-28d6-ad3546866d80.png)

#### Android版Firefox

アドレスバーに`about:config`と入力 → `dom.webnotifications.enabled`で検索

![sma_firefox_notice.png](https://qiita-image-store.s3.amazonaws.com/0/22772/0dae7930-9e08-f142-86a1-591702d4080e.png)


## postMessage

* [MDN - window.postMessage] (https://developer.mozilla.org/ja/docs/Web/API/Window/postMessage)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/postmessage.js

```js
'postMessage' in window
```

**API利用可能の判定コード**

```js
if (Modernizr.postmessage) {
  // supported
} else {
  // not-supported
}
```


## ServiceWorker API

* [ServiceWorker API] (https://developer.mozilla.org/ja/docs/Web/API/ServiceWorker_API)
* [Service Workerの利用について] (https://developer.mozilla.org/ja/docs/Web/API/ServiceWorker_API/Using_Service_Workers)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/serviceworker.js

```js
'serviceWorker' in navigator
```

**API利用可能の判定コード**

```js
if (Modernizr.serviceworker) {
  // supported
} else {
  // not-supported
}
```


## Touch Events

* [MDN - TouchEvent] (https://developer.mozilla.org/ja/docs/Web/API/TouchEvent)
* [MDN - DocumentTouch] (https://developer.mozilla.org/ja/docs/Web/API/DocumentTouch)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/touchevents.js

```js
var bool;
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
  bool = true;
} else {
  var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join('');
  testStyles(query, function(node) {
    bool = node.offsetTop === 9;
  });
}

return bool;
```

* prefixes,testStylesはModernizrの関数です。


**API利用可能の判定コード**

```js
if (Modernizr.touchevents) {
  // supported
} else {
  // not-supported
}
```

### PC版Chromeでのエミュレート

エミュレートするデバイスがTouch Eventsをサポートしていれば、PC版Chromeでも有効になります。
または、DevToolsのドロワーでSensorsを開きTouchの設定に"Force enabled"を選択します。

![touch_force_enabled.png](https://qiita-image-store.s3.amazonaws.com/0/22772/dea6e54f-05e9-1c38-be33-bf1117d7c1e6.png)


## Force Touch Events

* [MDN - Touch.force] (https://developer.mozilla.org/en-US/docs/Web/API/Touch/force)
* [MDN - Force Touch events] (https://developer.mozilla.org/en-US/docs/Web/API/Force_Touch_events)

**API検出ロジック**

```js
if (!hasEvent(prefixed('mouseforcewillbegin', window, false), window)) {
  return false;
}

return MouseEvent.WEBKIT_FORCE_AT_MOUSE_DOWN && MouseEvent.WEBKIT_FORCE_AT_FORCE_MOUSE_DOWN;
```

* hasEvent,prefiexedはModernizrの関数です。

**API利用可能の判定コード**

```js
if (Modernizr.forcetouch) {
  // supported
} else {
  // not-supported
}
```

## File API

* [MDN - FileReader] (https://developer.mozilla.org/ja/docs/Web/API/FileReader)
* [MDN - Web アプリケーションからファイルを扱う] (https://developer.mozilla.org/ja/docs/Using_files_from_web_applications)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/file/api.js

```js
!!(window.File && window.FileList && window.FileReader)
```

**API利用可能の判定コード**

```js
if (Modernizr.filereader) {
  // supported
} else {
  // not-supported
}
```


## Local Storage

* [MDN - Window.localStorage] (https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/storage/localstorage.js

```js
var mod = 'modernizr';
try {
  localStorage.setItem(mod, mod);
  localStorage.removeItem(mod);
  return true;
} catch (e) {
  return false;
}
```

**API利用可能の判定コード**

```js
if (Modernizr.localstorage) {
  // supported
} else {
  // not-supported
}
```


## Session Storage

* [MDN - Window.sessionStorage] (https://developer.mozilla.org/ja/docs/Web/API/Window/sessionStorage)

**API検出ロジック**

https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/storage/sessionstorage.js

```js
var mod = 'modernizr';
try {
  sessionStorage.setItem(mod, mod);
  sessionStorage.removeItem(mod);
  return true;
} catch (e) {
  return false;
}
```

**API利用可能の判定コード**

```js
if (Modernizr.sessionstorage) {
  // supported
} else {
  // not-supported
}
```