Canvas LMS のコンテンツ HTML に書き込めるタグ・属性

Canvas LMS のHTMLエディタで利用できるタグ・属性の公式リストと、私が経験した公式リストと実環境の挙動の違いをメモした記事です。

## 背景
- Canvas LMS のコンテンツの実体はHTMLです。
- ユーザーは、コンテンツのテキストをリッチエディタでWYSIWYGで編集することもできるし、HTMLエディタでHTMLを編集することもできます。

## HTML編集の制限
- ただし、何でも書き込めるわけではありません。
- ユーザーが記述したHTMLでページ構成が崩れるなどのリスクがあるコードは書き込めなくなっているものと思われます。

### 利用できないコードを記述した際の挙動
- 利用できないコードも、書き込んで保存ボタンをクリックすることはできます。その際、何の警告も出ませんが、利用許可のない記述は自動的に削除されて保存されます。
    - 保存後に同じ文書を編集しHTMLエディタで表示すると、利用許可のない記述が保存されていないことを確認できます。
- 利用できない属性やプロパティを記述した場合、該当するコードだけが削除されます。
    - 例：`<div name="A" class="B">XYZ</div>` と記述して保存すると、`<div class="B">XYZ</div>` と保存されます。（利用できない `name` 属性だけが削除されます）

## HTMLエディタで利用を許可されたコード（要素・属性）のリスト
- [利用可能な要素のリスト](https://community.canvaslms.com/t5/Canvas-Resource-Documents/Canvas-HTML-Editor-Allowlist/ta-p/387066 "Canvas HTML Editor Allowlist")は開発元のウェブサイトにあります（英語）。
- 次項はその簡単な和訳です（和訳するほどでもありませんが）。
    - 閲覧日：2024-01-14
    - 閲覧時の記事の最新更新日：2021-07-07
- 実際には、このリストで使えることになっているコードが使えない（記述しても保存されない）ことがあったので、次々項にメモします。（職場のCanvas LMSでの経験。オープンソース版を改変したもので、バージョンは確認できません）

## 【公式】利用できるコード一覧
### HTMLタグ
```
a, acronym, address, area, article, aside, audio, b, bdo, big, blockquote, br, 
caption, cite, code, col, colgroup, dd, del, details, dfn, div, dl, dt, em, embed, 
footer, h2, h3, h4, h5, h6, header, hr, i, img, ins iframe, kbd, legend, li, map, 
nav, object, ol, p, param, picture, pre, q, ruby, rp, rt, samp, section, small, 
span, strike strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, time, 
tr, track, tt, u, ul, var, video
```
### MathMLタグ
```
annotation, annotation-xml, maction, maligngroup, malignmark, math, menclose, 
merror, mfenced, mfrac, mglyph, mi, mlabeledtr, mlongdiv, mmultiscripts, mn, mo, 
mover, mpadded, mphantom, mprescripts, mroot, mrow, ms, mscarries, mscarry, msgroup, 
msline, mspace, msqrt, msrow, mstack, mstyle, msub, msubsup, msup, mtable, mtd, 
mtext, mtr, munder, munderover, none, semantics, mark
```
### HTML要素の属性
- `style, class, id, title, role, lang, dir` 属性はすべての要素で利用できます。

| 要素 | 利用できる属性 |
|:-|:-|
|a|href, target, name|
|abbr|title|
|area|alt, coords, href, shape, target|
|aria|labelledby, atomic, busy, controls, describedby, disabled, dropeffect, flowto, grabbed, haspopup, hidden, invalid, label, labelledby, live, owns, relevant, autocomplete, checked, disabled, expanded, haspopup, hidden, invalid, label, level, multiline, multiselectable, orientation, pressed, readonly, required, selected, sort, valuemax, valuemin, valuenow, valuetext|
|audio|name, src, muted, controls|
|blockquote	cite|
|col|span, width|
|colgroup|span, width|
|embed|name, src, type, allowfullscreen, pluginspage, wmode, allowscriptaccess, width, height|
|font|face, color, size|
|img|align, alt, height, src, title, usemap, width|
|iframe|src, width, height, name, align, allowfullscreen|
|map|name|
|object|width, height, style, data, type, classid, codebase|
|ol|start, type|
|param|name, value|
|q|cite|
|source|Media, sizes, src, srcset, type|
|table|summary, width, border, cellpadding, cellspacing, center, frame, rules|
|tr|align, valign, dir|
|td|abbr, axis, colspan, rowspan, width, align, valign, dir|
|th|abbr, axis, colspan, rowspan, width, align, valign, dir, scope|
|ul|type|
|video|name, src, allowfullscreen, muted, poster, width, height, controls, playsinline|

### 要素・属性によっては利用できるプロトコル
#### ftp, http, https, mailto
- a href
#### http, https
- blockquote cite
- img src
- q cite
- object data
- embed src
- iframe src
- style どの属性でも
#### skype
- href

#### style属性で利用できるプロパティ
```
background, border, border-radius, clear, color, cursor, direction, display, flex, 
float, font, grid, height, left line-height, list-style, margin, max-height, 
max-width, min-height, min-width, overflow overflow-x, overflow-y, padding, 
position, right, text-align, table-layout text-decoration, text-indent, top, 
vertical-align, visibility, white-space, width z-index, zoom
```

## 職場の環境で経験した公式リストとの挙動の違い
- 私が経験したものであって、体系立てて検証したわけではありません。

#### `div` タグ
- 子要素がないと `div` タグでつくったブロックそのものが保存されません。

#### `object` タグ
- 保存する際に `p` タグで括られ、段落要素として保存されます。
    - ユーザーが明示的に `div` または `p` タグで括っていればさらに`p` タグで括られることはありません。

#### `param` タグ
- `object` タグの子要素として利用できます。`applet` タグは利用できません。