points - SVG: スケーラブルベクターグラフィック

points
======

**`points`** 属性は、点のリストを定義します。各点は、ユーザー座標系における X 座標と Y 座標を表す数値の組で定義されます。属性に奇数の座標が含まれている場合、最後の座標は無視されます。

この属性は次の SVG 要素で使用できます。

* `<polyline>`
* `<polygon>`
例
-
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="-10 -10 220 120" xmlns="http://www.w3.org/2000/svg">
  <!-- polylineは開いた図形となる -->
  <polyline stroke="black" fill="none" points="50,0 21,90 98,35 2,35 79,90" />

  <!-- polygonは閉じた図形となる -->
  <polygon
 stroke="black"
 fill="none"
 transform="translate(100,0)"
 points="50,0 21,90 98,35 2,35 79,90" />

  <!--
 通常、XとYをカンマで、座標群をスペースで区切るのがベストプラクティスとされます。
 その方法はコードを人間にとって読みやすいものにしてくれます。
 -->
</svg>
```

polyline
--------

`<polyline>`の場合、 `points` で定義された点リストはそれぞれが描きたい線の頂点を表します。各点は、ユーザー座標系の X 座標と Y 座標として定義されます。

**メモ:** polyline は最初の点と最後の点が接続されない開いた図形となります。

|  |  |
| --- | --- |
| Value | [ `<number>`+ ]# |
| Default value | *none* |
| Animatable | Yes |
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="-10 -10 120 120" xmlns="http://www.w3.org/2000/svg">
  <!-- polylineは開いた図形となる -->
  <polyline stroke="black" fill="none" points="50,0 21,90 98,35 2,35 79,90" />
</svg>
```

polygon
-------

`<polygon>`の場合、`points` で定義された点リストはそれぞれが描きたい図形の頂点を表します。各点は、ユーザー座標系の X 座標と Y 座標として定義されます。

**メモ:** polygon は最初の点と最後の点が接続された閉じた図形となります。

|  |  |
| --- | --- |
| Value | [ `<number>`+ ]# |
| Default value | *none* |
| Animatable | Yes |
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="-10 -10 120 120" xmlns="http://www.w3.org/2000/svg">
  <!-- polygonは閉じた図形となる -->
  <polygon stroke="black" fill="none" points="50,0 21,90 98,35 2,35 79,90" />
</svg>
```

仕様
--

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # PolygonElementPointsAttribute |
| Scalable Vector Graphics (SVG) 2 # PolylineElementPointsAttribute |


stroke-linecap - SVG: スケーラブルベクターグラフィック

stroke-linecap
==============

« SVG 属性リファレンスホーム

`stroke-linecap` 要素は線を引いた時の開いている部分パスの終端の形状を指定します。

プレゼンテーション属性であるため、直接 CSS スタイルシートの中で定義したプロパティとして使うこともできます。

使用可能な場所
-------

| カテゴリ | プレゼンテーション属性 |
| --- | --- |
| 値 | butt | round | square | inherit |
| アニメーション | Yes |
| 標準文書 | SVG 1.1 (2nd Edition) |

例
-

```html
<?xml version="1.0"?>
<svg
 width="120"
 height="120"
 viewBox="0 0 120 120"
 version="1.1"
 xmlns="http://www.w3.org/2000/svg">
  <line
 stroke-linecap="butt"
 x1="30"
 y1="30"
 x2="30"
 y2="90"
 stroke="black"
 stroke-width="20" />

  <line
 stroke-linecap="round"
 x1="60"
 y1="30"
 x2="60"
 y2="90"
 stroke="black"
 stroke-width="20" />

  <line
 stroke-linecap="square"
 x1="90"
 y1="30"
 x2="90"
 y2="90"
 stroke="black"
 stroke-width="20" />

  <path d="M30,30 L30,90 M60,30 L60,90 M90,30 L90,90" stroke="white" />
</svg>
```

要素
--

以下の要素で `stroke-linecap` を使うことができます

* Shape 要素 »
* Text content 要素 »


scale - SVG: スケーラブルベクターグラフィック

scale
=====

**`scale`** 属性は、`<feDisplacementMap>` (en-US)フィルタプリミティブにおいて用いられる距離の尺度因子を定義します。その量は、`<filter>` (en-US)要素の`primitiveUnits (en-US)`属性で規定される座標系で表されます。

1 つの要素のみがこの属性を用います: `<feDisplacementMap>` (en-US)
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 480 220" xmlns="http://www.w3.org/2000/svg">
  <filter id="displacementFilter" x="-20%" y="-20%" width="140%" height="140%">
    <feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2" result="turbulence"/>
    <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="5"/>
  </filter>
  <filter id="displacementFilter2" x="-20%" y="-20%" width="140%" height="140%">
    <feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2" result="turbulence"/>
    <feDisplacementMap in2="turbulence" in="SourceGraphic" scale="50"/>
  </filter>

  <circle cx="100" cy="100" r="80" style="filter: url(#displacementFilter);""/>
  <circle cx="100" cy="100" r="80" style="filter: url(#displacementFilter2); transform: translateX(240px);""/>
</svg>
```

使用方法
----

|  |  |
| --- | --- |
| 値 | `<number>` |
| 既定値 | *None* |
| アニメーション可否 | はい |

`<number>`

この値は距離に関する尺度因子をのみを定義します。

この属性の値が`0`の場合は、元画像に対して影響しません。

仕様
--

| Specification |
| --- |
| Filter Effects Module Level 1 # element-attrdef-fedisplacementmap-scale |

ブラウザー実装状況
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


patternUnits - SVG: スケーラブルベクターグラフィック

patternUnits
============

**`patternUnits`** 属性は、 `<pattern>` 要素のジオメトリープロパティにどの座標系を使用するかを示します。

この属性は以下の SVG 要素で使用することができます。

* `<pattern>`
例
-
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- すべてのジオメトリープロパティは、現在のユーザー空間からの相対値です。 -->
  <pattern
 id="p1"
 x="12.5"
 y="12.5"
 width="25"
 height="25"
 patternUnits="userSpaceOnUse">
    <circle cx="10" cy="10" r="10" />
  </pattern>

  <!-- すべてのジオメトリープロパティは、対象とするバウンディングボックスからの相対値です。 -->
  <pattern
 id="p2"
 x=".125"
 y=".125"
 width=".25"
 height=".25"
 patternUnits="objectBoundingBox">
    <circle cx="10" cy="10" r="10" />
  </pattern>

  <!-- Left square with user space tiles -->
  <rect x="10" y="10" width="80" height="80" fill="url(#p1)" />

  <!-- Right square with bounding box tiles -->
  <rect x="110" y="10" width="80" height="80" fill="url(#p2)" />
</svg>
```

pattern
-------

`<pattern>` の場合、 `patternUnits` は要素のジオメトリープロパティ（`x`, `y`, `width (en-US)`, `height (en-US)`）に使用する座標系を定義します。

|  |  |
| --- | --- |
| 値 | `userSpaceOnUse` | `objectBoundingBox` |
| 既定値 | `objectBoundingBox` |
| アニメーション | 可 |

`userSpaceOnUse`

この値は、ジオメトリープロパティのすべての座標が、パターンが適用されたときに定義されたユーザー座標系を参照することを示します。

`objectBoundingBox`

この値は、ジオメトリープロパティのすべての座標が、パターンが適用される要素のバウンディングボックスの分数またはパーセント値を表します。バウンディングボックスは `<pattern>` のコンテンツが "`0 0 1 1`" `viewBox` にバインドされているのと同じと考えることができます。

仕様書
---

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # PatternElementPatternUnitsAttribute |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


writing-mode - SVG: スケーラブルベクターグラフィック

writing-mode
============

**`writing-mode`** 属性は、 `<text>` 要素の最初のインライン進行方向が左から右、右から左、上から下のいずれであるかを指定します。 `writing-mode` 属性は `<text>` 要素にのみ適用されます。 `<tspan>`, `<tref>` (en-US), `<altGlyph>`, `<textPath>` (en-US) サブ要素には無視されます。 (なお、インライン進行方向は、 Unicode 双方向アルゴリズムとプロパティ `direction (en-US)` および `unicode-bidi (en-US)` により、 `<text>` 要素内で変更される可能性があることに注意してください)。

**メモ:** プレゼンテーション属性なので、 `writing-mode` は CSS プロパティとして使用することができます。詳しくは CSS の `writing-mode` プロパティを参照してください。

プレゼンテーション属性として、どの要素にも適用できますが、 `<altGlyph>`, `<text>`, `<textPath>` (en-US), `<tref>` (en-US), `<tspan>` の 5 つの要素にのみ効果があります。

使用上の注意
------

|  |  |
| --- | --- |
| 既定値 | `horizontal-tb` |
| 値 | `horizontal-tb` | `vertical-rl` |
 `vertical-lr` |
| アニメーション可能 | はい |

`horizontal-tb`

この値はブロックのフロー方向を上から下に定義します。書字方向と文字の方向は共に水平方向です。

`vertical-rl`

この値はブロックのフロー方向を右から左に定義します。書字方向と文字の方向は共に垂直方向です。

`vertical-lr`

この値はブロックのフロー方向を左から右に定義します。書字方向と文字の方向は共に垂直方向です。

仕様書
---

| Specification |
| --- |
| CSS Writing Modes Level 4 # block-flow |
| Scalable Vector Graphics (SVG) 2 # WritingModeProperty |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `CSS writing-mode`


d - SVG: スケーラブルベクターグラフィック

d
=

**`d`** 属性は描かれるパスを定義します。

パスの定義はパスコマンドのリストで、各コマンドはコマンド文字とコマンドへのパラメータを示す数値から構成されます。コマンドの詳細は以下になります。

３つの要素がこの属性を有します： `<path>`, `<glyph>`, `<missing-glyph>`

`d` は プレゼンテーション属性 のため、CSS プロパティとして使用 することもできます。

例
-
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <path
 fill="none"
 stroke="red"
 d="M 10,30
 A 20,20 0,0,1 50,30
 A 20,20 0,0,1 90,30
 Q 90,60 50,90
 Q 10,60 10,30 z" />
</svg>
```

path
----

`<path>`要素に対しては、`d`属性は、描かれるパスを定義するパスコマンドの並びを含む文字列です。

|  |  |
| --- | --- |
| 値 | **<string>** |
| 既定値 | *none* |
| アニメーション | Yes |

glyph
-----

**警告:** SVG2 において、`<glyph>` (en-US)は非推奨であり、用いるべきではありません。

`<glyph>` (en-US)要素に対しては、`d`属性はグリフのアウトライン形状を定義するパスコマンドの並びを含む文字列です。

|  |  |
| --- | --- |
| 値 | **<string>** |
| 既定値 | *none* |
| アニメーション | Yes |

**メモ:** 原点(座標`0`, `0`)は通常、コンテキストの *左上の角* です。しかし、`<glyph>` (en-US)要素は、それ自身の原点を文字ボックスの *左下* に持ちます。

missing-glyph
-------------

**警告:** SVG2 において、`<missing-glyph>` (en-US)は非推奨であり、用いるべきではありません。

`<missing-glyph>` (en-US)要素に対しては、`d`属性は、グリフのアウトライン形状を定義するパスコマンドの並びを含んだ文字列です。

|  |  |
| --- | --- |
| 値 | **<string>** |
| 既定値 | *none* |
| アニメーション | Yes |

CSS プロパティとして d を使用
------------------

`d` は プレゼンテーション属性 であるため、CSS を使用して変更することもできます。
 このプロパティは、path() または `none` のいずれかをとります。

 以下の例は、要素の上にマウスを置くと新しいパスを適用する方法を示しています。
 新しいパスは古いパスと同じですが、ハートを横切る線が追加されます。

```css
html,
body,
svg {
  height: 100%;
}

/\* This path is displayed on hover\*/
#svg\_css\_ex1:hover path {
  d: path(
    "M10,30 A20,20 0,0,1 50,30 A20,20 0,0,1 90,30 Q90,60 50,90 Q10,60 10,30 z M5,5 L90,90"
  );
}
```

```html
<svg id="svg\_css\_ex1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <path
 fill="none"
 stroke="red"
 d="M 10,30
 A 20,20 0,0,1 50,30
 A 20,20 0,0,1 90,30
 Q 90,60 50,90
 Q 10,60 10,30 z
 " />
</svg>
```

パスコマンド
------

パスコマンドは、描かれるパスの定義を指定します。各コマンドは、コマンド文字とコマンドパラメータを示す数値で構成されます。

SVG では、6 つのタイプのパスコマンドを定義しており、全部で 20 個のコマンドがあります:

* MoveTo: `M`, `m`
* LineTo: `L`, `l`, `H`, `h`, `V`, `v`
* 3 次ベジエ曲線: `C`, `c`, `S`, `s`
* 2 次ベジエ曲線: `Q`, `q`, `T`, `t`
* 楕円円弧曲線: `A`, `a`
* ClosePath: `Z`, `z`

**メモ:** コマンドは *ケースセンシティブ（大小文字の区別あり）* です. 大文字のコマンドは絶対座標を指定し、これに対して小文字のコマンドは現在位置からの相対座標を指定します。

コマンドへの引数として負値を指定することは常に可能です:

* 負の角度は反時計回りとなります;
* *絶対値* での負の *x* と *y* の値は反転座標と解釈されます;
* *相対値* での負の *x* の値は左へ移動、相対値での負の *y* の値は上方向へ移動します。
### MoveTo パスコマンド

*MoveTo* での指定は、筆記用具を持ち上げ他の位置で下ろす動作と考えられます―言い換えると、*現在位置* (*Po*; {*xo*, *yo*}) の移動です。*Po* と新しい *現在位置* (*Pn*; {*xn*, *yn*}) との間には線は描かれません。

| コマンド | パラメータ | 説明 |
| --- | --- | --- |
| M | (`x`, `y`)+ |
*現在位置* を座標
 `x`,`y` へ移動します。後続する任意個の座標の組は暗黙的に絶対座標での LineTo(`L`)コマンドと解釈されます(*以下を参照*)。

**形式:** Pn = {`x`, `y`} |
| m | (`dx`, `dy`)+ | *現在位置* を最後に把握されたパス位置からの `dx` を x 軸方向、`dy` を y 軸に沿った並進として移動します。後続する任意個の座標の組は暗黙的に相対座標での LineTo(`l`)コマンドとして解釈されます(*以下を参照*)。

**形式:** Pn = {xo
 + `dx`, yo + `dy`}
  |

#### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  <path
 fill="none"
 stroke="red"
 d="M 10,10 h 10
 m 0,10 h 10
 m 0,10 h 10
 M 40,20 h 10
 m 0,10 h 10
 m 0,10 h 10
 m 0,10 h 10
 M 50,50 h 10
 m-20,10 h 10
 m-20,10 h 10
 m-20,10 h 10" />
</svg>
```

### LineTo パスコマンド

*LineTo* は、*現在位置* (*Po*; {*xo*, *yo*}) から *終端位置* (*Pn*; {*xn*, *yn*}) への直線を指定されたパラメータに基づいて描きます。*終端位置* (*Pn*) は、次のコマンドでの *現在位置* (*Po′*) となります。

| コマンド | パラメータ | 説明 |
| --- | --- | --- |
| L | (`x`, `y`)+ | *現在位置* から `x`,`y` で指定される *終端位置* へ直線を描きます。後続する任意個の座標の組は暗黙的に絶対座標での LineTo (`L`) コマンドと解釈されます。

**形式:** Po′ =
 Pn = {`x`, `y`}
  |
| l | (`dx`, `dy`)+ | *現在位置* から、*現在位置* に対する x-軸方向に`dx` 、y-軸方向に `dy` で表される *終端位置* への直線を描きます。後続する任意個の座標の組は、暗黙的に相対座標での LineTo (`l`) コマンドと解釈されます(*以下を参照*)。

**形式:** Po′ =
 Pn = {xo +
 `dx`, yo + `dy`}
  |
| H | `x`+ | *現在位置*から、パラメータ`x`と*現在位置*の`y`座標で指定される*終端座標*までの水平線を描きます。後続する任意個の値は、暗黙的に絶対座標での水平線用の LineTo (`H`)コマンドと解釈されます。

**形式:** Po′ =
 Pn = {`x`, yo}
  |
| h | `dx`+ | *現在位置*から、*現在位置*からの x-軸方向への`dx`の並進と*現在位置*の `y` 座標で指定される*終端位置*までの水平線を描きます。後続する任意個の値は、暗黙的に相対座標での水平線用の LineTo (`h`) コマンドと解釈されます。

**形式:** Po′ =
 Pn = {xo +
 `dx`, yo}
  |
| V | `y`+ | *現在位置*から、パラメータ `y` と*現在位置*の `x` 座標で指定される*終端座標*までの垂直線を描きます。後続する任意個の値は、暗黙的に絶対座標での垂直線用の LineTo (`V`)コマンドと解釈されます。

**形式:** Po′ =
 Pn = {xo, `y`}
  |
| v | `dy`+ | *現在位置*から、*現在位置*からの y-軸方向への `dy` の並進と*現在位置*の `x` 座標で指定される*終端位置*までの垂直線を描きます。後続する任意個の値は、暗黙的に相対座標での垂直線用の LineTo (`v`)コマンドと解釈されます。

**形式:** Po′ =
 Pn = {xo, yo + `dy`}
  |

#### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- 絶対座標でのLineToコマンド -->
  <path
 fill="none"
 stroke="red"
 d="M 10,10
 L 90,90
 V 10
 H 50" />

  <!-- 相対座標でのLineToコマンド -->
  <path
 fill="none"
 stroke="red"
 d="M 110,10
 l 80,80
 v -80
 h -40" />
</svg>
```

### 3 次ベジエ曲線

*3 次ベジエ曲線* は 4 点で定義される滑らかな曲線です:

*開始位置 (現在位置)*

(Po = {xo, yo})

*終端位置*

(Pn = {xn, yn})

*開始制御点*

 (Pcs = {xcs, ycs})
 (曲線の開始点近くの曲率を制御します)

*終端制御点*

 (Pce = {xce, yce})
 (曲線の終端近くの曲率を制御します)

描画後に、*終端位置* (*Pn*) は、次のコマンドに対する *現在位置* (*Po′*) となります。

| コマンド | パラメータ | 説明 |
| --- | --- | --- |
| C | (`x1`,`y1`, `x2`,`y2`, `x`,`y`)+ | *開始位置*から、`x`,`y`で指定される*終端位置*までの3次ベジエ曲線を描きます。*開始制御点*は`x1`,`y1`で指定され、*終端制御点*は`x2`,`y2`で指定されます。後続する任意個の3つ組の座標は、暗黙的な絶対座標での3次ベジエ曲線(`C`)コマンドへのパラメータと解釈されます。

形式:
Po′ = Pn = {`x`, `y`} ;Pcs = {`x1`, `y1`} ;Pce = {`x2`, `y2`}
 |
| c | (`dx1`,`dy1`, `dx2`,`dy2`, `dx`,`dy`)+ |
*開始位置*から、*開始位置*からのx-軸方向に`dx`,y-軸方向に`dy`とした並進となる*終端位置*までの3次ベジエ曲線を描きます。*開始制御点*は、*開始点*
 (曲線の開始位置)をx-軸方向に`dx1`,y-軸方向に`dy1`と並進した点です。*終端制御点*は*現在位置*
 (曲線の開始位置)を、x-軸方向に`dx2`,y-軸方向に`dy2`と並進した点です。後続する任意個の3つ組の座標は、暗黙的に相対座標での3次ベジエ曲線
 (`c`) コマンドと解釈されます。

形式:

Po′ = Pn = {xo
 + `dx`, yo + `dy`} ;Pcs = {xo +
 `dx1`, yo + `dy1`} ;Pce = {xo +
 `dx2`, yo + `dy2`}

 |
| S | (`x2`,`y2`, `x`,`y`)+ | *開始位置*から、`x`,`y`で指定される*終端位置*までの滑らかな3次ベジエ曲線を描きます。*終端制御点*は、`x2`,`y2`で指定されます。*開始制御点*は、直前の曲線コマンドの*終端制御点*が鏡映されます。もし直前のコマンドが3次ベジエ曲線でない場合は、*開始制御点*は曲線の開始位置(*現在座標*)と同一となります。後続する任意個の座標の組は、暗黙的に絶対座標での滑らかな3次ベジエ曲線(`S`)コマンドへのパラメータと解釈されます。 |
| s | (`dx2`,`dy2`, `dx`,`dy`)+ | *開始位置*から、*現在位置*からのx-軸方向への`dx`,y-軸方向への`dy`への並進で表される*終端位置*までの滑らかな3次ベジエ曲線を描きます。*終端制御点*は、*現在位置*(曲線の開始点)をx-軸方向への`dx2`とy-軸方向への`dy2`だけ並進させた点です。*開始制御点*は、直前の曲線コマンドの*終端位置*が鏡映されます。もし直前のコマンドが3次ベジエ曲線でない場合は、*開始制御点*は曲線の開始位置(*現在座標*)と同一となります。後続する任意個の座標の組は、暗黙的に相対座標での滑らかな3次ベジエ曲線
 (`s`) コマンドと解釈されます。
  |

#### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg
 viewBox="0 0 200 100"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- 絶対座標での3次ベジエ曲線 -->
  <path
 fill="none"
 stroke="red"
 d="M 10,90
 C 30,90 25,10 50,10
 S 70,90 90,90" />

  <!-- 相対座標での3次ベジエ曲線 -->
  <path
 fill="none"
 stroke="red"
 d="M 110,90
 c 20,0 15,-80 40,-80
 s 20,80 40,80" />

  <!-- 曲線の頂点と制御点の明示 -->
  <g id="ControlPoints">
    <!-- 1つ目の3次コマンドへの制御点 -->
    <line x1="10" y1="90" x2="30" y2="90" stroke="lightgrey" />
    <circle cx="30" cy="90" r="1.5" />

    <line x1="50" y1="10" x2="25" y2="10" stroke="lightgrey" />
    <circle cx="25" cy="10" r="1.5" />

    <!-- 2つめの円滑化制御点 (1つ目は暗黙的) -->
    <line
 x1="50"
 y1="10"
 x2="75"
 y2="10"
 stroke="lightgrey"
 stroke-dasharray="2" />
    <circle cx="75" cy="10" r="1.5" fill="lightgrey" />

    <line x1="90" y1="90" x2="70" y2="90" stroke="lightgrey" />
    <circle cx="70" cy="90" r="1.5" />

    <!-- 曲線上の頂点 -->
    <circle cx="10" cy="90" r="1.5" />
    <circle cx="50" cy="10" r="1.5" />
    <circle cx="90" cy="90" r="1.5" />
  </g>
  <use href="#ControlPoints" x="100" />
</svg>
```

### 2 次ベジエ曲線

*2 次ベジエ曲線* は 3 点で定義される滑らかな曲線です:

*開始座標(現在位置)*

*Po* = {*xo*, *yo*}

*終端座標*

*Pn* = {*xn*, *yn*}

*制御点*

*Pc* = {*xc*, *yc*}
 (曲率を制御します)

描画後に、*終端位置* (*Pn*) は、次のコマンドに対する *現在位置* (*Po′*)となります。

| コマンド | パラメータ | 説明 |
| --- | --- | --- |
| Q | (`x1`,`y1`, `x`,`y`)+ |
*開始位置*から`x`,`y`で指定される*終端位置*までの2次ベジエ曲線を描きます。*制御点*は`x1`,`y1`で指定されます。後続する任意個の座標の組は、暗黙的に絶対座標での4次ベジエ曲線
 (`Q`) コマンドへのパラメータと解釈されます。

**形式:**
Po′ = Pn = {`x`, `y`} ;Pc = {`x1`, `y1`}
 |
| q | (`dx1`,`dy1`, `dx`,`dy`)+ |
*開始位置*から、*開始位置*からのx-軸方向に`dx`,y-軸方向に`dy`とした並進となる*終端位置*までの2次ベジエ曲線を描きます。*制御点*は、*開始点*
 (曲線の開始位置)をx-軸方向に`dx1`,y-軸方向に`dy1`と並進した点です。後続する任意個の座標は、暗黙的に相対座標での2次ベジエ曲線
 (`q`) コマンドへのパラメータと解釈されます。

形式:

Po′ = Pn = {xo
 + `dx`, yo + `dy`} ;Pc = {xo +
 `dx1`, yo + `dy1`}

 |
| T | (`x`,`y`)+ | *開始位置*から`x`,`y`で指定される*終端位置*までの滑らかな2次ベジエ曲線を描きます。*制御点*は、直前の曲線コマンドの*終端制御点*が反映されます。もし直前のコマンドが2次ベジエ曲線でない場合は、*制御点*は曲線の開始位置(*現在座標*)と同一となります。後続する任意個の座標の組は、暗黙的に絶対座標での滑らかな2次ベジエ曲線(`T`)コマンドへのパラメータと解釈されます。

形式:
Po′ = Pn = {`x`, `y`}
 |
| t | (`dx`,`dy`)+ |
*開始位置*から、*現在位置*からのx-軸方向への`dx`,y-軸方向への`dy`への並進で表される*終端位置*までの滑らかな3次ベジエ曲線を描きます。*制御点*は、直前の曲線コマンドの*制御点*が反映されます。もし直前のコマンドが2次ベジエ曲線でない場合は、*制御点*は曲線の開始位置(*現在座標*)と同一となります。後続する任意個の座標の組は、暗黙的に相対座標での滑らかな2次ベジエ曲線
 (`t`) コマンドへのパラメータと解釈されます。

形式:

Po′ = Pn = {xo
 + `dx`, yo + `dy`}

 |

#### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg
 viewBox="0 0 200 100"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- 暗黙的な繰り返しによる2次ベジエ曲線 -->
  <path
 fill="none"
 stroke="red"
 d="M 10,50
 Q 25,25 40,50
 t 30,0 30,0 30,0 30,0 30,0" />

  <!-- 曲線の頂点と制御点の明示 -->
  <g>
    <polyline points="10,50 25,25 40,50" stroke="rgba(0,0,0,.2)" fill="none" />
    <circle cx="25" cy="25" r="1.5" />

    <!-- 曲線上の頂点 -->
    <circle cx="10" cy="50" r="1.5" />
    <circle cx="40" cy="50" r="1.5" />

    <g id="SmoothQuadraticDown">
      <polyline
 points="40,50 55,75 70,50"
 stroke="rgba(0,0,0,.2)"
 stroke-dasharray="2"
 fill="none" />
      <circle cx="55" cy="75" r="1.5" fill="lightgrey" />
      <circle cx="70" cy="50" r="1.5" />
    </g>

    <g id="SmoothQuadraticUp">
      <polyline
 points="70,50 85,25 100,50"
 stroke="rgba(0,0,0,.2)"
 stroke-dasharray="2"
 fill="none" />
      <circle cx="85" cy="25" r="1.5" fill="lightgrey" />
      <circle cx="100" cy="50" r="1.5" />
    </g>

    <use href="#SmoothQuadraticDown" x="60" />
    <use href="#SmoothQuadraticUp" x="60" />
    <use href="#SmoothQuadraticDown" x="120" />
  </g>
</svg>
```

### 楕円円弧曲線

*楕円円弧曲線* は楕円の一部として定義される曲線です。ベジエ曲線よりも楕円円弧曲線を用いるほうが、高度な正則曲線の描画が容易になることが多くあります。

| コマンド | パラメータ | 説明 |
| --- | --- | --- |
| A |
 (`rx` `ry`
`角度` `大円弧フラグ<`
`掃引フラグ` `x`
`y`)+
  | 現在位置から`x`,`y`座標へ円弧を描きます。楕円の中心はコマンドへの他のパラメータに基づいて自動的に決定されます。:* `rx`と`ry`は楕円の半径です;
* `角度`はx-軸に対する楕円の角度（度単位）です;
* `大円弧フラグ`と`掃引フラグ`は、他のパラメータによって描画可能な4つの可能な円弧のうち、どの円弧を描くかを選択可能にします。
    + `大円弧フラグ`では大きい円弧 (**1**)
     を描くか、小さい円弧 (**0**) を描くかを選択し,
    + `掃引フラグ`では時計回りの円弧 (**1**)
     を描くか、反時計周りの円弧 (**0**)
     を描くかを選択します。

座標 `x`,`y`
 は、次のコマンドに対する新しい現在位置となります。すべての後続するパラメータの組は、暗黙的に絶対座標での円弧曲線
 (`A`) コマンドに対するものと解釈されます。
  |
| a |
 (`rx` `ry`
`(`rx` `ry` `角度```大円弧フラグ`
`掃引フラグ` `dx`
`dy`)+
  | 現在位置から、現在位置からのx-軸方向への`dx`とy-軸方向への`dy`への並進で指定される点へ円弧を描きます。楕円の中心はコマンドへの他のパラメータに基づいて自動的に決定されます。:* `rx`と`ry`は楕円の半径です;
* `角度`はx-軸に対する楕円の角度（度単位）です;
* `大円弧フラグ`と`掃引フラグ`は、他のパラメータによって描画可能な4つの可能な円弧のうち、どの円弧を描くかを選択可能にします。
    + `大円弧フラグ`では大きい円弧 (**1**)
     を描くか、小さい円弧 (**0**) を描くかを選択し,
    + `掃引フラグ`では時計回りの円弧 (**1**)
     を描くか、反時計周りの円弧 (**0**)
     を描くかを選択します。

`dx`と`dy`で並進された座標`X`,`Y`は、次のコマンドに対する新しい現在位置となります。すべての後続するパラメータの組は、暗黙的に相対座標での円弧曲線
 (`a`) コマンドに対するものと解釈されます。
  |

#### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
  <!-- 円弧への２つのフラグの効果により各円弧が描画される -->
  <path
 fill="none"
 stroke="red"
 d="M 6,10
 A 6 4 10 1 0 14,10" />

  <path
 fill="none"
 stroke="lime"
 d="M 6,10
 A 6 4 10 1 1 14,10" />

  <path
 fill="none"
 stroke="purple"
 d="M 6,10
 A 6 4 10 0 1 14,10" />

  <path
 fill="none"
 stroke="pink"
 d="M 6,10
 A 6 4 10 0 0 14,10" />
</svg>
```

### ClosePath

*ClosePath* は、*現在位置* からパスの開始位置までの直線描画を指定します。

| コマンド | パラメータ | 説明 |
| --- | --- | --- |
| Z, z |  | パスの最終位置とその初期位置とを接続することで、現在のサブパスを閉じます。もし、2 つの点が異なる座標の場合は、2 点間に直線が描かれます。 |

**メモ:** *ClosePath* によって生じる形状は、他のコマンドを用いて初期位置へ線を描いて閉じた場合とは異なる場合があります。これは、描線の終端が互いに接続されるためです (`stroke-linejoin` 設定)を参照のこと。 単に同じ座標に配置されるわけではありません。

#### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 -1 30 11" xmlns="http://www.w3.org/2000/svg">
  <!--
 初期位置と異なる終端位置による
 パスで描かれる開いた形状
 -->
  <path
 stroke="red"
 d="M 5,1
 l -4,8 8,0" />

  <!--
 初期位置と一致する終端位置による
 パスで描かれる開いた形状
 -->
  <path
 stroke="red"
 d="M 15,1
 l -4,8 8,0 -4,-8" />

  <!--
 初期位置と異なる終端位置による
 パスで描かれる閉じた形状
 -->
  <path
 stroke="red"
 d="M 25,1
 l -4,8 8,0
 z" />
</svg>
```

仕様
--

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # DProperty |
| Scalable Vector Graphics (SVG) 1.1 (Second Edition) # GlyphElementDAttribute |
| Scalable Vector Graphics (SVG) 1.1 (Second Edition) # DAttribute |

ブラウザー互換性
--------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


fill - SVG: スケーラブルベクターグラフィック

fill
====

**`fill`** 属性には使われ方により 2 つの意味があります. 1 つは図形やテキストに使われた場合で，その要素を塗りつぶす色 (*またはグラデーションやパターンなどの SVG ペイント サーバー*) を意味します．もう 1 つはアニメーションに使われた場合で，そのアニメーションの最終状態を定義します．

この属性は次の SVG 要素で使用できます。

* `<circle>`
* `<ellipse>`
* `<path>`
* `<polygon>`
* `<polyline>`
* `<rect>`
* `<text>`
* `<textPath>` (en-US)
* `<tref>` (en-US)
* `<tspan>`

アニメーションとしては次の要素で使われています: `<animate>`, `<animateMotion>`, `<animateTransform>`, `<set>`.

例
-
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 300 100" xmlns="http://www.w3.org/2000/svg">
  <!-- Simple color fill -->
  <circle cx="50" cy="50" r="40" fill="pink" />

  <!-- Fill circle with a gradient -->
  <defs>
    <radialGradient id="myGradient">
      <stop offset="0%" stop-color="pink" />
      <stop offset="100%" stop-color="black" />
    </radialGradient>
  </defs>

  <circle cx="150" cy="50" r="40" fill="url(#myGradient)" />

  <!--
 Keeping the final state of an animated circle
 which is a circle with a radius of 40.
 -->
  <circle cx="250" cy="50" r="20">
    <animate
 attributeType="XML"
 attributeName="r"
 from="0"
 to="40"
 dur="5s"
 fill="freeze" />
  </circle>
</svg>
```

animate
-------

`<animate>` は、`fill` はアニメーションの最終状態を定義します。

|  |  |
| --- | --- |
| 値 | `freeze` (*Keep the state of the last animation frame*) | `remove` (*Keep the state of the first animation frame*) |
| 既定値 | `remove` |
| アニメーション | No |

animateMotion
-------------

`<animateMotion>` は、`fill` はアニメーションの最終状態を定義します。

|  |  |
| --- | --- |
| 値 | `freeze` (*Keep the state of the last animation frame*) | `remove` (*Keep the state of the first animation frame*) |
| 既定値 | `remove` |
| アニメーション | No |

animateTransform
----------------

`<animateTransform>` は、`fill` はアニメーションの最終状態を定義します。

|  |  |
| --- | --- |
| 値 | `freeze` (*Keep the state of the last animation frame*) | `remove` (*Keep the state of the first animation frame*) |
| 既定値 | `remove` |
| アニメーション | No |

circle
------

`<circle>` は、`fill` は円の色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

ellipse
-------

`<ellipse>` は、`fill` は楕円の色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

path
----

`<path>` は、`fill` は図形の内部の色を定義するプレゼンテーション属性です。 (*内部は `fill-rule (en-US)` 属性によって定義されます*)

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

polygon
-------

`<polygon>` は、`fill` は図形の内部の色を定義するプレゼンテーション属性です。 (*内部は `fill-rule (en-US)` 属性によって定義されます*)

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

polyline
--------

`<polyline>` は、`fill` は図形の内部の色を定義するプレゼンテーション属性です。 (*内部は `fill-rule (en-US)` 属性によって定義されます*)

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

rect
----

`<rect>` は、`fill` は四角形の色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

set
---

`<set>` は、`fill` はアニメーションの最終状態を定義します。

|  |  |
| --- | --- |
| 値 | `freeze` (*Keep the state of the last animation frame*) | `remove` (*Keep the state of the first animation frame*) |
| 既定値 | `remove` |
| アニメーション | No |

text
----

`<text>` は、`fill` はテキストの色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

textPath
--------

`<textPath>` (en-US) は、`fill` はテキストの色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

tref
----

**警告:** As of SVG2 `<tref>` (en-US) is deprecated and shouldn't be used.

`<tref>` (en-US) は、`fill` はテキストの色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

tspan
-----

`<tspan>` は、`fill` はテキストの色を定義するプレゼンテーション属性です。

|  |  |
| --- | --- |
| 値 | **<paint>** |
| 既定値 | `black` |
| アニメーション | Yes |

**メモ:** プレゼンテーション属性として `fill` を CSS プロパティとして使用できます。

仕様書
---

| Specification |
| --- |
| SVG Animations Level 2 # FillAttribute |
| Scalable Vector Graphics (SVG) 2 # SpecifyingFillPaint |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


cx - SVG: スケーラブルベクターグラフィック

cx
==

**`cx`** 属性は中心の x-座標を定義します。

この属性は次の SVG 要素で使用できます。

* `<circle>`
* `<ellipse>`
* `<radialGradient>`
例
-
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 300 100" xmlns="http://www.w3.org/2000/svg">
  <radialGradient cx="25%" id="myGradient">
    <stop offset="0" stop-color="white" />
    <stop offset="100%" stop-color="black" />
  </radialGradient>

  <circle cx="50" cy="50" r="45" />
  <ellipse cx="150" cy="50" rx="45" ry="25" />
  <rect x="205" y="5" width="90" height="90" fill="url(#myGradient)" />
</svg>
```

circle
------

`<circle>`に対して、`cx`は、図形の x-軸の中心を定義します。

|  |  |
| --- | --- |
| 値 | `<length-percentage>` |
| 既定値 | `0` |
| アニメーション | Yes |

**メモ:** SVG2 として開始する場合には、`cx`は*ジオメトリプロパティ*です。これは本属性が円への CSS プロパティとしても利用可能であることを意味します。

ellipse
-------

`<ellipse>`に対して、`cx`は、図形の x-軸の中心を定義します。

|  |  |
| --- | --- |
| 値 | `<length-percentage>` |
| 既定値 | `0` |
| アニメーション | はい |

**メモ:** SVG2 として開始する場合には、`cx`は*ジオメトリプロパティ*です。これは本属性が楕円への CSS プロパティとしても利用可能であることを意味します。

radialGradient
--------------

`<radialGradient>`に対して、`cx`は、放射状勾配の終端円の x-軸の中心を定義します。

|  |  |
| --- | --- |
| 値 | `<length>` |
| 既定値 | `50%` |
| アニメーション | はい |

### 例
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 34 10" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient cx="0" id="myGradient000">
      <stop offset="0%" stop-color="gold" />
      <stop offset="50%" stop-color="green" />
      <stop offset="100%" stop-color="white" />
    </radialGradient>

    <radialGradient cx="50%" id="myGradient050">
      <stop offset="0%" stop-color="gold" />
      <stop offset="50%" stop-color="green" />
      <stop offset="100%" stop-color="white" />
    </radialGradient>

    <radialGradient cx="100%" id="myGradient100">
      <stop offset="0%" stop-color="gold" />
      <stop offset="50%" stop-color="green" />
      <stop offset="100%" stop-color="white" />
    </radialGradient>
  </defs>

  <rect
 x="1"
 y="1"
 width="8"
 height="8"
 fill="url(#myGradient000)"
 stroke="black" />
  <rect
 x="13"
 y="1"
 width="8"
 height="8"
 fill="url(#myGradient050)"
 stroke="black" />
  <rect
 x="25"
 y="1"
 width="8"
 height="8"
 fill="url(#myGradient100)"
 stroke="black" />
</svg>
```

仕様
--

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # CX |
| Scalable Vector Graphics (SVG) 2 # RadialGradientElementCXAttribute |

関連情報
----

* cy
* r


y - SVG: スケーラブルベクターグラフィック

y
=

**`y`** 属性はユーザー座標系の Y 軸の座標を定義します。

この属性は、以下の SVG 要素で使用することができます。

* `<altGlyph>`
* `<cursor>` (en-US)
* `<feBlend>` (en-US)
* `<feColorMatrix>`
* `<feComponentTransfer>` (en-US)
* `<feComposite>` (en-US)
* `<feConvolveMatrix>` (en-US)
* `<feDiffuseLighting>` (en-US)
* `<feDisplacementMap>` (en-US)
* `<feDropShadow>`
* `<feFlood>` (en-US)
* `<feFuncA>` (en-US)
* `<feFuncB>` (en-US)
* `<feFuncG>` (en-US)
* `<feFuncR>` (en-US)
* `<feGaussianBlur>` (en-US)
* `<feImage>` (en-US)
* `<feMerge>` (en-US)
* `<feMergeNode>` (en-US)
* `<feMorphology>`
* `<feOffset>` (en-US)
* `<fePointLight>` (en-US)
* `<feSpecularLighting>` (en-US)
* `<feSpotLight>` (en-US)
* `<feTile>` (en-US)
* `<feTurbulence>` (en-US)
* `<filter>` (en-US)
* `<foreignObject>`
* `<glyphRef>` (en-US)
* `<image>`
* `<mask>`
* `<pattern>`
* `<rect>`
* `<svg>`
* `<symbol>` (en-US)
* `<text>`
* `<tref>` (en-US)
* `<tspan>`
* `<use>`
例
-
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 100 300" xmlns="http://www.w3.org/2000/svg">
  <rect y="20" x="20" width="60" height="60" />
  <rect y="120" x="20" width="60" height="60" />
  <rect y="220" x="20" width="60" height="60" />
</svg>
```

altGlyph
--------

**警告:** SVG2 では `<altGlyph>` は非推奨であるため、使用しないでください。

`<altGlyph>` の場合、 `y` は代替文字の Y 軸の座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 のリスト
  |
| 既定値 | *なし* |
| アニメーション | 可 |

feBlend
-------

`<feBlend>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feColorMatrix
-------------

`<feColorMatrix>` の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feComponentTransfer
-------------------

`<feComponentTransfer>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feComposite
-----------

`<feComposite>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feConvolveMatrix
----------------

`<feConvolveMatrix>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feDiffuseLighting
-----------------

`<feDiffuseLighting>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feDisplacementMap
-----------------

`<feDisplacementMap>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feDropShadow
------------

`<feDropShadow>` の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feFlood
-------

`<feFlood>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feFuncA
-------

`<feFuncA>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feFuncB
-------

`<feFuncB>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feFuncG
-------

`<feFuncG>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feFuncR
-------

`<feFuncR>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feGaussianBlur
--------------

`<feGaussianBlur>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feImage
-------

`<feImage>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feMerge
-------

`<feMerge>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feMergeNode
-----------

`<feMergeNode>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feMorphology
------------

`<feMorphology>` の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feOffset
--------

`<feOffset>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

fePointLight
------------

`<fePointLight>` (en-US) の場合、 `y` は `<filter>` (en-US) 要素の `primitiveUnits (en-US)` 属性で定義される座標系での光源の Y 位置を定義します。

|  |  |
| --- | --- |
| 値 | **<number>** |
| 既定値 | `0` |
| アニメーション | 可 |

feSpecularLighting
------------------

`<feSpecularLighting>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feSpotLight
-----------

`<feSpotLight>` (en-US) の場合、 `y` は `<filter>` (en-US) 要素の `primitiveUnits (en-US)` 属性で定義される座標系での光源の Y 位置を定義します。

|  |  |
| --- | --- |
| 値 | **<number>** |
| 既定値 | `0` |
| アニメーション | 可 |

feTile
------

`<feTile>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

feTurbulence
------------

`<feTurbulence>` (en-US) の場合、 `y` はこのプリミティブの描画領域における最小の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0%` |
| アニメーション | 可 |

filter
------

`<filter>` (en-US) の場合、 `y` はこのフィルターの描画領域における左上隅の Y 座標をを定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `-10%` |
| アニメーション | 可 |

foreignObject
-------------

`<foreignObject>` の場合、 `y` はこのフィルターの描画領域における左上隅の Y 座標をを定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0` |
| アニメーション | 可 |

**メモ:** SVG2 からは、`y` は*幾何プロパティ*であり、この属性は `<foreignObject>` の CSS プロパティとして使用することもできます。

glyphRef
--------

**警告:** SVG2 では `<glyphRef>` (en-US) は非推奨であり、使用すべきではありません。

`<glyphRef>` (en-US) の場合、 `y` が文字の Y 軸の座標を定義します。

|  |  |
| --- | --- |
| 値 | **<number>** |
| 既定値 | *なし* |
| アニメーション | 可 |

image
-----

`<image>` の場合、 `y` はこの画像の左上隅の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0` |
| アニメーション | 可 |

**メモ:** SVG2 からは、`y` は*幾何プロパティ*であり、この属性は画像用の CSS プロパティとしても使用できます。

mask
----

`<mask>` の場合、 `y` は、その影響する領域の左上隅の Y 座標を定義します。この属性の正確な効果は、 `maskUnits (en-US)` 属性に影響されます。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `-10%` |
| アニメーション | 可 |

pattern
-------

`<pattern>` の場合、 `y` はタイルパターンの左上隅の Y 座標を定義します。この属性の正確な効果は、 `patternUnits` と `patternTransform (en-US)` 属性に影響されます。

|  |  |
| --- | --- |
| 値 | **<length>** |
| 既定値 | `0` |
| アニメーション | 可 |

rect
----

`<rect>` の場合、 `y` は図形の左上隅の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0` |
| アニメーション | 可 |

**メモ:** SVG2 からは、`y` は*幾何プロパティ*であり、この属性は矩形の CSS プロパティとして使用することもできる。

svg
---

`<svg>` の場合、 `y` はそのビューポートの左上隅の Y 座標を定義します。

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0` |
| アニメーション | 可 |

**メモ:** SVG2 からは、`y` は*幾何プロパティ*であり、この属性は `<svg>` の CSS プロパティとして使用することもできます。

text
----

`<text>` にある値が 1 つの場合、 `y` は*コンテンツテキストの位置*を配置しなければならない Y 座標を定義します。*コンテンツテキストの位置*は、通常、テキストの最初の行のベースライン上の点です。正確な*コンテンツテキスト位置*は、 `text-anchor (en-US)` や `direction` など、他のプロパティの影響を受けます。

複数の値がある場合、`y` はテキストから個々の文字への Y 座標を定義します。値が文字よりも少ない場合、残りの文字は最後に配置された文字と一直線上に配置されます。値が文字よりも多い場合は、余分な値は無視されます。

|  |  |
| --- | --- |
| 値 |
 (**<length>**
 |
 **<percentage>**) のリスト
  |
| 既定値 | `0` |
| アニメーション | 可 |
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- horizontal line to materialized the text base line -->
  <line x1="0" y1="40%" x2="100%" y2="40%" />
  <line x1="0" y1="60%" x2="100%" y2="60%" />
  <line x1="0" y1="80%" x2="100%" y2="80%" />

  <!-- vertical line to materialized the x positioning -->
  <line x1="5%" y1="0" x2="5%" y2="100%" />
  <line x1="55%" y1="0" x2="55%" y2="100%" />

  <!-- y with a single value -->
  <text y="40%" x="5%">SVG</text>

  <!-- y with multiple values -->
  <text y="40%,60%,80%" x="55%">SVG</text>
</svg>
```

```css
text {
  font: 40px sans-serif;
}

line {
  fill: none;
  stroke: red;
  stroke-width: 0.5px;
  stroke-dasharray: 2px;
}
```

tref
----

**警告:** SVG2 では `<tref>` (en-US) は非推奨であり、使用すべきではありません。

`<tref>` (en-US) にある値が 1 つの場合、 `y` は*コンテンツテキストの位置*を配置しなければならない Y 座標を定義します。*コンテンツテキストの位置*は、通常、テキストの最初の行のベースライン上の点です。正確な*コンテンツテキスト位置*は、 `text-anchor (en-US)` や `direction` など、他のプロパティの影響を受けます。

複数の値がある場合、`y` はテキストから個々の文字への Y 座標を定義します。値が文字よりも少ない場合、残りの文字は最後に配置された文字と一直線上に配置されます。値が文字よりも多い場合は、余分な値は無視されます。

|  |  |
| --- | --- |
| 値 |
 (**<length>**
 |
 **<percentage>**) のリスト
  |
| 既定値 | `0` |
| アニメーション | 可 |

tspan
-----

`<tspan>` にある値が 1 つの場合、 `y` は*コンテンツテキストの位置*を配置しなければならない Y 座標を定義します。*コンテンツテキストの位置*は、通常、テキストの最初の行のベースライン上の点です。正確な*コンテンツテキスト位置*は、 `text-anchor (en-US)` や `direction` など、他のプロパティの影響を受けます。

複数の値がある場合、`y` はテキストから個々の文字への Y 座標を定義します。値が文字よりも少ない場合、残りの文字は最後に配置された文字と一直線上に配置されます。値が文字よりも多い場合は、余分な値は無視されます。

|  |  |
| --- | --- |
| 値 |
 List of (**<length>**
 |
 **<percentage>**)
  |
| 既定値 | *なし* |
| アニメーション | 可 |
```

html,
body,
svg {
  height: 100%;
}
```

```html
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
  <!-- horizontal line to materialized the text base line -->
  <line x1="0" y1="40%" x2="100%" y2="40%" />
  <line x1="0" y1="60%" x2="100%" y2="60%" />
  <line x1="0" y1="80%" x2="100%" y2="80%" />

  <!-- vertical line to materialized the x positioning -->
  <line x1="5%" y1="0" x2="5%" y2="100%" />
  <line x1="55%" y1="0" x2="55%" y2="100%" />

  <text>
    <!-- y with a single value -->
    <tspan y="40%" x="5%">SVG</tspan>

    <!-- y with multiple values -->
    <tspan y="40%,60%,80%" x="55%">SVG</tspan>
  </text>
</svg>
```

```css
text {
  font: 40px sans-serif;
}

line {
  fill: none;
  stroke: red;
  stroke-width: 0.5px;
  stroke-dasharray: 2px;
}
```

use
---

`<use>` の場合， `y` は参照される要素の左上隅の Y 座標を定義します．

|  |  |
| --- | --- |
| 値 | **<length>**
 |
 **<percentage>** |
| 既定値 | `0` |
| アニメーション | 可 |

**メモ:** SVG2 からは、`y` は*幾何プロパティ*であり、この属性は使用される要素の CSS プロパティとしても使用できます。

仕様書
---

| Specification |
| --- |
| Filter Effects Module Level 1 # element-attrdef-filter-y |
| Filter Effects Module Level 1 # element-attrdef-fespotlight-y |
| Filter Effects Module Level 1 # element-attrdef-fepointlight-y |
| Filter Effects Module Level 1 # element-attrdef-filter-primitive-y |
| CSS Masking Module Level 1 # element-attrdef-mask-y |
| Scalable Vector Graphics (SVG) 2 # Y |
| Scalable Vector Graphics (SVG) 2 # PatternElementYAttribute |
| Scalable Vector Graphics (SVG) 2 # TextElementYAttribute |


共通 (exsl) - EXSLT

共通 (exsl)
=========

**XSLT/XPath リファレンス**: XSLT 要素, EXSLT 関数, XPath 関数, XPath 軸

EXSLT 共通パッケージは、 XSLT の機能を拡張する基本的な関数を提供します。共通パッケージの名前空間は `http://exslt.org/common` です。

exsl:node-set()`exsl:node-set()` は結果木の断片からノードセットを返します。これは、変数の値を取得するために select 属性ではなく `xsl:variable` を見たときに得られるものです。これにより、変数内に作成された XML を複数のステップで処理することができます。

exsl:object-type()`exsl:object-type()` は、指定されたオブジェクトの型を示す文字列を返します。

ブラウザーの互換性
---------

{{Compat}}


Math (math) - EXSLT

Math (math)
===========

**XSLT/XPath リファレンス**: XSLT 要素, EXSLT 関数, XPath 関数, XPath 軸

EXSLT の Math パッケージは、数値の操作とノードの比較のための機能を提供します。 Math パッケージの名前空間は `http://exslt.org/math` です。

math:highest()`math:highest()` は、指定されたノードセットの最大値（`math:max()` (en-US) を使用して計算した最大値）を持つノードを返します。

math:lowest()`math:lowest()` は、指定されたノードセットの最小値（`math:min()` (en-US) を使用して計算した最小値）を持つノードを返します。

ブラウザーの互換性
---------

{{Compat}}


math:lowest() - EXSLT

math:lowest()
=============

**XSLT/XPath リファレンス**: XSLT 要素, EXSLT 関数, XPath 関数, XPath 軸

`math:lowest()` は、指定されたノードセットの最小値（`math:min()` (en-US) を使用して計算した最小値）を持つノードを返します。

ノードの文字列値を数値に変換した値が最小値と等しい場合、この最小値を持ちます。

構文
--
```

math:lowest(nodeSet)
```

### 引数

`nodeSet`

最小値を返すノードセット。

### 返値

`math:min()` (en-US) が返すノードのコピーで構成された結果ツリーの断片です。

仕様書
---

EXSLT - MATH:LOWEST


math:highest() - EXSLT

math:highest()
==============

**XSLT/XPath リファレンス**: XSLT 要素, EXSLT 関数, XPath 関数, XPath 軸

`math:highest()` は、指定されたノードセットの最大値（`math:max()` (en-US) を使用して計算した最大値）を持つノードを返します。

ノードの文字列値を数値に変換した値が最大値と等しい場合、この最大値を持ちます。

構文
--
```

math:highest(nodeSet)
```

### 引数

`nodeSet`

最大値を持つノードが返されるノードセット

### 返値

`math:max()` (en-US) が返すノードのコピーで構成された結果ツリーの断片です。

仕様書
---

EXSLT - MATH:HIGHEST


exsl:node-set() - EXSLT

exsl:node-set()
===============

**XSLT/XPath リファレンス**: XSLT 要素, EXSLT 関数, XPath 関数, XPath 軸

`exsl:node-set()` は結果木の断片からノードセットを返します。これは、変数の値を取得するために select 属性ではなく `xsl:variable` を見たときに得られるものです。これにより、変数内に作成された XML を複数のステップで処理することができます。

また、`exsl:node-set()` を使って、文字列をテキストノードにすることができます。

構文
--
```

exsl:node-set(object)
```

### 引数

`object`

対応するノードセットを返す対象となるオブジェクト。

### 返値

指定された `object` に対応するノードセットです。

仕様書
---

EXSLT - EXSL:NODE-SET


exsl:object-type() - EXSLT

exsl:object-type()
==================

**XSLT/XPath リファレンス**: XSLT 要素, EXSLT 関数, XPath 関数, XPath 軸

`exsl:object-type()` は、指定されたオブジェクトの型を示す文字列を返します。

**メモ:** ほとんどの XSLT オブジェクトの型は、安全に他の型へ自動変換されることがあります。しかし、自動変換によってはエラーを発生させることになります。特に、ノードセットでないものをノードセットとして扱うと、そのようになります。この機能により、名前付きテンプレートや拡張関数の作者は、簡単に引数値に柔軟性を持たせることができます。

構文
--
```

exsl:object-type(object);
```

### 引数

`object`

型が返されるオブジェクト。

### 返値

オブジェクトの型で、以下のいずれかになります。

* `string`
* `number`
* `boolean`
* `node-set`
* `RTF`
* `external`
仕様書
---

EXSLT - EXSL:OBJECT-TYPE


Firefox - Mozilla

Firefox
=======

Firefox は Mozilla のポピュラーな Web ブラウザで、デスクトップ上の Windows、OS X、Linux、そしてすべての Android および iOS モバイルデバイスを含む複数のプラットフォームで利用できます。幅広い互換性、最新の Web 技術、強力な開発ツールにより、Firefox は Web 開発者とエンドユーザーの両方にとって最適な選択肢です。

Firefox はオープンソースのプロジェクトです。コードの多くは私達の巨大なボランティアのコミュニティの貢献によるものです。ここでは、Firefox プロジェクトにどのように貢献するかについて学ぶことができ、Firefox アドオンの構築、Firefox の開発者ツールの使い方、その他のトピックへのリンクもあります。

Firefox のアドオンを作成する方法、Firefox 自体を開発して構築する方法、Firefox の内部とそのサブプロジェクトの仕組みについて学びます。

* 開発者向けリリースノート
 開発者向けのリリースノート。ウェブサイトとアドオンに向けた新しい機能が Firefox のどのバージョンで登場したのかがわかります。
* プロジェクトドキュメント
 Firefox の内部構造とそのビルドシステムに関する詳細な情報を入手してください。そうすれば、コード内であなたの道を見つけることができます。
* 開発者ガイド
 私たちの開発者ガイドでは、Firefox のソースコードを入手してコンパイルする方法、方法を見つける方法、プロジェクトに貢献する方法について詳しく説明しています。
Firefox チャンネル
-------------

Firefox は 5 つの**チャンネル**で利用できます。

### Firefox Nightly

毎晩、私たちは mozilla-central の最新コードから Firefox をビルドします。これらのビルドは、Firefox 開発者や、最新の最先端の機能をまだ積極的に開発している最中に試してみたい方向けです。

Firefox Nightly のダウンロード

### Firefox Developer Edition

これは開発者向けの Firefox のバージョンです。6 週間ごとに、Firefox Nightly から十分に安定した機能を取り込み、Firefox Developer Edition の新しいバージョンが作成されます。このチャンネルでのみ利用可能な開発者用の追加機能もいくつか追加しています。

Firefox Developer Edition についてさらに学ぶ

Firefox Developer Edition のダウンロード

### Firefox Beta

Firefox Developer Edition で 6 週間を過ごした後に、十分に安定した機能を利用し、新しいバージョンの Firefox Beta を作成します。 Firefox Beta ビルドは、Firefox 愛好者が次回リリースされることになる Firefox バージョンをテストするためのものです。

Firefox Beta のダウンロード

### Firefox

Beta でさらに 6 週間安定させた後、新しいリリースの Firefox で何億人ものユーザーに新機能を届ける準備が整います。

Firefox のダウンロード

### Firefox Extended Support Release (ESR)

Firefox ESR は、学校、大学、企業、大規模な展開のための延長サポートを必要とする組織など、組織が使用するためのデスクトップ用 Firefox の長期サポート版です。

Firefox Extended Support Release についてさらに学ぶ

Firefox ESR のダウンロード

目次
--

Firefox における実験的機能このページでは、提案されているまたは最先端のウェブプラットフォーム標準を含む、 Firefox の実験的かつ部分的に実装された機能を一覧にしています。また、それらの機能が搭載されているビルドの情報、「既定で」有効になっているかどうか、有効または無効にするためにどの*環境設定*を使用すべきかについても説明しています。
 これにより、機能がリリースされる前に、その機能をテストすることができます。

Firefox 開発者向けリリースノート以下は、開発者向けの Firefox リリースノートへのリンクです。どの機能や API が追加され、改善されたか、Firefox の各バージョンでどのようなバグが修正されたかについての詳細が、懇切丁寧に記されています。これらは皆さん開発者がほしいかと思って用意したものです。えっへん。

Firefox プロファイル
--------------

複数の Firefox チャンネル、または複数の設定を定常的に使用している場合は、Firefox のプロファイルマネージャーやその他のプロファイル管理ツールを利用して複数の Firefox プロファイルを使用する方法をお読みください。

こちらもどうぞ
-------

* メーリングリスト
* リリーススケジュール


アドオン - Mozilla

アドオン
====

開発者はアドオン (add-on) を作成して Firefox の機能を拡張したり変更したりすることができます。 アドオンは JavaScript、HTML、CSS といったウェブ標準技術と、幾つかの専用の JavaScript API を使って作成します。

中でも、以下のようなことがアドオンで実現できます。

* 特定のウェブサイトの見た目や内容を変更する
* Firefox のユーザーインタフェースを変更する
* Firefox に新しい機能を追加する

アドオンには幾つかの種類がありますが、もっとも一般的なものは拡張機能 (extension) です。

拡張機能の開発
-------

以前は Firefox の拡張機能を開発するためのツールセットが幾つかありましたが、 2017 年 11 月からは WebExtensions API を使って拡張機能を構築するようにしなければいけません。 それ以外のツールセット (例えば overlay add-on, bootstrapped add-on, add-on SDK) はサポートされなくなりました。

WebExtensions API を使って Firefox 向けに作った拡張機能は、ブラウザー間の互換性を持つように設計されています。大抵の場合、 Chrome、Edge、Opera でも必要に応じてわずかに修正するだけで動作します。マルチプロセスの Firefox とも完全な互換性があります。Firefox とその他のブラウザーで現在対応している API はこちらです。

### 拡張機能ワークショップ

Firefox Extension Workshop は、 Firefox 用の拡張機能を開発し、ユーザーが閲覧の使い勝手をカスタマイズできるようにする、シンプルかつ強力な方法を提供するお手伝いをします。次のようなものがあります。

* Firefox 拡張機能の概要
* 開発とテストのためのツールとプロセス
* 拡張機能を addons.mozilla.org で公開する、または自分で配布する方法
* 公開した拡張機能を管理する方法
* 拡張機能の開発と使用のためのエンタープライズガイド
* Firefox のテーマを開発する方法
* Firefox 開発者コミュニティ
### Android 版 Firefox の拡張機能

2020 年に、 Mozilla は新しい Android 版 Firefox の操作形態をリリースします。この新しい高性能な Android 向けブラウザーは、Mozilla のモバイルブラウザーエンジンである GeckoView を使って作り直されています。現在、 GeckoView で WebExtensions API のサポートを構築中です。

### 既存の拡張機能の移行

XUL overlay、bootstrapped、add-on SDK などを使用した既存の拡張機能を保守している場合は、 WebExtension API を使って移植できます。 MDN の関連記事をご覧ください。

移行全般のサポート情報は、 Wiki ページを参照してください。

アドオンの公開
-------

Addons.mozilla.org は、 "AMO" と呼ばれる Mozilla 公式サイトです。開発者はアドオンを掲載し、ユーザーはアドオンを探すことができます。アドオンを開発したら AMO にアップロードして、ユーザーやクリエイターのコミュニティに注目してもらいましょう。

開発したアドオンを AMO に掲載することは必須ではありませんが、 Mozilla が署名しない限り、ユーザーはインストールできません。

アドオンを公開する手順の概要については、アドオンに署名して配布するにはをご覧ください。

その他の種類のアドオン
-----------

拡張機能の他にも、ユーザーが Firefox をカスタマイズするためのアドオンが何種類かあります。

* User dictionaries は、色々な言語のスペルチェックを可能にします。
* Language packs は、 Firefox のユーザーインターフェイスで更に多くの言語に対応できるようにします。
連絡先
---

連絡先ページでは、サポートを受ける方法、アドオンの最新情報を入手する方法、フィードバックを提供する方法などの詳細を確認できます。


連絡先 - Mozilla

連絡先
===

サポートを受けたり、アドオン関連の最新ニュースを追いかけたり、ご意見を寄せたりするには、下記のリンクからどうぞ。

### アドオンフォーラム

Add-ons Discourse forum は、アドオン開発全般の議論や質問に使って下さい。

### メーリングリスト

**dev-addons メーリングリスト** は 2020 年 12 月 1 日に廃止されました。 dev-addons archives で WebExtensions API と addons.mozilla.org に関する過去の議論を参照することができます。

### チャット

Matrix は、分散型リアルタイム通信のための、オープンで軽量なプロトコルです。 Mozilla の Matrix インスタンスに参加する方法については、 MozillaWiki の Matrix ページを参照してください。

* Add-ons (拡張機能、テーマ、 WebExtensions API のサポート)
* AMO (addons.mozilla.org に関する議論)
### 問題を報告する

#### セキュリティ欠陥

アドオンのセキュリティ欠陥を見つけた場合は、それが Mozilla のサイトで提供しているものでなくても、私たちまでお知らせ下さい。私たちは開発者と協力して問題を修正します。 連絡は非公開で、 Bugzilla または amo-admins@mozilla.com 宛てのメールでお願いします。

#### サイト addons.mozilla.org (AMO)のバグ

もしサイト自体の問題を見つけたら、是非修正したいと思います。 バグ報告して、できるだけ多くの詳細を含めてください。


ブラウザー拡張機能 - Mozilla

ブラウザー拡張機能
=========

拡張機能はブラウザーの能力を拡張・修正するものです。Firefox の拡張機能は WebExtensions API を使ってビルドされ、この API は拡張機能をクロスブラウザーで開発するシステムです。このシステムの大半は Google Chrome と Opera と W3C Draft Community Group でサポートされている extension API と互換性があります。

これらのブラウザー用に書かれた拡張機能は大抵の場合、ほんの少し変更を加えるだけで (en-US) Firefox や Microsoft Edge でも動かすことができます。この API は マルチプロセス Firefox にも完全互換です。

お持ちのアイデアや質問があったり、レガシーアドオンを WebExtensions API を使うように移行するのに助けが要る場合、dev-addons のメーリングリスト (英語) や Add-ons room (英語) や Matrix (英語) にてご連絡ください。

日本語情報としては Mozilla Japan コミュニティの Slack の #extdev チャンネルで情報交換が行われています。

始めましょう
------

* 拡張機能とは何か?
* 初めての拡張機能
* 2 つめの拡張機能
* 拡張機能の中身
* 拡張機能の例
概念
--

* コンテンツスクリプト
* マッチパターン
* ファイルの操作
* 国際化拡張
* セキュリティのベストプラクティス
* Content Security Policy
* Native messaging
* devtools APIs を使用する
* ネイティブマニフェスト
* manifests ファイル
ユーザーインターフェイス
------------

* 導入
* ブラウザーツールバーボタン
* ポップアップ付きブラウザーツールバーボタン
* アドレスバーボタン
* ポップアップ付きアドレスバーボタン
* コンテキストメニューの項目
* サイドバー
* オプションページ
* Extension pages
* 通知
* アドレスバーの入力候補 (en-US)
* 開発ツールパネル
* ブラウザースタイル (en-US)
逆引きリファレンス
---------

* HTTP リクエストへの介入
* web ページの変更
* ツールバーボタンの追加
* 設定画面の実装
* クリップボードとのやりとり
* Tabs API を使用する
* Bookmarks API を使用する
* Cookies API を使用する (en-US)
* Contextual Identity を使用する (en-US)
* userScripts を使用する (en-US)
* 外部コンテンツの挿入 (en-US)
移行
--

* Google Chrome extension からの移行 (en-US)
* 古い Firefox アドオンの移行
* Android 向け Firefox 拡張機能の開発
* Thunderbird における WebExtensions によるアドイン開発
* Add-on SDK との比較
* XUL/XPCOM 拡張との比較
* Chrome との非互換性
* デスクトップ版と Android 版の拡張機能の違い
Firefox でのワークフロー
----------------

* ユーザー体験の成功事例
* Firefox への一時的なインストール
* デバッグ
* テストの持続と再起動機能
* はじめての web-ext
* web-ext コマンドリファレンス
* Extensions と Add-on ID
* 配布方法の選択肢
* 正しいパーミッションを要求する
* オブジェクトを Web ページのスクリプトと共有する (en-US)
* 拡張機能を引退させる (en-US)
* Tips and Tricks
* ブラウザー拡張機能の開発ツール
リファレンス
------

### JavaScript API 群

* JavaScript API の概要
* JavaScript API 群のブラウザー互換性表
* alarms
* bookmarks
* browserAction
* browserSettings
* browsingData
* clipboard
* commands
* contentScripts
* contextualIdentities
* cookies
* devtools
* downloads
* events
* extension
* extensionTypes
* find
* history
* i18n
* identity
* idle
* management
* menus
* notifications
* omnibox
* permissions
* pkcs11
* privacy
* proxy
* runtime
* sessions
* sidebarAction
* storage
* tabs
* theme
* topSites
* types
* webNavigation
* webRequest
* windows
### Manifest keys

* manifest.json の概要
* manifest.json のブラウザー互換性
* author
* background
* browser\_action
* browser\_specific\_settings
* chrome\_settings\_overrides
* chrome\_url\_overrides
* commands
* content\_scripts
* content\_security\_policy
* default\_locale
* description
* developer
* devtools\_page
* homepage\_url
* incognito
* manifest\_version
* name
* omnibox
* optional\_permissions
* options\_ui
* page\_action
* permissions
* protocol\_handlers
* short\_name
* sidebar\_action
* version
* version\_name
* web\_accessible\_resources


設定ページを実装する - Mozilla

設定ページを実装する
==========

設定ページは、ユーザーに拡張機能の設定を確認して変える方法を与えます(「プリファレンス」や「オプション」とも呼ばれます)。

WebExtension API では一般に、設定は `storage` API で保存されます。設定ページの実装は次の 3 ステップの手順です:

* 設定を表示して、ユーザーがそれを変更できる HTML を書く。
* HTML からインクルードされる、ストレージから設定ページに投入し、ユーザーが変更した時に保存された設定を更新するスクリプトを書く。
* HTML ファイルのパスを manifest.json の `options_ui` キーに設定する。これにより、HTML 文書が、拡張機能の名前や説明と共に、文書ブラウザーのアドオンマネージャーに表示される。

**メモ:** `runtime.openOptionsPage()` 関数を使ってプログラム的に開くこともできます。

簡単な拡張機能
-------

まずは、ユーザーが訪問するページに青い枠をつける拡張機能を書きます。

"settings" というディレクトリーを作り、そこに "manifest.json" という名前のファイルを作って下記の中身を入れます:

```json
{
  "manifest\_version": 2,
  "name": "Settings example",
  "version": "1.0",

  "content\_scripts": [
    {
      "matches": ["<all\_urls>"],
      "js": ["borderify.js"]
    }
  ]
}
```

この拡張機能はブラウザーに対し、"borderify.js" というコンテンツスクリプトを、ユーザーが訪問するすべてのウェブページで読み込むよう指示します。

次に、"settings" ディレクトリー内に "borderify.js" というファイルを作り、次の中身を入れます:

```js
document.body.style.border = "10px solid blue";
```

これは単にページに青い枠をつけます。

この拡張機能をインストールしてテストします — お好みのあらゆるウェブページを開きます:

設定を追加する
-------

今度は枠の色をユーザーが設定できるような設定ページを作りましょう。

まずは "manifest.json" を次の中身に更新します:

```json
{
  "manifest\_version": 2,
  "name": "Settings example",
  "version": "1.0",

  "content\_scripts": [
    {
      "matches": ["<all\_urls>"],
      "js": ["borderify.js"]
    }
  ],

  "options\_ui": {
    "page": "options.html"
  },

  "permissions": ["storage"],

  "applications": {
    "gecko": {
      "id": "addon@example.com"
    }
  }
}
```

新しく次の 3 つのキーを追加しました:

* `options_ui`: これは HTML 文書に、この拡張機能の設定ページ(オプションページともいう)であることを設定します
* `permissions`: `storage` API を使って設定を保存し、この API を使うパーミッションが必要です
* `applications`: 同期ストレージに設定を読み書きするには、拡張機能の ID を入れておく必要があります

次に "options.html" を提供する約束をしたので、作成します。"settings" ディレクトリー内にその名前でファイルを作成して、次の中身を与えます:

```html
<!doctype html>

<html>
  <head>
    <meta charset="utf-8" />
  </head>

  <body>
    <form>
      <label>Border color<input type="text" id="color" /></label>
      <button type="submit">Save</button>
    </form>

    <script src="options.js"></script>
  </body>
</html>
```

これは `<form>` と、そこにラベル付きのテキスト `<input>` と送信 `<button>` を定義します。また "options.js" というスクリプトも入っています。

もう一度 "options.js"を "settings" ディレクトリーに作り、次の中身を与えます:

```js
function saveOptions(e) {
  e.preventDefault();
  browser.storage.sync.set({
    color: document.querySelector("#color").value,
  });
}

function restoreOptions() {
  function setCurrentChoice(result) {
    document.querySelector("#color").value = result.color || "blue";
  }

  function onError(error) {
    console.log(`Error: ${error}`);
  }

  var getting = browser.storage.sync.get("color");
  getting.then(setCurrentChoice, onError);
}

document.addEventListener("DOMContentLoaded", restoreOptions);
document.querySelector("form").addEventListener("submit", saveOptions);
```

これは 2 つのことをします:

* 文書が読み込まれた時、"color" の値を `storage.sync.get()` を使ってストレージから取り出します。値が未設定なら、既定の "blue" を用います。これで値を `sync` ストレージ領域から取得できます。
* ユーザーが "Save" を押して送信した時、テキストボックスの値を `storage.sync.set()` を用いて保存します。これで値を `sync` ストレージ領域に保存できます。

**メモ:** 別々の .js ファイルの指定が必要です。インライン JavaScript は使用できません。

ローカルストレージがふさわしいと感じる場合、代わりにローカルストレージに設定値を保存できます。

**メモ:** Firefox の `storage.sync` の実装はアドオン ID に依存しているのに注意します。`storage.sync` を使う場合、上記 manifest にあるように、manifest.json の `applications` キーに拡張機能の ID をセットしておく必要があります。

最後に、ストレージから枠の色を読むのに "borderify.js" を更新します:

**警告:** バージョン 52 より前の Firefox の browser.storage.local.get() のバグにより、下記のコードは機能しません。バージョン 52 より前の Firefox で動作させるには、`onGot()` の中で 2 回出てくる `item.color` を `item[0].color` に変えないといけません。

```js
function onError(error) {
  console.log(`Error: ${error}`);
}

function onGot(item) {
  var color = "blue";
  if (item.color) {
    color = item.color;
  }
  document.body.style.border = "10px solid " + color;
}

var getting = browser.storage.sync.get("color");
getting.then(onGot, onError);
```

この時点で、拡張機能はこのようになります:
```

settings/
    borderify.js
    manifest.json
    options.html
    options.js
```

いま、次を行ってみます:

* 拡張機能を再読み込み
* ウェブページを読み込む
* 設定ページを開いて枠の色を変える
* ウェブページを再読み込みして違いを見る

Firefox で設定ページにアクセスするには about:addons に移動して拡張機能のエントリーの隣の "Preferences" ボタンをクリックします。

詳しく学ぶ
-----

* `options_ui` マニフェストキーのリファレンス文書
* `storage` API のリファレンス文書
* 拡張機能から直接設定ページを開くには `runtime.openOptionsPage()` API を使う
* 設定ページの例:
    + favourite-colour


JavaScript API 群 - Mozilla

JavaScript API 群
================

WebExtension 用の JavaScript API は拡張機能のバックグラウンドスクリプトと、その他の拡張機能にバンドルした文書 (ブラウザーアクションやページアクションポップアップやサイドバーやオプションページや新規タブページを含む) で使用できます。いくつかの API は拡張機能のコンテンツスクリプトからもアクセスできます (コンテンツスクリプトガイドの表を見てください)。

もっと強力な API を使うには、拡張機能の `manifest.json` でパーミッションをリクエストする必要があります。

`browser` 名前空間内で API にアクセスできます:

```js
function logTabs(tabs) {
  console.log(tabs);
}

browser.tabs.query({ currentWindow: true }, logTabs);
```

API の多くは非同期で、 `Promise` を返します:

```js
function logCookie(c) {
  console.log(c);
}

function logError(e) {
  console.error(e);
}

let setCookie = browser.cookies.set({ url: "/" });
setCookie.then(logCookie, logError);
```

これは Google Chrome の拡張機能システムでは違っていて、`browser` の代わりに `chrome` 名前空間を使い、promise や非同期関数の代わりにコールバックを使っているのに注意してください。移植の助けとして、WebExtensions API の Firefox 実装は `browser` と promise と同様に `chrome` とコールバックもサポートします。Mozilla は `browser` と promise を使うコードが Chrome で変更なく動作する polyfill も書いています: https://github.com/mozilla/webextension-polyfill.

Firefox は `chrome` 名前空間の下でコールバックを使う API も実装しています。これにより Chrome 向けのコードをここに文書化された API を使って、Firefox で大部分変更なしに実行させることができます。

Microsoft Edge は `browser` 名前空間を使いますが、promise ベースの非同期 API はサポートされていません。Edge では当面、非同期 API はコールバックを使うのが必須です。

すべてのブラウザーがすべての API をサポートしているわけではありません: 詳しくは JavaScript API のブラウザーサポートをご覧ください。

JavaScript API 一覧
-----------------

下記の JavaScript API の完全な一覧をご覧ください:

alarmsコードが動作するタイミングを予約します。この API は `setTimeout()` や `setInterval()` と似ていますが、 alarms API はバックグラウンドで動作する点が異なります。

bookmarksWebExtensions `bookmarks` API を利用すると、拡張機能からブラウザーのブックマークシステムにアクセスしたり、操作することができます。ページをブックマークしたり、既存のブックマークを取得したり、ブックマークを編集・削除・整理することが可能です。

browserActionブラウザーのツールバーにボタンを追加します。

browserSettings拡張機能にグローバルなブラウザー設定の変更を可能にします。この API の各プロパティは `types.BrowserSetting` オブジェクトで、これはそれぞれの設定の変更能力を提供します。これはグローバルな設定のため、拡張機能で衝突が起きる可能性があります。衝突の処理方法の詳細は `BrowserSetting.set()` の文書を見てください。

browsingData拡張機能がユーザーの閲覧中に蓄積したデータをクリアできるようにします。

clipboardクリップボード API は、拡張機能がシステムのクリップボードに要素をクリップするのを可能にします。現在この API は画像のコピーだけをサボートしていますが、将来的にはテキストと HTML のコピーをサボートする計画です。

commands`commands` manifest.json キーを使って、登録したコマンドをユーザーが実行するのをリッスンします。

contentScriptsこの API はコンテントスクリプトを登録するためにお使いいただけます。コンテントスクリプトを登録することで、指定した URL にマッチするページにそのスクリプトを挿入するようブラウザに指定することができます。

contextualIdentitiescontextual identities の操作: contextual identities を一覧、作成、削除、更新します。

cookies拡張機能に cookie の取得と設定と、変更された時の通知を可能にします。

devtools拡張機能がブラウザーのDeveloper Toolsと対話することを可能にします。この API を使用して、開発者ツールのページを作成したり、検査対象のウィンドウと対話したり、ページのネットワーク使用状況を検査したりすることができます。

downloads拡張機能にブラウザーのダウンロードマネージャーとのやりとりを可能にします。この API モジュールを、ファイルマネージャーでのファイルのダウンロード、キャンセル、停止、ダウンロードの再開、ダウンロード済みのファイルの表示に使用できます。

eventsイベントをディスパッチする API から使われる共通の型です。

extension拡張機能に関連するユーティリティ。拡張機能のリソースパッケージの URL を取得したり、拡張機能のページの `Window` オブジェクトを取得したり、いろいろな設定の値を取得したりします。注意として、このモジュールのメッセージ APIs は非推奨で、 `runtime` モジュールの同様な API が好まれます。

extensionTypesその他の WebExtension API で使われる共通な型

findウェブページのテキストを検索し、マッチしたものをハイライトします。

historyブラウザー履歴とやりとりする `history` API を使用します。

i18n拡張機能を国際化する関数です。これらの API は、拡張機能に同梱したロケールファイルからローカライズ文字列を取得したり、ブラウザーの現在の言語や、その Accept-Language ヘッダー を調べるために使用します。

identityidentity API を使って OAuth2 の認証コードやアクセストークンを取得し、拡張機能が OAuth2 での認証（Google や Facebook アカウントなど）をサポートするサービスからユーザーデータを取得できるようにします。

idleユーザーのシステムがアイドル状態、ロックされた状態、アクティブな状態であるのを発見します。

managementインストール済みのアドオンの管理情報を取得します。

menusブラウザーのメニューシステムに項目を追加します。

notificationsOS の通知メカニズムを使って、ユーザーへの通知を表示します。この API は OS の通知メカニズムを使うため、OS とユーザー設定によって通知の現れ方やふるまいは変わってきます。

omnibox拡張機能に、ユーザーがアドレスバーに入力した時のカスタマイズされた振る舞いを有効にします。

permissions拡張機能のインストール後、実行時に特別なパーミッションの要求を可能にする。

pkcs11`pkcs11` API は拡張機能にセキュリティモジュール PKCS #11 の列挙を可能とし、キーの元と証明書としてブラウザーからアクセスできるようにします。

privacyさまざまなプライバシー関連のブラウザー設定にアクセスや変更を行います。

proxy拡張された Proxy Auto-Configuration (PAC) file (これはウェブのリクエストをプロキシ化するポリシーを実装します) を実装するのにプロキシ API を使います。この実装は標準の PAC 設計といくつかそれていて、なぜなら PAC ファイルのデファクト仕様は 1995 年頃の初期実装から変えられてないためです。仕様を維持している標準化団体はありません。

runtimeこのモジュールは拡張機能と実行環境の情報を提供します。

sessionsセッション API を使ってブラウザーが動作している間に閉じたタブやウィンドウを一覧、復帰します。

sidebarAction拡張機能のサイドバーのプロパティを取得、設定します。

storage拡張機能にデータの保存、取得と、保存項目の変更をリッスンできるようにします。

tabsブラウザーのタブシステムとやりとりします。

themeブラウザー拡張機能がブラウザーのテーマを更新できるようにします。

topSitestopSites API を使うと、ユーザーがよく訪れるページをを含む配列を取得できます。

typesブラウザー設定を表すのに使われる `BrowserSetting` 型を定義します。

webNavigationナビゲーションのいろいろな段階でイベントリスナーを追加します。ナビゲーションにはある URL から他に移動するブラウザーフレームにより成り立っていて、それは(いつもではなく)通常はリンクのクリックやロケーションバーへの URL 入力といったユーザー操作の応答として発生します。

webRequestwebsocket が ws:// and wss:// としてリクエストするものも含めた、HTTP リクエスト作成のいろいろなステージでイベントリスナーを追加します。イベントリスナーはリクエストの詳細情報を受け取ったり、リクエストを編集、修正したりします。

windowsブラウザーウィンドウと相互作用します。この API を使って開いているウィンドウの情報を取得したり、ウィンドウを開き、修正し、閉じることができます。ウィンドウのオープン、クローズ、アクティベートのイベントをリッスンすることもできます。


初めての拡張機能 - Mozilla

初めての拡張機能
========

この記事では、Firefox 用の拡張機能をどのように作ればよいのか、その初めから最後までを一通り説明します。この拡張機能は "mozilla.org" とそのサブドメインから読み込まれたページに赤い枠を付けるだけです。

このサンプルのソースコードは GitHub で公開しています（https://github.com/mdn/webextensions-examples/tree/master/borderify）。

これ以降は、バージョン 45 以降の Firefox が必要となります。

拡張機能を書く
-------

新しいディレクトリーを作成し、そのディレクトリーに移動します。例えば、コマンドライン/ターミナルでは次のようにできます:

```bash
mkdir borderify
cd borderify
```

### manifest.json

それでは、"borderify" ディレクトリー配下に新しいファイル "manifest.json" を作成します。以下の内容を書き込んで保存してください。

```json
{
  "manifest\_version": 2,
  "name": "Borderify",
  "version": "1.0",

  "description": "Adds a solid red border to all webpages matching mozilla.org.",

  "icons": {
    "48": "icons/border-48.png"
  },

  "content\_scripts": [
    {
      "matches": ["\*://\*.mozilla.org/\*"],
      "js": ["borderify.js"]
    }
  ]
}
```

* 最初の 3 つのキー `manifest_version`、`name`、`version` は必須であり、拡張機能の基本的なメタデータを指定します。
* `description` は省略可能ですが、設定しておくことをお勧めします。この値はアドオンマネージャーに表示されます。
* `icons` は省略可能ですが、設定しておくことをお勧めします。この値は拡張機能のアイコンを指定するものであり、アイコンはアドオンマネージャーに表示されます。

ここで最も興味深いキーは `content_scripts` です。このキーは、指定したパターンにマッチする URL のウェブページにスクリプトを読み込ませるよう Firefox に指示するものです。今回は、"borderify.js" というスクリプトを "mozilla.org" とそのサブドメインの HTTP / HTTPS ページすべてに読み込ませるように指定しています。

* コンテンツスクリプト関する詳細
* マッチパターンに関する詳細

**警告:** 時折、あなたの拡張機能用に ID を指定する必要があります。アドオンの ID が必要なとき、`manifest.json` 内に `applications` キーを入れて `gecko.id` プロパティをセットします:

```json
"applications": {
  "gecko": {
    "id": "borderify@example.com"
  }
}
```

### icons/border-48.png

拡張機能にはアイコンを用意すると良いでしょう。このアイコンは、アドオンマネージャーでアドオンのリスト横に表示されます。今回の manifest.json では "icons/border-48.png" を用意していると宣言しています。

まずは "borderify" ディレクトリーの下に "icons" ディレクトリーを作成します。次に、アイコンを "border-48.png" という名前で "icons" ディレクトリー内に保存します。必要であれば サンプルで使用しているアイコン を利用しても構いません（このアイコンは Google Material Design iconset から引用したものであり、Creative Commons Attribution-ShareAlike ライセンスの下で使用しています）。

ここでアイコンを自分で用意する場合は 48x48 ピクセルのサイズにする必要があります。高解像度のディスプレイには 96x96 ピクセルのアイコンを表示させたい場合は、manifest.json の `icons` オブジェクトに `96` というプロパティで設定してください。

```json
"icons": {
  "48": "icons/border-48.png",
  "96": "icons/border-96.png"
}
```

他の方法として、SVG ファイルを指定すれば正しく拡大・縮小されて表示されます。(しかし、SVG にテキストが含んだアイコンを使っている場合、SVG エディターの "convert to path" ツールでテキストを展開し、適切なサイズ/位置に拡大/縮小したくなるかもしれません。)

* アイコンを指定する方法に関する詳細
### borderify.js

最後に、"borderify" ディレクトリーの下に "borderify.js" というファイルを作成します。次の内容を書き込んで保存してください。

```js
document.body.style.border = "5px solid red";
```

このスクリプトは、manifest.json の `content_scripts` キーで指定したパターンにマッチするページに読み込まれます。読み込まれたスクリプトは、そのページ自身のスクリプトと同じようにドキュメントへ直接アクセスします。

* コンテンツスクリプトに関する詳細
動かしてみよう
-------

ここで、必要なファイルが正しい場所に保存されているか再確認してください。
```

borderify/
    icons/
        border-48.png
    borderify.js
    manifest.json
```

### インストール

Firefox の場合: about:debugging ページを開いて、"この Firefox" (Firefox の新しいバージョンで)をクリックし、"一時的なアドオンを読み込む" をクリックし、アドオンのディレクトリーにあるファイルをどれか 1 つ選択します。

ここでインストールされたアドオンは Firefox を再起動するまで有効です。

あるいは、web-ext ツールを使ってコマンドラインから拡張機能を実行することもできます。

### テスト

それでは "mozilla.org" 配下のページを開いてみましょう。ページが赤い枠で囲まれていることを確認できるはずです。

**メモ:** ただ addons.mozilla.org では試さないで! このドメインでは現在、コンテンツスクリプトがブロックされています。

もう少し実験をします。コンテンツスクリプトを編集して、枠線の色を変更したり、ページのコンテンツに何か他の操作を加えてみましょう。コンテンツスクリプトを保存し、"about:debugging"の"再読み込み"ボタンをクリックして拡張機能ファイルを再読み込みすると、加えた変更がすぐに反映されているはずです。

* 拡張機能の読み込みに関する詳細
パッケージ化と公開
---------

自分が作ったアドオンを他の人にも使ってもらうには、アドオンをパッケージとしてまとめた後、署名するために Mozilla へ送信する必要があります。詳細は拡張機能の公開 (en-US)を参照してください。

次のステップ
------

これで Firefox 用 WebExtension の開発手順について概念を学ぶことが出来ました。それでは次のステップに進みましょう。

* 拡張機能の中身を詳しく学ぶ
* より複雑な拡張機能を書いてみる
* 拡張機能で利用できる JavaScript API を詳しく調べる


コンテンツスクリプト - Mozilla

コンテンツスクリプト
==========

コンテンツスクリプトは、特定のウェブページのコンテキストで実行される拡張機能の一部です（拡張機能の一部であるバックグラウンドスクリプトや、ウェブサイト自体の一部であるスクリプト、例えば `<script>` 要素みたいなものと対をなすような)。

バックグラウンドスクリプト (en-US)はすべての WebExtension JavaScript API にアクセスできますが、ウェブページのコンテンツに直接アクセスすることはできません。だからあなたの拡張機能がそれを行う必要がある場合は、コンテンツスクリプトが必要です。

通常のウェブページで読み込まれたスクリプトと同様に、コンテンツスクリプトは、標準の DOM API を使用してページのコンテンツを読み取り、変更することができます。

コンテンツスクリプトは、WebExtension API の小さなサブセットにしかアクセスできませんが、メッセージングシステムを使用して バックグラウンドスクリプトと通信し、WebExtension API に間接的にアクセスすることができます。

**メモ:** コンテンツスクリプトは次のドメインでブロックされます。

* accounts-static.cdn.mozilla.net
* accounts.firefox.com
* addons.cdn.mozilla.net
* addons.mozilla.org
* api.accounts.firefox.com
* content.cdn.mozilla.net
* discovery.addons.mozilla.org
* input.mozilla.org
* install.mozilla.org
* oauth.accounts.firefox.com
* profile.accounts.firefox.com
* support.mozilla.org
* sync.services.mozilla.com
* testpilot.firefox.com

これらドメインのページにコンテンツスクリプトを挿入しようとすると、そのスクリプトは失敗し、ページは CSP エラーをログに記録します。

これらの制限は addons.mozilla.org を含んでいるので、ユーザーはインストール直後に拡張機能を使用しようとし、それが動作しないことに気付くかもしれません。 適切な警告を追加したり、オンボーディングページを追加して、ユーザーを `addons.mozilla.org` から遠ざけたりするとよいでしょう。

コンテンツスクリプトの読み込み
---------------

次の 3 つの方法のいずれかを使用して、ウェブページにコンテンツスクリプトを読み込むことができます。

1. インストール時に、URL パターンに一致するページ内へ。
    * : `manifest.json` の `content_scripts` キーを使用して、URL が指定されたパターンに一致するページをロードするたびにコンテンツスクリプトを読み込むようブラウザーに依頼できます。
2. 実行時に、URL パターンに一致するページ内へ。
    * : `contentScripts` API を使って、URL が指定されたパターンに一致するページを読み込むたびにコンテンツスクリプトを読み込むようブラウザーに依頼できます。これは方法 1 と似ていますが、実行時にコンテンツスクリプトを追加/削除できる点が異なります。）
3. 実行時に、特定のタブへ。
    * : Manifest V2 において、`tabs.executeScript()` API を使用するか、Manifest V3 において、`scripting.executeScript()` (en-US) を使用すると、必要なときにコンテンツスクリプトを特定のタブに読み込むことができます。（ユーザーがブラウザーアクションをクリックした場合など。）

*フレームごと、拡張機能ごとの*グローバルスコープしかありません。これは 1 つのコンテンツスクリプトの変数は、読み込み方にかかわらず、他のコンテンツスクリプトからアクセスできることになります。

方法 (1) と (2) では一致パターンを使って表現された URL のスクリプトだけを読み込みできます。

方法 (3) では、拡張機能と一緒にパッケージされたページのスクリプトも読み込みできますが、"`about:debugging`" や "`about:addons`"のような権限つきページにはスクリプトを読み込めません。

**メモ:** ダイナミック JS モジュールインポートがコンテンツスクリプトで動作するようになりました。詳しくはFirefox バグ 1536094を参照してください。
 *moz-extension* スキームを持つ URL のみが許可され、データ URL は除外されます (Firefox バグ 1587336)。

コンテンツスクリプト環境
------------

### DOM アクセス

コンテンツスクリプトは、普通のページスクリプトと同様に、ページの DOM にアクセスして修正できます。ページスクリプトにてなされた DOM の変更を見ることもできます。

しかし、コンテンツスクリプトは DOM の「きれいな」見た目を取得します。すなわち、

* コンテンツスクリプトはページスクリプトにて定義された JavaScript 変数を見ることができない
* ページスクリプトが組み込み DOM プロパティを再定義した場合、コンテンツスクリプトはそのプロパティの（再定義後でなく）オリジナル値を見ている

Firefox では、この挙動は Xray vision (en-US) と呼ばれます。

次のようなウェブページを考えてみてください。

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  </head>

  <body>
    <script src="page-scripts/page-script.js"></script>
  </body>
</html>
```

"page-script.js" スクリプトは次を実行します。

```js
// page-script.js

// add a new element to the DOM
let p = document.createElement("p");
p.textContent = "This paragraph was added by a page script.";
p.setAttribute("id", "page-script-para");
document.body.appendChild(p);

// define a new property on the window
window.foo = "This global variable was added by a page script";

// redefine the built-in window.confirm() function
window.confirm = () => {
  alert("The page script has also redefined 'confirm'");
};
```

今度は拡張機能がページにコンテンツスクリプトを挿入します。

```js
// content-script.js

// can access and modify the DOM
let pageScriptPara = document.getElementById("page-script-para");
pageScriptPara.style.backgroundColor = "blue";

// can't see properties added by page-script.js
console.log(window.foo); // undefined

// sees the original form of redefined properties
window.confirm("Are you sure?"); // calls the original window.confirm()
```

逆も同様で、ページスクリプトはコンテンツスクリプトが追加した JavaScript のプロパティを見ることができません。

これは、コンテンツスクリプトが、ページスクリプトからの変数と衝突することを心配することなく、予測可能な動作をする DOM プロパティに頼っていることを意味しています。

この動作の実用的な結果の一つは、コンテンツスクリプトが、ページによって読み込まれたいかなる JavaScript ライブラリーにもアクセスできないことです。そのため、例えばページに jQuery が記載されていても、コンテンツスクリプトはそれを見ることができません。

コンテンツスクリプトが JavaScript ライブラリーを使用する必要がある場合、そのライブラリー自体は、それを使用したいコンテンツスクリプトと *並べて* 挿入すべきです。

```json
"content\_scripts": [
  {
    "matches": ["\*://\*.mozilla.org/\*"],
    "js": ["jquery.js", "content-script.js"]
  }
]
```

**メモ:** Firefox ではコンテンツスクリプトからページスクリプトによって生成された JavaScript オブジェクトにアクセスしたり、ページスクリプトにコンテンツスクリプトの JavaScript オブジェクトを公開できるようにする API が提供されます。

詳しくはページスクリプトとオブジェクトを共有する (en-US)のページを見てください。

### WebExtension API

標準 DOM API に加え、コンテンツスクリプトは次の WebExtension API を使用できます。

**`extension` から:**

* `getURL()` (en-US)
* `inIncognitoContext` (en-US)

**`runtime` から:**

* `connect()` (en-US)
* `getManifest()` (en-US)
* `getURL()` (en-US)
* `onConnect` (en-US)
* `onMessage`
* `sendMessage()`

**`i18n` から:**

* `getMessage()`
* `getAcceptLanguages()`
* `getUILanguage()`
* `detectLanguage()`

**`menus` から:**

* `getTargetElement` (en-US)

**すべてから:**

* `storage`
### XHR と Fetch

コンテンツスクリプトは通常の `window.XMLHttpRequest` と `window.fetch()` API を使ってリクエストを作成できます。

**メモ:** Firefox では、コンテンツスクリプトの（例えば、`fetch()` を使った）リクエストは、拡張機能のコンテキストで起こるので、ページコンテンツを参照する URL を絶対 URL で提供せねばなりません。

Chrome では、リクエストはページのコンテキストで起こるので、相対 URL で行われます。例えば、`/api` は `https://[現在のページの URL]/api` に送られます。

コンテンツスクリプトは拡張機能の他の部分と同一のクロスドメイン権限を取得します。よって拡張機能が `manifest.json` の `permissions` キーを使ってあるドメインのクロスドメインアクセスを要求している場合、コンテンツスクリプトも同様にそのドメインのアクセスを取得します。

**メモ:** Manifest V3 を使用する場合、出力先サーバーが CORS を使用してオプトインするとき、コンテンツスクリプトはオリジン間リクエストを実行できます。ただし、コンテンツスクリプトではホスト権限は動作しませんが、通常の拡張ページではまだ動作しています。

これは、コンテンツスクリプトでより特権的な XHR とフェッチインスタンスを公開することによって達成されます。これは、ページ自身からのリクエストのように、`Origin` および `Referer` ヘッダーを設定しない副作用があります。これは、クロスオリジンの性質を明らかにしないリクエストを行うにはよく望ましいとされることです。

**メモ:** Manifest V2 の Firefox では、コンテンツ自身によって送信されたかのように振る舞うリクエストを実行する必要がある拡張機能は、代わりに `content.XMLHttpRequest` と `content.fetch()` を使用することができます。

クロスブラウザー拡張機能にとってこれらの存在は機能検出となります。

Manifest V3 では `content.XMLHttpRequest` と `content.fetch()` が利用できないため、このようなことは起こりえません。

**メモ:** Chrome ではバージョン 73 から、Firefox ではバージョン 101 からマニフェスト V3 を使用する場合、コンテンツスクリプトは、その中で実行されるページと同じ CORS ポリシーが適用されるようになりました。バックエンドスクリプトのみ、昇格したクロスドメイン特権があります。Chrome Extension コンテンツスクリプトにおける Cross-Origin Requests の変更点を参照してください。

バックグラウンドスクリプトとの通信
-----------------

コンテンツスクリプトは WebExtension の API のほとんどを直接使用することはできませんが、メッセージング API を使用して拡張機能のバックグラウンドスクリプトと通信できるため、バックグラウンドスクリプトが使用できるのと同じ API にすべて間接的にアクセスすることができます。

バックグラウンドスクリプトとコンテンツスクリプトの間の通信には、基本的な 2 つのパターンがあります。

* **単発のメッセージ**（オプションのレスポンス付き）を送信することができます。
* **両者の間に長寿命のコネクション**を設定し、そのコネクションを使用してメッセージを交換することができます。
### 単発のメッセージ

レスポンスが必須でない単発のを送るには、次の API を使います。

|  | コンテンツスクリプト内 | バックグラウンドスクリプト内 |
| --- | --- | --- |
| メッセージの送信 | `browser.runtime.sendMessage()` | `browser.tabs.sendMessage() (en-US)` |
| メッセージの受信 | `browser.runtime.onMessage` | `browser.runtime.onMessage` |

例えば、ウェブページでのクリックイベントを待ち受けするコンテンツスクリプトがここにあります。

クリックがリンク上である場合、ターゲット URL をバックグラウンドページにメッセージします。

```js
// content-script.js

window.addEventListener("click", notifyExtension);

function notifyExtension(e) {
  if (e.target.tagName !== "A") {
    return;
  }
  browser.runtime.sendMessage({ url: e.target.href });
}
```

バックグラウンドスクリプトはこのメッセージを待ち受けして、`notifications` API を使って通知を表示します。

```js
// background-script.js

browser.runtime.onMessage.addListener(notify);

function notify(message) {
  browser.notifications.create({
    type: "basic",
    iconUrl: browser.extension.getURL("link.png"),
    title: "You clicked a link!",
    message: message.url,
  });
}
```

この例のコードは GitHub の notify-link-clicks-i18n のサンプルから簡単に適用できます。

### コネクションベースのメッセージ

バックグラウンドスクリプトとコンテンツスクリプトの間で多くのメッセージを交換する場合、単発のメッセージの送信は面倒になることがあります。そこで、 2 つのコンテキスト間でより詳しい接続を確立し、この接続を使用してメッセージを交換するという方法があります。

いずれの側にも `runtime.Port` (en-US) オブジェクトがあり、メッセージ交換に使うことができます。

コネクションを作成するには次のようにします。

* 片方で `runtime.onConnect` (en-US) にてコネクションを待ち受けする。
* もう片方で次を呼び出す。
    + `tabs.connect()` (en-US) (コンテンツスクリプトに接続する場合)
    + `runtime.connect()` (en-US) (バックグラウンドスクリプトに接続する場合)

これは `runtime.Port` (en-US) オブジェクトを返します。

* `runtime.onConnect` (en-US) リスナーには自身の `runtime.Port` (en-US) オブジェクトが渡される。

それぞれがポートを持ったら、両方が、

* `runtime.Port.postMessage()` でメッセージを送って
* `runtime.Port.onMessage` でメッセージを受信できるようになる。

例えば、ロードしたらすぐに、このコンテンツスクリプトは、

* バックグラウンドに接続し
* `myPort` 変数に `Port` を格納する
* `myPort` のメッセージを待ち受けする (ログに出す)
* ユーザーがドキュメントをクリックしたとき、バックグラウンドスクリプトに `myPort` を使ってメッセージを送る

```js
// content-script.js

let myPort = browser.runtime.connect({ name: "port-from-cs" });
myPort.postMessage({ greeting: "hello from content script" });

myPort.onMessage.addListener((m) => {
  console.log("In content script, received message from background script: ");
  console.log(m.greeting);
});

document.body.addEventListener("click", () => {
  myPort.postMessage({ greeting: "they clicked the page!" });
});
```

対応するバックグラウンドスクリプトは、

* コンテンツスクリプトからの通信試行を待ち受けする
* 通信試行を受け取ったとき、
    + `portFromCS` という名前の変数にポートを格納する
    + そのポートを使ってコンテンツスクリプトにメッセージを送る
    + ポートに届いたメッセージを待ち受けしてログに出す
* ユーザーが拡張機能のブラウザーアクションをクリックしたとき、`portFromCS` を使ってコンテンツスクリプトにメッセージを送る

```js
// background-script.js

let portFromCS;

function connected(p) {
  portFromCS = p;
  portFromCS.postMessage({ greeting: "hi there content script!" });
  portFromCS.onMessage.addListener((m) => {
    portFromCS.postMessage({
      greeting: `In background script, received message from content script: ${m.greeting}`,
    });
  });
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  portFromCS.postMessage({ greeting: "they clicked the button!" });
});
```

#### 複数のコンテンツスクリプト

同時に複数のコンテンツスクリプトが通信する場合、各接続を配列に格納するのが良いかもしれません。

```js
// background-script.js

let ports = [];

function connected(p) {
  ports[p.sender.tab.id] = p;
  // …
}

browser.runtime.onConnect.addListener(connected);

browser.browserAction.onClicked.addListener(() => {
  ports.forEach((p) => {
    p.postMessage({ greeting: "they clicked the button!" });
  });
});
```

### 単発メッセージとコネクションベースのメッセージとの選択

単発とコネクションベースのメッセージの選択は、拡張機能がどうメッセージを利用すると期待されるかに依存します。

推奨されるベストプラクティスは、次の通りです。

* **単発メッセージを使用する場合**
    + メッセージに 1 つだけの応答がある場合
    + メッセージの受信を少しのスクリプトが待ち受けする場合(`runtime.onMessage` 呼び出し)
* **コネクションベースのメッセージを使用する場合**
    + スクリプトが、複数のメッセージを交換するセッションに関わる場合
    + 拡張機能がタスクの進捗や、タスクが中断されたのを知る必要がある場合、または初期化されたタスクをメッセージング経由で中断したい場合
ウェブページとの通信
----------

既定では、コンテンツスクリプトはページスクリプトが作成したオブジェクトにアクセスできませんが、DOM `window.postMessage` と `window.addEventListener` API を使ってページスクリプトと通信できます。

例えば:

```js
// page-script.js

let messenger = document.getElementById("from-page-script");

messenger.addEventListener("click", messageContentScript);

function messageContentScript() {
  window.postMessage(
    {
      direction: "from-page-script",
      message: "Message from the page",
    },
    "\*",
  );
}
```

```js
// content-script.js

window.addEventListener("message", (event) => {
  if (
    event.source === window &&
    event?.data?.direction === "from-page-script"
  ) {
    alert(`Content script received message: "${event.data.message}"`);
  }
});
```

これの完全な動作サンプルは、GitHub のデモページに行って指示に従ってください。

**警告:** **この方法で信頼できないウェブコンテンツと相互作用するには細心の注意が必要です**！
 拡張機能は強力な力を持つコードの権限があり、敵意のあるウェブページは簡単にこの力にアクセスします。

細かい例を作るには、メッセージを受け取ったコンテンツスクリプトがこのようなことを行うと仮定してください:

```js
// content-script.js

window.addEventListener("message", (event) => {
  if (
    event.source === window &&
    event?.data?.direction === "from-page-script"
  ) {
    eval(event.data.message);
  }
});
```

今やページスクリプトはコンテンツスクリプトのすべての権限でコードを実行できます。

コンテンツスクリプト内で eval() を使う
-----------------------

**メモ:** `eval()` はマニフェスト V3 では利用できません。

Chrome では

`eval` は常にページコンテキストではなくて**コンテンツスクリプト**のコンテキストで動作します。

Firefox では

`eval()` を呼ぶ場合、**コンテンツスクリプト**のコンテキストで動作します。

`window.eval()` を呼ぶ場合、**ページ**のコンテキストで動作します。

例えば、こんなコンテンツスクリプトを考えてみます。

```js
// content-script.js

window.eval("window.x = 1;");
eval("window.y = 2");

console.log(`In content script, window.x: ${window.x}`);
console.log(`In content script, window.y: ${window.y}`);

window.postMessage(
  {
    message: "check",
  },
  "\*",
);
```

このコードは単に変数 x と y を、`window.eval()` と `eval()` を用いて作成し、値をログに出し、ページにメッセージします。

メッセージの受信に際し、ページスクリプトは同じ変数をログに出します。

```js
window.addEventListener("message", (event) => {
  if (event.source === window && event.data && event.data.message === "check") {
    console.log(`In page script, window.x: ${window.x}`);
    console.log(`In page script, window.y: ${window.y}`);
  }
});
```

Chrome では、こんな出力が生成されます:
```

In content script, window.x: 1
In content script, window.y: 2
In page script, window.x: undefined
In page script, window.y: undefined
```

Firefox では、こんな出力が生成されます:
```

In content script, window.x: undefined
In content script, window.y: 2
In page script, window.x: 1
In page script, window.y: undefined
```

同じことは `setTimeout()`、`setInterval()`、`Function()` にも言えます。

**警告:** ページのコンテキストでコードを実行するときは特に注意してください！

ページの環境が悪意をはらんだウェブページにコントロールされ、期待しない方法であなたが操作するオブジェクトを再定義するかもしれません。

```js
// page.js redefines console.log

let original = console.log;

console.log = () => {
  original(true);
};
```

```js
// content-script.js calls the redefined version

window.eval("console.log(false)");
```


ツールバーにボタンを追加する - Mozilla

ツールバーにボタンを追加する
==============

ツールバーボタンは拡張機能で利用できる主な UI コンポーネントです。ツールバーボタンはブラウザーツールバーに存在してアイコンを含んでいます。ユーザーがアイコンをクリックした時、下記の 2 つのいずれかが起こります:

* アイコンのポップアップを指定した場合、ポップアップが表示されます。ポップアップは HTML, CSS, JavaScript を使った一時的なダイアログです。
* ポップアップを指定していない場合、クリックイベントが生成され、コード内でそれをリッスンして、応答すべき他のアクションを実行できます。

WebExtension API では、こうしたボタンの種類は "ブラウザーアクション" と呼ばれ、次のようにセットアップされます:

* ボタンを定義するために使われる manifest.json の `browser_action` キー
* JavaScript API `browserAction` はコードに応じてクリックとボタンの変更をリッスンしたりアクションを実行します。
シンプルなボタン
--------

このセクションでは、ツールバーにボタンを追加する拡張機能を作ります。ユーザーがボタンをクリックしたときに https://developer.mozilla.org を新しいタブで開きます。

まず、新しいディレクトリー"button"を作り、そして"manifest.json"と呼ばれる、以下の内容のファイルを作ります:

```json
{
  "description": "Demonstrating toolbar buttons",
  "manifest\_version": 2,
  "name": "button-demo",
  "version": "1.0",

  "background": {
    "scripts": ["background.js"]
  },

  "browser\_action": {
    "default\_icon": {
      "16": "icons/page-16.png",
      "32": "icons/page-32.png"
    }
  }
}
```

これは "background.js"という名前のバックグラウンドスクリプトと、"icons"ディレクトリーにあるブラウザーアクション(ボタン)を指定します。

These icons are from the bitsies! iconset created by Recep Kütük.

次に、"buttons"ディレクトリー内に "icons" ディレクトリーを作成し、下記に表示されている 2 つのアイコンを保存します:

* "page-16.png" (
 ![](/ja/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar/page-16.png))
* "page-32.png" (
 ![](/ja/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar/page-32.png)).

高解像度ディスプレイで大きいのを使うように 2 つのアイコンがあります。ブラウザーは現在のディスプレイに最適なアイコンを選ぶよう配慮します。

次に、拡張機能のルートディレクトリー内の "background.js" を作り、次の中身を入れます:

```js
function openPage() {
  browser.tabs.create({
    url: "https://developer.mozilla.org",
  });
}

browser.browserAction.onClicked.addListener(openPage);
```

これはブラウザーアクションのクリックイベントをリッスンして、イベントが発火したとき、`openPage()` 関数が実行されて、`tabs` API を使って特定のページを開きます。

ここで完全な拡張機能は次のようです:
```

button/
    icons/
        page-16.png
        page-32.png
    background.js
    manifest.json
```

ここで拡張機能をインストールしてボタンをクリックします:

ポップアップを追加する
-----------

ボタンにポップアップを追加してみましょう。manifest.json を次のように置き換えます:

```json
{
  "description": "Demonstrating toolbar buttons",
  "manifest\_version": 2,
  "name": "button-demo",
  "version": "1.0",

  "browser\_action": {
    "browser\_style": true,
    "default\_popup": "popup/choose\_page.html",
    "default\_icon": {
      "16": "icons/page-16.png",
      "32": "icons/page-32.png"
    }
  }
}
```

オリジナルから 3 つの変更点があります:

* もう "background.js"は参照しません、なぜならポップアップスクリプト内で拡張機能のロジックを扱うためです (ポップアップと同様に background.js が許可されますが、この場合は不要です)。
* `"browser_style": true` を追加しており、これはポップアップがブラウザーの一部であるようなスタイリングに役立ちます。
* 最後に `"default_popup": "popup/choose_page.html"` を追加します。これはブラウザーアクションがクリック時にポップアップを表示し、"popup/choose\_page.html" に document があることをブラウザーに伝えます。

さてポップアップを作らねばなりません。"popup" というディレクトリーを作成してその中に "choose\_page.html" というファイルを作ります。中身は次の通り:

```html
<!doctype html>

<html>
  <head>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="choose\_page.css" />
  </head>

  <body>
    <div class="page-choice">developer.mozilla.org</div>
    <div class="page-choice">support.mozilla.org</div>
    <div class="page-choice">addons.mozilla.org</div>
    <script src="choose\_page.js"></script>
  </body>
</html>
```

これはふつうの HTML ページに 3 つの`<div>` 要素があり、その中に Mozilla サイトがあるのが分かるでしょう。また次で追加する CSS ファイルと JavaScript ファイルも入っています。

"popup" ディレクトリーに"choose\_page.css" というファイルを作って、次の中身を入れます:

```css
html,
body {
  width: 300px;
}

.page-choice {
  width: 100%;
  padding: 4px;
  font-size: 1.5em;
  text-align: center;
  cursor: pointer;
}

.page-choice:hover {
  background-color: #cff2f2;
}
```

これは単にポップアップのスタイリングです。

次に、"popup" ディレクトリーに"choose\_page.js" ファイルを作成し、次の中身を入れます:

```js
document.addEventListener("click", function (e) {
  if (!e.target.classList.contains("page-choice")) {
    return;
  }

  var chosenPage = "https://" + e.target.textContent;
  browser.tabs.create({
    url: chosenPage,
  });
});
```

この JavaScript で、ポップアップ選択のクリックをリッスンします。まずは page-choices にクリックがあったかをチェックし、そうでない場合は何もしません。クリックが page-choice にあった場合は、それから URL を作成し、対応するページを含む新規タブを開きます。注意として、バックグラウンドスクリプト内と同じように、ポップアップスクリプトでも WebExtension APIs を使用できます。

拡張機能の最終構造は次の通りです:
```

button/
    icons/
        page-16.png
        page-32.png
    popup/
        choose_page.css
        choose_page.html
        choose_page.js
    manifest.json
```

拡張機能を再読み込みし、もう一度ボタンをクリックし、ポップアップの選択をクリックしてみてください:

ページアクション
--------

ページアクション (en-US) はブラウザーアクションと同様ですが、ブラウザー全体でなく特定ページだけに関連するアクションという点だけが異なります。

ブラウザーアクションはいつも見えていて、ページアクションは関連するタブだけに見えています。ページアクションボタンはブラウザーツールバーでなく、URL バーに表示されます。

関連項目
----

* `browser_action` マニフェストキー
* `browserAction` API
* ブラウザーアクションの例:
    + beastify
    + Bookmark it!
    + favourite-colour
    + open-my-page-button
* `page_action` マニフェストキー
* `pageAction` (en-US) API
* ページアクションの例:
    + chill-out


developer tools の拡張 - Mozilla

developer tools の拡張
===================

**メモ:** このページでは、Firefox 55 に存在する devtools API について説明しています。この API はChrome devtools APIsに基づいていますが、まだ Firefox では実装されていないため、ここでは説明していません。現在欠けている機能を確認するには、devtools API の制限を参照してください。

WebExtensions API を使用して、ブラウザの組み込み開発者ツールを拡張できます。 devtools 拡張機能を作成するには、manifest.json に "devtools\_page" キーを含めます:

```json
"devtools\_page": "devtools/devtools-page.html"
```

このキーの値は、拡張機能にバンドルされている HTML ファイルを指す URL です。URL は manifest.json ファイル自体に関連する必要があります。

HTML ファイルは、devtools ページと呼ばれる特別なページを拡張機能で定義します。

devtools ページ
------------

devtools ページはブラウザの devtools を開くとロードされ、閉じるとアンロードされます。devtools ウィンドウは単一のタブに関連付けられているため、複数の devtools ウィンドウ、つまり複数の devtools ページが同時に存在する可能性が非常に高いことに注意してください。

devtools ページには目に見える DOM はありませんが、`<script>` タグを使用して JavaScript ソースを含めることができます。ソースは拡張機能自体にバンドルする必要があります。ソースは以下にアクセスできます:

* グローバル `window` オブジェクトを介してアクセス可能な通常の DOM API
* コンテンツスクリプトと同じ WebExtension API
* devtools API:
    + `devtools.inspectedWindow`
    + `devtools.network`
    + `devtools.panels`

devtools ページは他の WebExtension API にアクセスできず、バックグラウンドページは devtools API にアクセスできないことに注意してください。代わりに、devtools ページとバックグラウンドページは `runtime` メッセージング API を使用して通信する必要があります。ここに例があります:

```html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <script src="devtools.js"></script>
  </body>
</html>
```

devtools.js ファイルには、開発ツール拡張機能を作成する実際のコードが保持されます。

パネルの作成
------

devtools ウィンドウは、JavaScript デバッガ、ネットワークモニターなどの多数の個別ツールをホストします。上部にあるタブの行により、ユーザーはさまざまなツールを切り替えることができます。各ツールのユーザーインターフェイスをホストするウィンドウは「パネル」と呼ばれます。

`devtools.panels.create()` API を使用して、devtools ウィンドウに独自のパネルを作成できます:

```js
browser.devtools.panels
  .create(
    "My Panel", // title
    "icons/star.png", // icon
    "devtools/panel/panel.html", // content
  )
  .then((newPanel) => {
    newPanel.onShown.addListener(initialisePanel);
    newPanel.onHidden.addListener(unInitialisePanel);
  });
```

これにはパネルのタイトル、アイコン、コンテンツの 3 つの引数が必要です。新しいパネルを表す `devtools.panels.ExtensionPanel` オブジェクトに解決される `Promise` を返します。

ターゲットウィンドウとのインタラクション
--------------------

開発者ツールは常に特定のブラウザタブに添付されます。これは開発者ツールの「ターゲット」または「検出済みウィンドウ」と呼ばれます。`devtools.inspectedWindow` を使用して、検出されたウィンドウとインタラクションできます。

### ターゲットウィンドウでコードを実行する

`devtools.inspectedWindow.eval()` は、検出されたウィンドウでコードを実行する 1 つの方法を提供します。

これは `tabs.executeScript()` を使用してコンテンツスクリプトを挿入することに似ていますが、1 つの重要な違いがあります:

* コンテンツスクリプトとは異なり、**`devtools.inspectedWindow.eval()`** を使用してロードされたスクリプトは「DOM のクリーンビュー」を取得**しません**。つまり、ページスクリプトによって行われたページの変更を確認できます。

**メモ:** DOM のクリーンビューはセキュリティ機能であり、ネイティブ DOM 関数の動作を再定義することにより、悪意のあるページが拡張機能をだますことを防ぐのに役立つことに注意してください。これは eval() を使用する際に非常に注意する必要があることを意味し、可能であれば通常のコンテンツスクリプトを使用する必要があります。

`devtools.inspectedWindow.eval()` を使用してロードされたスクリプトも、コンテンツスクリプトで定義された JavaScript 変数を認識しません。

### コンテンツスクリプトの使用

devtools ドキュメントは `tabs.executeScript()` に直接アクセスできません。したがって、コンテンツスクリプトを挿入する必要がある場合、devtools ドキュメントはバックグラウンドスクリプトにメッセージを送信してスクリプトの挿入を要求する必要があります。`devtools.inspectedWindow.tabId` はターゲットタブの ID を提供します。devtools ドキュメントはこれをバックグラウンドスクリプトに渡すことができ、バックグラウンドスクリプトはそれを `tabs.executeScript()` に渡すことができます:

```js
// devtools-panel.js

const scriptToAttach = "document.body.innerHTML = 'Hi from the devtools';";

window.addEventListener("click", () => {
  browser.runtime.sendMessage({
    tabId: browser.devtools.inspectedWindow.tabId,
    script: scriptToAttach,
  });
});
```

```js
// background.js

function handleMessage(request, sender, sendResponse) {
  browser.tabs.executeScript(request.tabId, {
    code: request.script,
  });
}

browser.runtime.onMessage.addListener(handleMessage);
```

ターゲットウィンドウで実行されているコンテンツスクリプトと devtools ドキュメントの間でメッセージを交換する必要がある場合は、`runtime.connect()` (en-US) および `runtime.onConnect` (en-US) を使用してバックグラウンドページと devtools ドキュメント間の接続を設定することをお勧めします。バックグラウンドページはタブ ID と `runtime.Port` (en-US) オブジェクト間のマッピングを維持し、これを使用して 2 つのスコープ間でメッセージをルーティングできます。

![](/ja/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools/devtools-content-scripts.png)

devtools APIs の制限
-----------------

これらの API は Chrome devtools API に基づいていますが、Chrome と比較して多くの機能がまだありません。このセクションでは、Firefox 54 の時点でまだ実装されていない機能をリストします。devtools API は活発に開発中であり、将来のリリースでそれらのほとんどのサポートを追加する予定です。

### devtools.inspectedWindow

以下はサポートされていません:

* `inspectedWindow.getResources()`
* `inspectedWindow.onResourceAdded`
* `inspectedWindow.onResourceContentCommitted`

`inspectedWindow.eval()` のオプションはいずれもサポートされていません。

`inspectedWindow.eval()` を使用して挿入されたスクリプトは、コンソールのすべてのコマンドラインヘルパー関数を使用できませんが、 `$0` と `inspect(...)` の両方がサポートされています (Firefox 55 以降)。

### devtools.panels

以下はサポートされていません:

* `panels.elements`
* `panels.sources`
* `panels.setOpenResourceHandler()`
* `panels.openResource()`
* `panels.ExtensionPanel.createStatusBarButton()`
* `panels.Button`
* `panels.ElementsPanel`
* `panels.SourcesPanel`
例
-

GitHub の webextensions-examples リポジトリには、devtools パネルを使用する拡張機能のいくつかの例が含まれています。

* devtools-panels は devtools パネルを使用します:


次にどうするのか？ - Mozilla

次にどうするのか？
=========

ブラウザー拡張機能のアイデアを実現化していく準備ができているでしょう。開発の旅に出る前に、いくつかの注意点を意識することはスムーズに旅をする上で価値があります。

開発環境
----

ブラウザー拡張機能を開発するためには、どんな特別な開発ツールや環境構築も必要ありません。テキストエディターだけで素晴らしいブラウザー拡張機能を作成することはいくらでも可能です。しかし、ウェブ用の開発で再利用したいツールと環境を持っている場合もあるでしょう。その場合は、いくつかのことを意識する必要があります。

圧縮や難読化ツールを使用して最終コードを提出する場合には、AMO レビュープロセスにソースコードを提供する必要があります。また、使用するツール (圧縮、難読化、ビルド用) は、オープンソース (または無期限の無料提供) かつレビュー担当者のコンピューター上 (Windows、Mac、Linux) で実行可能である必要があります。残念ながらレビュー担当者は有償ツール、またはウェブベースのツールでは作業することができません。

ビルドツールに関する詳細

サードパーティライブラリー
-------------

サードパーティライブラリーはブラウザー拡張機能に複雑な特徴や機能性を素早く追加するための優れた手段です。AMO レビュープロセスに拡張機能を提出する時、どんなサードパーティライブラリーが使用されているかも検討されます。効率的なレビューのため、サードパーティライブラリーは常に公式ウェブサイトやリポジトリーからダウンロードし、ライブラリーが圧縮されている場合はソースコードへのリンクを提供してください。サードパーティライブラリーはいかなる方法でも変更できないことに注意してください。

ソースコードの提出に関する詳細

Firefox アドオン配布同意事項
------------------

Firefox のリリース版、またはベータ版にインストールを行うために、拡張機能に署名する必要があります。署名は、addons.mozilla.org (AMO) で行われ、Firefox アドオン配布同意事項の条件に従います。この契約の目的は、Firefox ユーザーに対し、Firefox での体験を強化するような、十分にサポートされた高品質のアドオンを提供することにあります。

同意約内容を確認する

署名に関する詳細

レビュープロセス
--------

署名のためにブラウザー拡張機能が提出されると、自動審査の対象となります。また、自動審査においてマニュアル審査が必要と判定された場合には、マニュアル審査の対象となる場合もあります。ブラウザー拡張機能は自動審査を通過するまで署名は行われず、マニュアル審査を通過しなかった場合に署名が取り消されることがあります。この審査の過程は厳密なガイドラインに従っているため、審査で問題になりそうな点を確認して回避することは簡単です。

レビューポリシーとガイドラインに関する詳細

AMO のおすすめブラウザー拡張機能
------------------

AMO にブラウザー拡張機能を掲載することを選んだ場合、拡張機能は AMO のウェブサイト、Firefox ブラウザーのアドオンマネージャー、または Mozilla のウェブサイト上のいずれかの場所に表示されます。拡張機能がどのようにおすすめとして選ばれるかを取り上げたガイドラインの一覧を作成しました。これらのガイドラインに従うことで、拡張機能をおすすめされるための最高の機会を得ることになります。

アドオンのおすすめに関する詳細

学習体験を続ける
--------

これまでの内容を知ったところで、今度はブラウザー拡張機能の開発について詳しく説明します。以下のセクションを確認してください:

* ブラウザー拡張機能の裏にある基本的なコンセプトについて、JavaScript API の使い方の詳細から説明します。
* ブラウザー拡張機能で利用できる、ユーザーインターフェイスコンポーネント のガイド。
* 拡張機能の主な課題を達成する方法や、JavaScript API の使用方法に関するガイドのまとめ。
* 他のブラウザー拡張機能を Firefox に移行する方法に関する情報。
* ブラウザー拡張機能の開発で使用できる Firefox 特有のワークフローの詳細について。
* JavaScript API に関するリファレンスガイド。
* マニフェストキーに関するリファレンスガイド。


拡張機能の例 - Mozilla

拡張機能の例
======

拡張機能の開発方法を分かりやすく説明するため、シンプルな拡張機能のサンプルを集めたリポジトリ https://github.com/mdn/webextensions-examples を公開しています。この記事では、そのリポジトリで使われている WebExtension API について説明します。

これらのサンプルは Firefox Nightly で動作します。ほとんどのものがより早期の Firefox でも動作しますが、拡張機能の manifest.json に指定されている `strict_min_version` キーを確認してください。

**警告:** いくつかの例では、特定のドメインまたはページでのみ動作します。制限事項の詳細は、各サンプルの readme ファイルに記載されています。どの例も既定ではプライベートブラウジングウィンドウでは動作しません。詳細は「プライベートブラウジングでの拡張機能」をご覧ください。

これらの例を試してみる場合は、リポジトリをクローンしてから下記のようにしてください。

1. 一時的なアドオンを読み込む (Load Temporary Add-on) 機能を使用する。拡張機能は Firefox を再起動するまで読み込まれたままになります。
2. コマンドラインで拡張機能のソースフォルダーを開き、 web-ext を使用して拡張機能を実行する。拡張機能は Firefox を再起動するまで読み込まれたままになります。
3. Firefox で **ファイル** > **ファイルを開く** を使用し、 build フォルダーにある例を探す。 `build` フォルダーにはビルドされ署名されたバージョンのすべての例が置いてあります。これは例を永続的にインストールします。

**警告:** この例の WebExtension を addons.mozilla.org (AMO) に投稿しないでください、WebExtension の例を実行するのに署名をする必要はありません。単に上記の手順に従ってください。

リポジトリに貢献したい方は、是非とも pull request を送ってください！

| Name | Description | JavaScript APIs |
| --- | --- | --- |
| annotate-page | Displays a sidebar that lets you take notes on web pages. | `storage.local``tabs.onActivated``tabs.onUpdated``tabs.query``tabs.Tab``windows.getCurrent``windows.Window` |
| apply-css | Adds a page action to the toolbar. Click the button to apply a red border using injected CSS. Click the button again to remove the CSS. | `pageAction.getTitle``pageAction.onClicked``pageAction.setIcon``pageAction.setTitle``pageAction.show``tabs.insertCSS``tabs.onUpdated``tabs.query``tabs.removeCSS``tabs.Tab` |
| beastify | Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. | `extension.getURL``runtime.onMessage``tabs.executeScript``tabs.insertCSS``tabs.query``tabs.removeCSS``tabs.sendMessage``tabs.Tab` |
| bookmark-it | Adds a bookmark button to the toolbar. Click the button to toggle a bookmark for the current page. | `bookmarks.create``bookmarks.onCreated``bookmarks.onRemoved``bookmarks.remove``bookmarks.search``browserAction.onClicked``browserAction.setIcon``browserAction.setTitle``tabs.onActivated``tabs.onUpdated``tabs.query``tabs.Tab``windows.onFocusChanged` |
| borderify | Adds a solid red border to all webpages matching mozilla.org. |  |
| chill-out | Show a page action after a period of inactivity. Show cat gifs when the page action is clicked. | `alarms.clearAll``alarms.create``alarms.onAlarm``pageAction.hide``pageAction.onClicked``pageAction.show``tabs.get``tabs.onActivated``tabs.onUpdated``tabs.query``tabs.update` |
| commands | Demonstrates using the commands API to set up a keyboard shortcut. The shortcut created is accessed using Ctrl+Shift+U (Command+Shift+U on a Mac). | `commands.getAll``commands.onCommand``commands.reset``commands.update``tabs.create` |
| content-script-register | Illustrates how an extension can register URL-matching content scripts at runtime. | `contentScripts.register``runtime.onMessage``runtime.sendMessage` |
| context-menu-copy-link-with-types | Add a context menu option to links to copy the link to the clipboard, as plain text and as a link in rich HTML. | `contextMenus.create``contextMenus.onClicked``tabs.executeScript` |
| contextual-identities | List, create, and remove contextual identities. | `contextualIdentities.query``tabs.create``tabs.query``tabs.remove` |
| cookie-bg-picker | Allows the user to customize the background color and tiled pattern on sites they visit, and also saves their preferences via a cookie, reapplying them whenever they revisit a site they previously customized. | `cookies.get``cookies.onChanged``cookies.remove``cookies.set``extension.getURL``runtime.onMessage``tabs.onActivated``tabs.onUpdated``tabs.query``tabs.Tab``tabs.sendMessage` |
| devtools-panels | Demonstrates some of the devtools APIs. | `devtools.inspectedWindow``devtools.panels``runtime.getURL``runtime.onMessage``runtime.sendMessage``tabs.executeScript` |
| discogs-search | Demonstrates adding a custom search engine with the chrome\_settings\_overrides key. |  |
| dnr-block-only | Demonstrates how to block network requests without host permissions using the declarativeNetRequest API with the `declarative\_net\_request` manifest key. | `declarativeNetRequest.Rule``declarativeNetRequest.RuleAction``declarativeNetRequest.RuleCondition` |
| dnr-dynamic-with-options | Demonstrates a generic way to request host permissions and register declarativeNetRequest rules to modify network requests, without any install-time permission warnings. The options\_ui page offers a way to request permissions and register DNR rules. | `declarativeNetRequest.Rule``declarativeNetRequest.getDynamicRules``declarativeNetRequest.getSessionRules``declarativeNetRequest.updateDynamicRules``declarativeNetRequest.updateSessionRules``permissions.getAll``permissions.remove``permissions.request` |
| dnr-redirect-url | Demonstrates multiple ways to redirect requests using the declarativeNetRequest API through the `declarative\_net\_request` manifest key. Demonstrates aspects of Manifest Version 3 (MV3): action, host\_permissions, and web\_accessible\_resources, and includes a comparison with Manifest Version 2 (MV2). | `declarativeNetRequest.Redirect``declarativeNetRequest.Rule``declarativeNetRequest.RuleAction``declarativeNetRequest.RuleCondition``declarativeNetRequest.URLTransform``permissions.contains``permissions.remove``permissions.request` |
| dynamic-theme | Dynamic theme example | `alarms.create``alarms.onAlarm``theme.update` |
| emoji-substitution | Replaces words with emojis. |  |
| eslint-example | Demonstrates how to configure an extension with eslint. |  |
| export-helpers | Demonstrates how to use export helpers like cloneInto to share objects with page scripts. | `notifications.create``runtime.onMessage``runtime.sendMessage` |
| favourite-colour | An example options page, letting you store your favourite colour. | `browserAction.onClicked``runtime.openOptionsPage``storage.managed``storage.sync` |
| find-across-tabs | Demonstration of the find API. | `browserAction.onClicked``extension.getBackgroundPage``find.find``find.highlightResults``runtime.getURL``runtime.onMessage``runtime.sendMessage``tabs.create``tabs.query``tabs.Tab` |
| firefox-code-search | Demonstrates how to use the omnibox API. | `omnibox.onInputChanged``omnibox.onInputEntered``omnibox.setDefaultSuggestion``tabs.create``tabs.update` |
| forget-it | Demonstrates how to use the browsingData API. | `browserAction.onClicked``browsingData.remove``notifications.create``storage.local` |
| google-userinfo | Demonstrates how to use the identity API. | `browserAction.onClicked``identity.getRedirectURL``identity.launchWebAuthFlow``notifications.create` |
| history-deleter | History API demo: deletes history items for a given domain | `history.deleteUrl``history.search``pageAction.show``tabs.onUpdated``tabs.query` |
| http-response | Demonstrates how to rewrite HTTP responses using the webRequest.filterResponseData() API. | `webRequest.filterResponseData``webRequest.onBeforeRequest` |
| imagify | Using a sidebar, illustrates the use of file picker and drag and drop. A content script replaces the current page content with the chosen image. | `extension.getURL``runtime.onMessage``tabs.executeScript``tabs.query``tabs.sendMessage` |
| latest-download | Shows the last downloaded item, and lets you open or delete it. | `downloads.erase``downloads.getFileIcon``downloads.open``downloads.removeFile``downloads.search` |
| list-cookies | This extensions list the cookies in the active tab. | `cookies.getAll``tabs.query` |
| menu-accesskey-visible | Shows how to set up a single letter access key for a menu item. | `i18n.getMessage``menus.update``menus.create``menus.onClicked` |
| menu-demo | Demonstrates adding and manipulating menu items using the menus API. | `i18n.getMessage``menus.create``menus.onClicked``menus.remove``menus.update``runtime.lastError``tabs.executeScript` |
| menu-labelled-open | Shows how an extension can listen for the display of a menu and then add, remove, or update its menu items. | `menus.create``menus.onClicked``menus.onShown``menus.refresh``menus.update``tabs.update` |
| menu-remove-element | Shows how to detect the page element at the cursor position and remove that element, or a parent element, from the page. This example includes use of the polyfill, illustrating cross-browser extension development. | `menus.create``menus.onClicked``menus.getTargetElement``pageAction.openPopup``pageAction.show``tabs.executeScript` |
| menu-search | Illustrates how to retrieve a list of search engines and issue a search request, using search engine details added to the context menu for selected text. | `search.search``search.get``menus.create``menus.onClicked` |
| mocha-client-tests | This example shows two methods of testing an extension: running tests from within the extension, and running tests from the command line using Karma. | `runtime.onMessage``runtime.sendMessage` |
| native-messaging | Example of native messaging, including a Python application and an extension which exchanges messages with it. | `browserAction.onClicked``runtime.connectNative` |
| navigation-stats | Demonstration of the webNavigation API, showing basic stats about which pages you've visited. | `storage.local``webNavigation.onCommitted``webNavigation.onCompleted` |
| notify-link-clicks-i18n | Shows a localized notification when the user clicks on links. | `extension.getURL``i18n.getMessage``notifications.create``runtime.onMessage``runtime.sendMessage` |
| open-my-page-button | Adds a browser action icon to the toolbar. When the browser action is clicked, the add-on opens a page that was packaged with it. | `browserAction.onClicked``tabs.create` |
| page-to-extension-messaging | Demonstrates how a web page and a content script can exchange messages. Visit https://mdn.github.io/webextensions-examples/content-script-page-script-messaging.html for the demo. |  |
| permissions | Demonstrates optional permissions using the permissions API. | `browserAction.onClicked``permissions.getAll``permissions.remove``permissions.request``runtime.getURL``tabs.create` |
| private-browsing-theme | Example dynamic theme: sets a dark theme for private windows. | `theme.reset``theme.update``windows.getAll``windows.onCreated` |
| proxy-blocker | Uses the proxy API to block requests to hosts specified on a list. | `extension.getURL``proxy.onRequest``proxy.onError``storage.local``storage.onChanged` |
| quicknote | Allows the user to make quick notes by clicking a button and entering text into the resulting popup. The notes are saved in storage. | `storage.local` |
| root-cert-stats | Shows how to get details about a request's TLS connection. | `webRequest.getSecurityInfo` |
| runtime-examples | Demo of various runtime APIs. | `browserAction.onClicked``notifications.create``runtime.getManifest``runtime.onInstalled``runtime.reload` |
| selection-to-clipboard | Demonstrates how to write to the clipboard from a content script |  |
| session-state | Demonstrates how to retrieve extension-defined state from restored tabs. | `menus.create``menus.onClicked``sessions.getTabValue``sessions.setTabValue``tabs.insertCSS``tabs.onCreated``tabs.onUpdated``tabs.query` |
| store-collected-images | Demonstrates how to use the idb-file-storage library to store and manipulate files in an extension. | `browserAction.onClicked``contextMenus.create``contextMenus.onClicked``runtime.onMessage``runtime.sendMessage``tabs.create``windows.create` |
| stored-credentials | Performs basic authentication by supplying stored credentials. | `storage.local``webRequest.onAuthRequired``webRequest.onCompleted``webRequest.onErrorOccurred` |
| tabs-tabs-tabs | Demonstrates tab manipulation: opening, closing, moving, zooming tabs. | `browserAction.setBadgeBackgroundColor``browserAction.setBadgeText``tabs.create``tabs.duplicate``tabs.getZoom``tabs.move``tabs.onCreated``tabs.onMoved``tabs.onRemoved``tabs.query``tabs.reload``tabs.remove``tabs.setZoom``tabs.Tab``tabs.update` |
| theme-integrated-sidebar | A sidebar that integrates with the current theme. | `theme.getCurrent``theme.onUpdated``windows.getCurrent` |
| theme-switcher | An example of how to use the management API for themes. | `management.getAll``management.setEnabled` |
| themes | A collection of themes illustrating:* weta\_fade: a basic theme employing a single image specified in `theme_frame:`.
* weta\_fade\_chrome: the weta\_fade theme implemented with Chrome compatible manifest keys.
* weta\_tiled: a theme using a tiled image.
* weta\_mirror: a theme using multiple images and aligning those images in the header.
* animated: use of an animated PNG.
 |  |
| top-sites | Demonstration of the topSites API. | `topSites.get` |
| user-agent-rewriter | Demonstrates using the webRequest API to rewrite the User-Agent HTTP header. | `extension.getBackgroundPage``webRequest.onBeforeSendHeaders` |
| user-script-register | Illustrates how an extension can register URL-matching user scripts at runtime. | `userScripts.register``runtime.onMessage``runtime.sendMessage` |
| webpack-modules | Demonstrates how to use webpack to package npm modules in an extension. | `runtime.onMessage``runtime.sendMessage` |
| window-manipulator | Demonstrates how to manipulate windows: opening, closing, resizing windows. | `windows.create``windows.getAll``windows.getCurrent``windows.remove``windows.update``windows.Window` |
| open-irc-links | Demonstrates the use of protocol handlers. |  |