Rangeをメソッドチェーンで操作する(簡易版)

メソッドチェーンって直観的で分かりやすいと思うので、Rangeオブジェクトをメソッドチェーンで扱えるようにしてみました。
とりあえず版ですので、もっと充実させていく予定。
今のところ、ただのラッパーなんでIEでも動くと少しは実用性が出てくるかも。
Firefox3で動作確認してます。

使い方

HTML
<p id='test1'>aaaaaaaaaa</p>
<p id='test2'>bbbbbbbbbb</p>
<p id='test3'>cccccccccc</p>
JavaScript
window.addEventListener('load', function() {
  var
    test1 = document.getElementById('test1').firstChild,
    test2 = document.getElementById('test2').firstChild,
    test3 = document.getElementById('test3'),
    span = function(color) {
      var s = document.createElement('span');
      s.style.color = color;
      return s;
    };

  // id="test1"の3文字目から5文字目を赤くする
  new R()
    .start(test1, 3)
    .end(test1, 5)
    .wrap(span('red'))
    .detach();

  // id="test2"の文字列を青くする
  new R()
    .sel(test2)
    .wrap(span('blue'))
    .detach();

  // id="test3"の範囲選択した文字列を黄色にする
  test3.addEventListener('mouseup', function() {
    var selection = window.getSelection();

    new R(selection)
      .wrap(span('yellow'))
      .detach();
  }, false);

}, false);

ソース

(function() {
window.R = function(selection) {
  return R.fn.init(selection);
};

R.fn = {
  init: function(selection) {
    this.range = selection ? selection.getRangeAt(0) : document.createRange();
    return this;
  },

  start: function(node, index) {
    this.range.setStart(node, index || 0);
    return this;
  },

  end: function(node, index) {
    this.range.setEnd(node, index || 0);
    return this;
  },

  sel: function(node) {
    this.range.selectNode(node);
    return this;
  },

  wrap: function(elem) {
    this.range.surroundContents(elem);
    return this;
  },
  
  detach: function() {
    this.range.detach();
  }
};
})();