Home > Latest topics

Latest topics > ハイライト表示のためにテキストフィールド内に挿入されたspan要素が邪魔になる件

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

ハイライト表示のためにテキストフィールド内に挿入されたspan要素が邪魔になる件 - May 04, 2008

前のエントリの続き。

Safari風ハイライトに限らず元々、Firefoxの検索での「すべて強調表示」では、背景色と文字色を指定したspan要素を検索がヒットした箇所に動的に埋め込むという形で、ハイライト表示を実現している。これはinput要素やtextarea要素の場合でも全く同じ。実はFirefoxではテキスト入力欄もすべて、内部的には編集可能なHTMLとして実装されていて、それ故にspan要素の埋め込みも可能になっている。

ただ、この時span要素が埋め込まれる先のDOMツリーはchildNodesとかのプロパティでは辿れない場所にあって、アクセスするにはこんな風にする必要がある。

var editable = content.document.getElementsByTagName('textarea')[0];
var nodesInEditable = editable
     .QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
     .editor
     .rootElement
     .childNodes;

textareaでこれをやってみると、改行が内部的にはbr要素で表現されているとかそういうのも見て取れる。nsIFindで検索する時はテキストフィールド内のこうした「隠しDOMツリー」も普通に検索対象になるようで、span要素を埋め込む時も特に変わったことはしなくていいようだ。

しかし、ここで一つ問題がある。こうしてテキストフィールド内に普通のspan要素を埋め込んでしまうと、その要素は、選択も内部の文字の編集もできない、ワープロでいえば埋め込まれた画像みたいな状態になってしまう。普段は特に意識せずに済むけど、常に強調表示を有効にするようにしていると当然テキストフィールド内でハイライト表示が行われることになる場合も多くなり、この問題が目につくようになってくる。というか僕自身がテスト用ドキュメントでテストしていて、いいかげんウザくなってきたのでなんとかしたかった。

理想的には、テキストフィールドにフォーカスされた時に自動的に強調表示を解除するという風な挙動にできるとよかったんだけど、試してみるとどうもなかなか大変そうだということが分かった。挿入されるspan要素にonclickなどの属性でイベントハンドラを設定してみたところ、getAttributeやdispatchEventなどのメソッド、あるいはparentNodeなどのプロパティを参照しようとするとパーミッションエラーが表示されてしまった。これではnode.parentNode.removeChild()という風なことができないし、独自イベントを発行してChrome領域のスクリプトに後の処理を任せるということもできない。

これについては幸いにも、createRangeなどの機能は使うことができるようだったので、deleteContentsやextractContentsを使って自分自身を削除させるようにはできた。強調表示された箇所を選択して「選択範囲のソース」を表示してみれば、こんな風になっていることが分かると思う。

<h1>B.B.S. <span class="sub"><span onmousedown="
  try {
    var xpathResult = this.ownerDocument.evaluate(
        'ancestor::*[contains(&quot; INPUT input TEXTAREA textarea &quot;, concat(&quot; &quot;, local-name(), &quot; &quot;))]',
        this,
        null,
        XPathResult.FIRST_ORDERED_NODE_TYPE,
        null
      );
    if (!xpathResult.singleNodeValue) return;
  }
  catch(e) {
    // permission denied, then this is in the input area!
  }
  var range = document.createRange();
  range.selectNodeContents(this);
  var contents = range.extractContents(true);
  range.selectNode(this);
  range.deleteContents();
  range.insertNode(contents);
  range.detach();
" id="__firefox-findbar-search-id" style="...">掲示板</span></span></h1>

無駄とは分かっていても一応、正攻法の判別処理も入れてある。テキストフィールド以外の部分に挿入されたspanにも全部このイベントハンドラが設定されてしまうのは、挿入先に応じて挿入する内容を変えるのがめんどかったから。まあとりあえず、これがあっても正常に動かなくなるわけではないし、別にいいかなと。

これだとキーボード操作に対して反応させることができない(そもそもカーソルをspanの中に移動できない)し、本当は特にクリック等の操作をしなくても、テキストフィールドにフォーカスが当たった時点で強調表示を解除するという風な挙動を実現したかったわけで、そこら辺まだまだ改善の余地はある。

分類:Mozilla > 拡張機能 > xulmigemo, , , , , , , , 時刻:08:19 | Comments/Trackbacks (0) | Edit

Comments/Trackbacks

TrackBack ping me at


の末尾に2020年11月30日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2008-05-04_highlight.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

writeback message: Ready to post a comment.

2020年11月30日時点の日本の首相のファミリーネーム(ひらがなで回答)

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき