2010/07/19

ブラウザ三国志で書簡を保存するグリモンを修正

http://www.ai-mai.net/archives/2010/01/post-2.phpにて公開されていたGreasemonkeyスクリプトを取りあえず動くように修正。今回はChrome対応してません。(というか31行目jsonObj.toSource()が上手くいかなかった)自己責任でお願いします。

ファイルはこちら
// ==UserScript==
// @name           bura3_MailBox
// @description    書簡を保存する
// @include        http://*.3gokushi.jp/message/inbox.php
// @include        http://*.3gokushi.jp/message/inbox.php#*
// @include        http://*.3gokushi.jp/message/inbox.php?p=1*
// ==/UserScript==

var oldData = getData();
//初回(自ページから)のnext link
var nextUri = "";
//カウンタ
var offset = 0;
//本文内の情報を格納
var mailBoxSet = new Array();
//本文へのURIを格納
var mailUri =  new Array();

var LOCAL_STORAGE = "bro3_mailbox";

//XPath
function xpath(query,targetDoc) {return document.evaluate(query, targetDoc, null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);}

//GM永続データの取得
function getData(){
  return eval(GM_getValue(location.host + "MailBox"));
}

//GM永続データの保存
function setData(jsonObj){
  GM_setValue(location.host + "MailBox", jsonObj.toSource());
}

//渡されたHTMLデータから書簡本文へのリンクだけを抜き出す
function mailUriSet(htmlData){
  var htmlSnap = xpath("//table[@class='commonTables']/tbody/tr/td[2]/a", htmlData);
  for (i=0; i < htmlSnap.snapshotLength; i++){
    mailUri[offset] = htmlSnap.snapshotItem(i).href;
    offset++;
  }
  if (htmlData == document){
    //次に画面下部のnext linkから抜き出し
    nextUriFetch();
  }
}

//リンクを一気に取得
function nextUriFetch(){
  var nextXhr = new XMLHttpRequest();
  //nextXhr.open("GET",nextUri);
  //nextXhr.send(null);

 // nextXhr.onreadystatechange = function(){
  //  if(nextXhr.readyState ==4){
  //    if(nextXhr.status == 200){
        //パーサーチックに
        var newDiv = document.createElement("div");
        newDiv.innerHTML = nextXhr.responseText;
        //パースしたのをmailUriSetに投げる。
        mailUriSet(newDiv);
        //スマートじゃないけど面倒臭いからこれで
        try{
            nextUri = newDiv.getElementsByClassName("last")[1].childNodes[0].href
        }
        catch(e){
          offset = 0;
          //アーカイブと同じIDのは削除する。
          var tmpIdx = 0;
          var changeFlag = false;
          if(oldData){
            for(var i=0; i < mailUri.length;){
              for(var j=0; j<oldData.length; j++){
                if(oldData[j][0] == mailUri[i].match("id=[0-9]+")[0].split("=")[1]){
                  changeFlag = true;
                  break;
                }
              }
              if(changeFlag){
                mailUri.splice(i,1);
                changeFlag = false;
              }
              else{
                i++;
              }
            }
          }
          //nextをすべて抜き出しおわったら本文内の処理をやっていく。
          xhr();
          return;
        }
        nextUriFetch();
      //}
    //}
  //}
}

//XHR用の再帰関数
function xhr(){
  //オブジェクトが無かったらおしまい。
  if(!mailUri[offset]){
    //make save data
    makeSaveData();
    nextUri = document.getElementsByClassName("last")[1].childNodes[0].href;
    alert("保存処理が終わりました。");
    return 0;
  }
  targetUri = mailUri[offset];
  //XHR
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open("GET",targetUri);
  xmlhttp.send(null);
  //ステータスチェンジで発生するイベント
  xmlhttp.onreadystatechange = function(){
    //ifネストしてるのはキャッシュ判定とかのためだけどたぶん使わない
    if(xmlhttp.readyState ==4){
      if(xmlhttp.status == 200){
        //パーサー
        var responseXML = document.createElement("div");
        responseXML.innerHTML = xmlhttp.responseText;
        //書簡の部分だけを取得
        var message = responseXML.getElementsByClassName("ttl w80");
        mailBoxSet[offset] = new Array();
        //uriのIDをメッセージIDにしてunique管理
        mailBoxSet[offset][0] = targetUri.match("id=[0-9]+")[0].split("=")[1];
        for(var i=0; i<message .length; i++){
            mailBoxSet[offset][i+1]  = message [i].parentNode.getElementsByTagName("td")[0].innerHTML
        }
        offset++;
        xhr();
      }
    }
  }
}

function makeSaveData(){
  var saveData = getData();
  if(saveData){
    var numOfOld = saveData.length;
  }
  else{
    var numOfOld = 0;
    saveData = new Array();
  }
  for(i=0; i < mailBoxSet.length; i++){
    saveData[numOfOld + i] = mailBoxSet[i];
  }
  setData(saveData);
}

function startSave(){
  //まずは自ページ(p=1)から書簡本文リンクの抜き出し
  mailUriSet(document);
}

//このへんから実行
initGMWrapper();
var mailMenu = document.getElementById("statMenu");

//保存用
var saveButton = document.createElement("span");
saveButton.innerHTML = "<input id='saveMail' type='button' value='書簡保存' />";
saveButton.id = "saveButton";
saveButton.style.padding = "0 10px 0 0";
mailMenu.appendChild(saveButton);

//表示
var archiveButton = document.createElement("span");
archiveButton.innerHTML = "<input id='archiveButton' type='button' value='アーカイブ' />";
archiveButton.id = "archivebutton";
archiveButton.style.padding = "0 10px 0 0";
mailMenu.appendChild(archiveButton);

//削除
var delButton = document.createElement("span");
delButton.innerHTML = "<input id='delButton' type='button' value='削除' />";
delButton.id = "delButton";
delButton.style.padding = "0 10px 0 0";
mailMenu.appendChild(delButton);

document.getElementById("saveButton").addEventListener("click",
    function() {
        oldData = getData();
        nextUri = document.getElementsByClassName("last")[1].childNodes[0].href;
        mailBoxSet = []
        //本文へのURIを格納
        mailUri =  []
        offset = 0;
        startSave();
    },true);

document.getElementById("archiveButton").addEventListener("click",
  function() {
    var archiveInner = "";
    var archiveData = getData();
    if(archiveData){
      for(var i=0; i < archiveData.length; i++){
        archiveInner += 
          "<tr><td><input name='chk[]' value='" + archiveData[i][0] + "' type='checkbox'>" +
          "</td><td><a href='javascript:void(0)' name='mboxTitle' id='" + archiveData[i][0] + "'>" + archiveData[i][4] + "</a>" +
          "</td><td>" + archiveData[i][1] +
          "</td><td class='fs77'>" + archiveData[i][3] +
          "</td></tr>";
      }
      var tableHead = "<tbody><tr><th class='ttl w30'>選択</th><th class='ttl w300'>件名</th><th class='ttl'>送信者</th><th class='ttl w120'>送信時間</th></tr><tr></tr>";
      var tableFoot = "</tbody>";
      document.getElementsByClassName("commonTables")[0].innerHTML = tableHead + archiveInner + tableFoot;
      //本文表示イベントリスナーの設定
      var mboxTitle = document.getElementsByName("mboxTitle");
      for(var i=0; i<mboxTitle.length; i++){
        (function(i){
          mboxTitle[i].addEventListener("click",function(){
              for(var j=0; j<archiveData.length; j++){
                if(archiveData[j][0] == mboxTitle[i].id){
                  var mesinnerHTML = "<tbody><tr><th class='ttl w80'>送信者</th><td>" + archiveData[j][1] +
                                     "</td></tr><tr><th class='ttl w80'>宛先</th><td>" + archiveData[j][2] +
                                     "</td></tr><tr><th class='ttl w80'>日時</th><td>" + archiveData[j][3] +
                                     "</td></tr><tr><th class='ttl w80'>件名</th><td>" + archiveData[j][4] +
                                     "</tr><tr><th class='ttl w80'>本文</th><td>" +archiveData[j][5] + "</td></tr></tbody>";
                  document.getElementsByClassName("commonTables")[0].innerHTML = mesinnerHTML;
                  return;
                }
              }
          },false);
        })(i);
      }
    }
    else{
      alert("アーカイブデータはありません。")
    }
  },true
);

document.getElementById("delButton").addEventListener("click",
   function() {
      if(confirm('全てのデータを削除します。')){
        GM_setValue(location.host + "MailBox", "")
        alert("削除しました。")
      }
    },true);

//Google Chrome用GM_*系ラッパー関数
function initGMWrapper() {
  // @copyright   2009, James Campos
 // @license  cc-by-3.0; http://creativecommons.org/licenses/by/3.0/
 if ((typeof GM_getValue == 'undefined') || (GM_getValue('a', 'b') == undefined)) {
  GM_addStyle = function(css) {
   var style = document.createElement('style');
   style.textContent = css;
   document.getElementsByTagName('head')[0].appendChild(style);
  }

  GM_deleteValue = function(name) {
   localStorage.removeItem(LOCAL_STORAGE + "." + name);
  }

  GM_getValue = function(name, defaultValue) {
   var value = localStorage.getItem(LOCAL_STORAGE + "." + name);
   if (!value)
    return defaultValue;
   var type = value[0];
   value = value.substring(1);
   switch (type) {
    case 'b':
     return value == 'true';
    case 'n':
     return Number(value);
    default:
     return value;
   }
  }

  GM_log = function(message) {
   console.log(message);
  }

  GM_registerMenuCommand = function(name, funk) {
  //todo
  }

  GM_setValue = function(name, value) {
   value = (typeof value)[0] + value;
   localStorage.setItem(LOCAL_STORAGE + "." + name, value);
  }
  
  //by froo
  GM_listValues = function() {
   var res = new Array();
   for (var i = 0; i < localStorage.length; i++) {
    var key = localStorage.key(i);
    if (key.indexOf(LOCAL_STORAGE + ".", 0) == 0) {
     res.push(key.replace(/^.*?\./, ""));
    }
   }
   return res;
  }
 }
}

0 件のコメント: