ASINページに本の情報を表示するブックマークレット

はてなブックマークレットの「asin記法を表示」をベースに、自分の好みの書式で表示するようにしてみた。

javascript:(function() {
  function getInnerText(node) {
    var nodes = node.childNodes;
    var ret = [];
    for (var i = 0; i < nodes.length; i++) {
      if (nodes[i].hasChildNodes())
        ret.push(getInnerText(nodes[i]));
      else if (nodes[i].nodeType == Node.TEXT_NODE)
        ret.push(nodes[i].nodeValue);
      else if (nodes[i].alt)
        ret.push(nodes[i].alt);
    }
    return ret.join('');
  }

  function div(s) {
    var d = document.createElement('div');
    with (d.style) {
      border = '1px solid #5279E7';
      margin = '10 5% 10 5%';
      padding = '2';
    }
    d.innerHTML = s;
    return d;
  }

  function textfield(value) {
    return '<input type=\'text\' size=\'100\' value=\'' + value + '\' onfocus=\'this.select()\' style=\'border:none\' />';
  }

  if (window.location.href.match(/^http:\/\/d\.hatena\.ne\.jp\/asin\/([^\/]+)$/)) {
    var asin = RegExp.$1;
    var h = document.getElementsByTagName('h1')[0];
    var p = h.previousSibling;
    if (p.nodeName == 'DIV') {
      h.parentNode.removeChild(p);
    } else {
      var title = h.firstChild.nodeValue;
      var authors = [];
      var nodes = document.getElementsByTagName('p');
      var asin_prefix = 'ASIN:';
      for (var i = 0; i < nodes.length; i++) {
        var t = getInnerText(nodes[i]);
        if (t.match(/作者:(.*)/)) {
          authors.push(RegExp.$1);
        } else if (t.match(/ISBN:/)) {
          asin_prefix = 'ISBN:';
        }
      }
      var author = authors.join(', ') + ' ';
      if (author != ' ')
        author = ' / ' + author;
      var d = div(textfield(title + author + asin_prefix + asin));
      h.parentNode.insertBefore(d, h);
    }
    window.scroll(0, 0);
  }
})();

getInnerText()の実装は要素の内部テキストを得る - outsider reflexから。また、MozillaでinnerTextでの議論も参考にした。