m2

ブックマークレットの状態を保存する

ブックマークのものはブックマークに。IE6不可。
bookmarklet:

改行付き:

(function main(data) {
  // 保存用の関数
  function save(obj) {
    prompt(
      'これをブックマークしてください。',
      'javascript:' + encodeURIComponent('(' + main.toString().replace(/\s*\r?\n\s*/g,'') + ')(' + toJSON(obj) + ')')
    );
  }
  function toJSON(o) {
    if (o == void(0)) {
      return 'null';
    }
    var c = o.constructor;
    if (c == Boolean) {
      return o.toString();
    }
    if (c == Number) {
      return isNaN(o) ? '"NaN"' : !isFinite(o) ? '"Infinity"' : o.toString(10);
    }
    if (c == String) {
      return '"' + esc(o) + '"';
    }
    if (c == Array) {
      var tmp = [];
      for (var i=0; i<o.length; i++) {
        tmp[i] = toJSON(o[i]);
      }
      return '[' + tmp.join(',') + ']';
    }
    if (o.toString() == '[object Object]') { // Opera では DOMNode の コンストラクタも Object.
      var tmp = [];
      for (var i in o) {
        if (o.hasOwnProperty(i)) {
          tmp.push('"' + esc(i) + '":' + toJSON(o[i]));
        }
      }
      return '{' + tmp.join(',') + '}';
    }
    return '\"' + esc(o.toString()) + '\"';
  }
  function esc(s) {
    return escape(s).replace(/%([0-9A-F]{2})/g,'\\u00$1').replace(/%u/g,'\\u');
  }
  // ここから本来の実装
  var dv = document.createElement('div');
  dv.style.cssText = 'width: 30em; padding: 5px; position: absolute; top: 20px; left: 20px; background-color: white; border: black solid 1px';
  dv.innerHTML = '<textarea style="width: 100%;height: 7em;display: block"></textarea><button>保存</button><button>閉じる</button>';
  document.body.appendChild(dv);
  if(data){ dv.childNodes[0].value = data.text.join('\n') } // データの復元
  dv.childNodes[1].addEventListener('click', function(){ save( { text: dv.childNodes[0].value.split(/\r?\n/) } )}, false);
  dv.childNodes[2].addEventListener('click', function(){ dv.parentNode.removeChild(dv) }, false);
  // Drag & Drop
  DD(dv);
  function DD(a){
    var d=document,s=a.style,p,f,x,y,E='addEventListener';
    s.cursor='move';
    s.position='absolute';
    s.zIndex='10';
    a[E]('mousedown',function(e){
        f=1;
        p=a;
        x=e.pageX;
        y=e.pageY;
        while(p)x-=p.offsetLeft,y-=p.offsetTop,p=p.offsetParent;
    },0);
    d[E]('mousemove',function(e){
        if(f)s.left=e.pageX-x+'px',s.top=e.pageY-y+'px'
    },0);
    d[E]('mouseup',function(){f=0},0);
  }
})()
  • -

追記
修正しました。主に toJSON の修正です。
配列に対して無意味に破壊的だったり、 JSON の仕様に従っていなかったりしていたのを修正しました。Object に循環参照があると無限ループするのは変わりません(仕様です)。

toJSON については以下のページが大変参考になりました(参考というよりほとんど同じコードになっちゃいました)。ありがとうございます。