ブラウザエディタの出発点

ブラウザでリッチテキストエディタを作るときは
ここから機能を追加したり削除したり
デザインを綺麗にしたり

[w3c HTML Editing APIs](https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html)

```editor.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" media="screen" href="stylesheets/bootstrapicon.css">
<style type="text/css">
a {
  background-color:#ffffff;
  border:1px solid #dcdcdc;
  display:inline-block;
  color:#666666;
  font-family:arial;
  font-size:15px;
  padding:6px 9px;
  text-decoration:none;
  text-shadow:1px 1px 0px #ffffff;
}a:hover {
  background-color:#f6f6f6;
}a:active {
  position:relative;
  top:1px;
}
/* This imageless css button was generated by CSSButtonGenerator.com */
</style>
<script type="text/javascript">
<!--
var editableDocument = null;

window.onload = function()
{
    editableDocument = document.getElementById("iframe01").contentDocument;
    editableDocument.designMode = "on";
    editableDocument.addEventListener("keyup", showText, true);
}

function showText(event)
{
    document.getElementById("textarea01").value = document.getElementById("iframe01").contentWindow.document.body.innerHTML;
}

function setDesign()
{
    document.getElementById("iframe01").contentWindow.document.body.innerHTML = document.getElementById("textarea01").value;
}
function setColor(obj)
{
    if(7 == obj.value.length)
    {
        obj.style.backgroundColor = obj.value;
        obj.style.color = InactiveBorder;
    }
}
function closeLittleWindow()
{
    var objs = document.getElementsByName('littleWindow');
    for(i=0;i<objs.length;i++)
    {
        objs[i].style.display = 'none';
    }
}
//-->
</script>
</head>
<body>
<a href="#" class="btn" onclick="">保存</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('copy',false,null)">コピー</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('cut',false,null)">✄</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('paste',false,null)">貼付</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('selectAll',false,null)">全選択</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('undo',false,null)">↶</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('redo',false,null)">↷</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('justifyLeft',false,null)">左寄せ</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('justifyCenter',false,null)">中寄せ</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('justifyRight',false,null)">右寄せ</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('justifyFull',false,null)">幅揃え</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('indent',false,null)">インデント</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('outdent',false,null)">インデント取消</i></a>
<select id="formatblock">
  <option value="<h1>">h1</option>
  <option value="<h2>">h2</option>
  <option value="<h3>">h3</option>
  <option value="<h4>">h4</option>
  <option value="<h5>">h5</option>
  <option value="<h6>">h6</option>
  <option value="<pre>">pre</option>
</select>
<a href="#" class="btn" onclick="editableDocument.execCommand('formatBlock',false,document.getElementById('formatblock').options[document.getElementById('formatblock').selectedIndex].value)">タグ</a>
<br />
<a href="#" class="btn" onclick="editableDocument.execCommand('insertLineBreak',false,null)">br</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('insertParagraph',false,null)">p</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('insertHorizontalRule',false,null)">hr</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('bold',false,null)"><b>B</b></a>
<a href="#" class="btn" onclick="editableDocument.execCommand('italic',false,null)"><i>I</i></a>
<a href="#" class="btn" onclick="editableDocument.execCommand('underline',false,null)"><u>U</u></a>
<a href="#" class="btn" onclick="editableDocument.execCommand('strikethrough',false,null)"><strike>S</strike></a>
<a href="#" class="btn" onclick="editableDocument.execCommand('subscript',false,null)">X<sub>2</sub></a>
<a href="#" class="btn" onclick="editableDocument.execCommand('superscript',false,null)">X<sup>2</sup></a>
<input type="text" id="forecolor" style="width:8em;" onkeyup="setColor(this);" placeholder="#000000" value="#ffffff"/>
<a href="#" class="btn" onclick="editableDocument.execCommand('foreColor',false,document.getElementById('forecolor').value)">文字色</a>
<input type="text" id="hilitecolor" style="width:8em;" onkeyup="setColor(this);" placeholder="#000000" value="#ffffff"/>
<a href="#" class="btn" onclick="editableDocument.execCommand('hiliteColor',false,document.getElementById('hilitecolor').value)">選択色</a>
<select id="fontsize">
  <option value="1">x-small</option>
  <option value="2">small</option>
  <option value="3" selected="selected">normal</option>
  <option value="4">large</option>
  <option value="5">x-large</option>
  <option value="6">xx-large</option>
  <option value="7">xxx-large</option>
</select>
<a href="#" class="btn" onclick="editableDocument.execCommand('fontSize',false,document.getElementById('fontsize').options[document.getElementById('fontsize').selectedIndex].value)">フォントサイズ</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('removeFormat',false,null)">タグ消去</a>
<br />
<input type="text" id="createlink" placeholder="http://wwww." value=""/>
<a href="#" class="btn" onclick="editableDocument.execCommand('createLink',false,document.getElementById('createlink').value)">リンク</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('unlink',false,null)">リンク解除</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('insertOrderedList',false,null)">順序リスト</a>
<a href="#" class="btn" onclick="editableDocument.execCommand('insertUnorderedList',false,null)">リスト</a>
<a href="#" class="btn" onclick="winRuby();"><ruby>亜<rp>【</rp><rt>あ</rt><rp></rp></ruby></a>
<a href="#" class="btn" onclick="winImagebase64();">画像</a>
<script>
/* ルビ入力窓 */
function winRuby()
{
    document.getElementById('ruby').style.display = 'block';
}
<!-- イメージ挿入用小窓 -->
function winImagebase64()
{
    document.getElementById('imagebase64').style.display = 'block';
}
</script>
<br />
<iframe id="iframe01"></iframe>
<br />
<textarea id="textarea01" name="textarea01" onKeyup="setDesign();"></textarea>
<br />

<!-- ルビ入力用小窓 -->
<div id="ruby" name="littleWindow" style="display:none;position:fixed;border:3px solid #444444;backgroundColor:#ffffff;">
  <table style="border-collapse:collapse;width:100%;" bgcolor="#ffffff">
    <tr>
      <th colspan="2" bgcolor="#eeeeee" style="padding:7px;border:1px solid #444444;">ルビ</th>
    </tr>
    <tr>
      <td>ルビを付ける文字</td><td><input type="text" id="ruby01"  style="padding:4px;text-align:left;" value="" /></td>
    </tr>
    <tr>
      <td>ルビ</td><td><input type="text" id="ruby02" style="padding:4px;text-align:left;" value="" /></td>
    </tr>
    <tr>
      <td>ルビが非対応だった場合のカッコ</td>
      <td>
        <select id="ruby03" style="padding:4px;text-align:left;">
          <option value="1">【】</opiton>
          <option value="2">[]</opiton>
          <option value="3">()</opiton>
          <option value="4">（）</opiton>
        </select>
      </td>
    </tr>
    <tr>
    <td colspan="2"><input type="button" style="padding:4px;" value="挿入" onclick="addRuby('textarea01');"/>
        <input type="button" style="padding:4px;" value="キャンセル" onclick="closeLittleWindow();"/></td>
    </tr>
  </table>
</div>
<script>
function addRuby(objid)
{
    var str01 = document.getElementById('ruby01').value;
    var str02 = document.getElementById('ruby02').value;
    var obj03 = document.getElementById('ruby03');
    var str03 = obj03.options[obj03.selectedIndex].text;
    var str = "<ruby>" + str01 + "<rp>" + str03.charAt(0) + "</rp><rt>" + str02 + "</rt><rp>" + str03.charAt(1) + "</rp></ruby>";
    editableDocument.execCommand('insertHTML',false,str);
    document.getElementById('ruby').style.display = 'none';
}
</script>
<!-- イメージ挿入用小窓 -->
<div id="imagebase64" name="littleWindow" style="display:none;position:fixed;border:3px solid #444444;backgroundColor:#ffffff;">
  <table style="border-collapse:collapse;width:100%;" bgcolor="#ffffff">
    <tr>
      <th colspan="2" bgcolor="#eeeeee" style="padding:7px;border:1px solid #444444;">画像選択</th>
    </tr>
    <tr>
    <td colspan="2"><input type="file" onchange="base64(event)" style="width:100%"></td>
    </tr>
  </table>
</div>
<script>
function base64(e)
{
  var file = e.target.files[0]
  if(file)
  {
    readfile(file);
  }
}
function readfile(file)
{
  var reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = loaded;
}
function loaded(e)
{
  editableDocument.execCommand('insertHTML',false,"<img src='" + e.target.result + "' alt='' />");
  document.getElementById('imagebase64').style.display = 'none';
}
</script>
</body>
</html>
```