Googleウェブ履歴にサムネイルとfaviconを表示するGreasemonkeyスクリプト

スクリーンショット:

// ==UserScript==
// @name           Show Thumbnail in Google History
// @namespace      http://d.hatena.ne.jp/nozom/
// @include        http://www.google.*/history/*
// ==/UserScript==
 
(function(){
 
  function getLink(a) {
    var link = a.href;
    if (link.match(/\?url=([^&]*)/)) {
      link = decodeURIComponent(RegExp.$1);
      return link;
    }
    return null;
  }
 
  function createFavicon(link) {
    var a = document.createElement('a');
    a.href = link;
 
    var favicon = document.createElement('img');
    favicon.src = "http://" + a.hostname + "/favicon.ico";
    favicon.alt   = "";
    favicon.style.width = '16px';
    favicon.style.border = '0px';
    favicon.style.backgroundColor = '#ffffff';
 
    var container = document.createElement('div');
    container.style.cssFloat = 'left';
    container.style.minWidth = '16px';
    container.style.minHeight = '16px';
    container.style.backgroundImage = 'url("chrome://global/skin/icons/folder-item.png")';
    container.appendChild(favicon);
 
    return container;
  }
 
  function createImage(link) {
    var api = "http://img.simpleapi.net/small/";
    var img = document.createElement('img');
    img.src = api + link;
    img.style.border = '0px';
    return img;
  }
 
  function init() {
    var internal_link = true;
    var external_link = true;
  
    var tmpimg = document.createElement('img');
  
    var nodes = document.getElementsByTagName('a');
    for (var i = 0, len = nodes.length; i < len; i++) {
      var a = nodes[i];
      tmpimg.src = a.href;
      var link = tmpimg.src;
      if (!link.match(/^http/)) continue;
      var is_internal_link = link.match(location.hostname);
      if ((internal_link && is_internal_link) || (external_link && !is_internal_link)) {
        addFavicon(a);
        addZoomImage(a);
      }
    }
  }
 
  function addFavicon(a) {
    var link = getLink(a);
    if (link) {
      var img = createFavicon(link);
      if (img) {
        var span = document.createElement('span');
        span.appendChild(img);
 
        a.insertBefore(span, a.firstChild);
      }
    }
  }
 
  function addZoomImage(a) {
    var link = getLink(a);
    if (link == null) return;
 
    var span = document.createElement('span');
    span.style.position = 'absolute';
    span.style.margin   = '-10px 0 0 5px';
    span.style.display  = 'none';
 
    a.appendChild(span);
 
    a.addEventListener('mouseover', function(e) {
      var a = this;
      var span = a.lastChild;
      if (!span.firstChild) {
        var link = getLink(a);
        if (link) {
          var img = createImage(link);
          if (img) {
            // img.style.width    = '256px';
            // img.style.height   = '256px';
 
            span.appendChild(img);
          }
        } else {
          span.appendChild(document.createTextContent(" "));
        }
      }
      span.style.display = 'inline';
    }, true);
    a.addEventListener('mouseout', function(e) {
      var a = this;
      var span = a.lastChild;
      span.style.display = 'none';
    }, true);
  }
 
  init();
})()

SimpleAPIのウェブサイトサムネイル作成APIを使用しています。

参考にしたページ

(2007-11-19追記)