[翻訳]Riot RouterのReadme.md

まだまだ枠が大量に空いていたので[Riot.js Advent Calendar 2020](https://qiita.com/advent-calendar/2020/riotjs)に16日目の記事として参加します。また、[なんか適当な Advent Calendar 2020](https://adventar.org/calendars/5649)16日目にも参加します。

Riot公式のRouterである[Riot Router](https://github.com/riot/route)のReadmeを2021年2月18日現在最新の版([432c94e](https://github.com/riot/route/blob/432c94e89608a9981fd94db7a2d7e199d316c6be/README.md))に基づき日本語訳しました。記事の内容は全てMITライセンスです。ライセンスの詳細は末尾に記載してあります。

2021/2/18更新: 2/13のコミット(432c94e)での更新を取り込み済みです。

# Riot Router

> Simple isomorphic router

The Riot.js Routerは以下の技術で実装されたミニマルなルーターです。

- DOM pushState や history API との互換性
- isomorphic functional API
- [erre.js streams](https://github.com/GianlucaGuarini/erre) と javascript async generators
- [rawth.js](https://github.com/GianlucaGuarini/rawth)のurls parsing


実行にはRiot.jsを必ずしも必要とせず、スタンドアローンモジュールとして利用できます。

**Riot.js 3 以前のバージョンに関しては[v3 branch](https://github.com/riot/route/tree/v3)を参照してください。**

## 目次

- [インストール](#インストール)
- [ドキュメント](#ドキュメント)
- [デモ](https://github.com/riot/examples)

## インストール

2つのエディションがあります。

エディション | ファイル
:-- | :--
**UMD Version** | `route.js`
**ESM Module** | `route.esm.js`
**Standalone UMD Module** | `route.standalone.js`

### Script injection

```html
<script src="https://unpkg.com/@riotjs/route@x.x.x/route.js"></script>
```

*注*: `x.x.x` の部分を利用したいバージョンに変えてください。 例: `4.5.0`、`4.7.0`

### ESM module

```js
import { route } from 'https://unpkg.com/@riotjs/route/route.esm.js'
```

### npm

```bash
$ npm i -S @riotjs/route
```

### 自分でダウンロードする

- [Standalone](https://unpkg.com/@riotjs/route/route.js)
- [ESM](https://unpkg.com/@riotjs/route/route.esm.js)

## ドキュメント

### Riot.jsとの併用

以下のように `<router>`コンポーネント と `<route>`コンポーネント をインポートしてアプリケーション内で利用できます。

```html
<app>
  <router>

    <!-- リンクは自動でHTML5 history eventsを発火する  -->
    <nav>
      <a href="/home">Home</a>
      <a href="/about">About</a>
      <a href="/team/gianluca">Gianluca</a>
    </nav>

    <!-- アプリケーションルートがここにレンダリングされる -->
    <route path="/home">
      Home page
    </route>
    <route path="/about">
      About
    </route>
    <route path="/team/:person">
      Hello dear { route.params.person }
    </route>

  </router>

  <script>
    import { Router, Route } from '@riotjs/route'

    export default {
      components { Router, Route }
    }
  </script>
</app>
```

`riot.register` メソッドを使用してグローバルに使用できるようにすることもできます。

```js
import { Route, Router } from '@riotjs/route'
import { register } from 'riot'

// Routerコンポーネント と Routeコンポーネント がグローバルに有効になる
register('router', Router)
register('route', Route)
```

#### Router

`<router>`コンポーネント はapplication markupで囲まれている必要があります。そうすることで、route eventのトリガーになるリンクの全てのクリックが自動的に検出されるようになります。

```html
<router>
  <!--riot router eventを発火 -->
  <a href="/path/somewhere">Link</a>
</router>
<!-- 通常のリンクのようにrouter eventsを発火しない  -->
<a href="/path/to/a/page">Link</a>
```

また、コンポーネント属性を通じてアプリケーションのbaseを定義することができます。

```html
<router base="/internal/path">
  <!-- base外のリンクのため通常のリンクのように機能する -->
  <a href="/somewhere">Link<a>
</router>
```

ルーターコンポーネントは`onStarted`コールバックも持ちます。 このコールバックは始めのroute eventが呼ばれた後に非同期的に呼ばれます。

```html
<router onStarted={onRouterStarted}></router>
```

#### Route

`<route>`コンポーネントは、子(単純な[URL](https://developer.mozilla.org/ja/docs/Web/API/URL)オブジェクト) にURLクエリパラメーターを検出できるようにする`route`プロパティーを提供します。

```html
<route path="/:some/:route/:param">
  {JSON.stringify(route.params)}
</route>

<route path="/search(.*)">
  <!-- URLが"/search?q=awesome"であるように振る舞う -->

  {route.searchParams.get('q')}
</route>
```

それぞれの `<route>`コンポーネントはマウント、アンマウントされたときに知らせるために、自身のlifecycle属性を持ちます。

```html
<app>
  <router>
    <route path="/home"
      on-before-mount={onBeforeHomeMount}
      on-mounted={onHomeMounted}
      on-before-unmount={onBeforeHomeUnmount}
      on-unmounted={onHomeUnmounted}
    />
  </router>
</app>
```

### スタンドアローン

このモジュールはriot.jsと共に使われるためだけではなく、スタンドアローンモジュールとして使われるようにも出来ています。Riot.jsのコンポーネントをインポートすることなくコアメソッドをexportして利用できます。これによって、あらゆる種類のフロントエンドシステムと互換性を持つルーターを構築してカスタマイズすることが可能です。

#### 基礎

このモジュールはnodeとモダンブラウザ上で動き、[rawth](https://github.com/GianlucaGuarini/rawth)が公開している`router`(訳注: おそらく`route`)プロパティーと`router`プロパティーをexportします。

```js
import { route, router, setBase } from '@riotjs/route'

// 最初にbaseをセットする必要がある
setBase('/');

// root streamの作成
const aboutStream = route('/about')

aboutStream.on.value(url => {
  console.log(url) // URL object
})

aboutStream.on.value(() => {
  console.log('just log that the about route was triggered')
})

// 各route eventでトリガー
router.on.value(path => {
  // この関数の中で path は常に文字列
  console.log(path)
})

// route changeを手動でトリガー
router.push('/about')

// streamここまで
aboutStream.end()
```

#### Base path

ブラウザでルーターを使う前にapplication base pathを設定する必要があります。
これは単純に`setBase`で設定できます。

```js
import { setBase } from '@riotjs/route'

// HTML5 history navigation を使用する場合
setBase(`/`)

// hash navigation を使用する場合
setBase(`#`)
```

application routeのbase pathは、ルートを作成する前の最初に必ず設定する必要があります。

#### DOM binding
上の例はブラウザ環境で動かしている場合、あまり実用的ではありません。ブラウザ環境ではルーターとroute change eventのトリガーとなる全てのDOM listening click eventに関連付けたいと思うはずです。
Window history `popstate` eventsはルーターと接続する必要があります。
`initDomListeners`メソッドは上の機能をすべて自動的にもたらします。

```js

import { initDomListeners } from '@riotjs/route'

const unsubscribe = initDomListeners()
// page DOMとルーターを接続

// ...分解してルーターをDOMから切断
unsubscribe()
```

`initDomListeners` はアプリケーション上のすべてのリンクのクリックを無効化します。しかし、特定のDOM領域だけを対象としてスコープするために、HTMLElementやHTMLElementのリストを引数として受け取ることができます。

```js
import { initDomListeners } from '@riotjs/route'

initDomListeners(document.querySelector('.main-navigation'))
```

## ライセンス
```
MIT License

Copyright (c) Gianluca Guarini

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```