ニコニコ動画でcookieにマイリスト登録するGreasemonkeyスクリプト

http://d.hatena.ne.jp/shrkw/20070623で更新版をのせてるので、そっちをみたほうがいいかもしれません。

マイリストは100個以上登録したいけど、お金を払いたくないよ!という貴兄に贈る。
ということではなく、Greasemonkeyスクリプト内でjQueryを使う練習と、クッキーを使うのの習作。
http://www.ne.jp/asahi/shrkw/shrkw/in-cookie_my_list.user.js
個別の動画ページのマイリスト登録ボタンの下にcookie追加のボタンがでて、マイリスト閲覧するときに下のほうにcookieマイリストの内容が表示されます。削除はマイリスト閲覧のところで。

全然理解してないまま書きなぐってるのでなんか微妙な気がする点がいろいろ。

  • cookieの容量をみないで追加してるから4KB越えそう
  • "path=/"でcookieに入れてるのっていいんかいな
  • "expires=Tue, 1-Jan-2030 00:00:00 GMT;"って書いてるからcookieがいつまでたっても消えないのも嫌な気がする

試すときは自己責任で。
消したいときは"__shrkw"というキーでcookieに入れているので、適当に消してください。

jQueryのロード

とかいろいろ参考にしてみたけど、うまいこと動かせなかったので、

にあったのをまるパクリ。
これでjQueryを使えるようになったけど、イベント登録のclickメソッドを使うと

uncaught exception: [Exception... "Component is not available" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: http://www.ne.jp/asahi/shrkw/shrkw/jquery-latest.pack.js :: anonymous :: line 1" data: no]

なんていうエラーが。bindメソッドでも一緒だった。
なのでイベント登録だけプレインなJSで。
気になるけど、調べるパスが思い浮かばない。

書いてるとき

ロジック自体はcookieから出し入れしているだけだからすぐ書けたけど、画面から操作できるようにするのがめんどくさかったのと、ISPのホームページサービスに上げるためのパスワードを忘れててそれを探すのに一番時間かかっちゃった。

スクリプトのソース

// ==UserScript==
// @name           add_in-cookie_my-list
// @namespace      d.hatena.ne.jp/shrkw
// @include        http://www.nicovideo.jp/*
// ==/UserScript==
(function () {
    // copy from http://www.nabble.com/Greasemonkey-+-jquery-+-functions-t3890929s15494.html
    var GM_JQ = document.createElement('script');
    GM_JQ.src = 'http://www.ne.jp/asahi/shrkw/shrkw/jquery-latest.pack.js';
    GM_JQ.type = 'text/javascript';
    document.getElementsByTagName('head')[0].appendChild(GM_JQ);
    // Check if jQuery's loaded
    function GM_wait() {
        if (typeof unsafeWindow.jQuery == 'undefined') {
            window.setTimeout(GM_wait, 100);
        }
        else {
            $ = unsafeWindow.jQuery;
            letsJQuery();
        }
    }
    GM_wait();
    function letsJQuery() {
        var _key = "__shrkw";
        function parse_cookie() {
            var _cookie = document.cookie;
            var ar = _cookie.split(";");
            for (var i = 0; i < ar.length; i++) {
                if (ar[i].indexOf(_key) == 1) {
                    return ar[i].split("=")[1];
                }
            }
            return "";
        }
        var parsed_cookie = parse_cookie();

        // append add-button if you see watch page
        if (String(document.location).indexOf("watch") !=  - 1) {
            function _add_cookie() {
                var _movie_id = String(document.location).split('/').pop();
                var _indi_node = $("span#_indi_node");
                if (_indi_node.length == 0) {
                    _indi_node = $(document.createElement("span"));
                }
//                _indi_node.css("margin", "1em");
                _indi_node.attr("id", "_indi_node");
                // return if already registered
                if (parsed_cookie.indexOf(_movie_id) !=  - 1) {
                    _indi_node.html("you are already added to in-cookie my-list");
                }
                else {
                    var old_val = parsed_cookie == "" ? parsed_cookie : parsed_cookie + ",";
                    document.cookie = _key + "=" + old_val + _movie_id + "; path=/; expires=Tue, 1-Jan-2030 00:00:00 GMT;";
                    _indi_node.html("add to in-cookie my-list successfully");
                }
                // indicate of end of adding process
                _indi_node.insertAfter("button#_shrkw_button");
            }

            var btn = document.createElement("button");
            btn.addEventListener("click", _add_cookie, false);
            btn = $(btn);
            btn.attr("id", "_shrkw_button");
            btn.css("margin", "0em 1em 0em 0em");
            btn.html("add to in-cookie my-list");

            // append
            var target_node;
            if (String(document.location).indexOf("/watch/") !=  - 1) {
                target_node = $("form[@name^='mylist_form']");
            }
            else if (String(document.location).indexOf("/watch_naisho/") !=  - 1) {
                target_node = $("table").get(9);
            }
            var _btn_area = $(document.createElement("div"));
            _btn_area.attr("id", "_shrkw_area");
            _btn_area.css("margin", "1em 0em");
            _btn_area.append(btn);

            _btn_area.insertAfter(target_node);
        };

        // show in-cookie my-list if you see mylist page
        if (String(document.location).indexOf("www.nicovideo.jp/mylist/") !=  - 1) {
            if (parsed_cookie.length == 0) {
                return;
            }
            var _list_area = $(document.createElement("div"));
            _list_area.insertAfter($("/div").get(0));
            var _list_elem = $(document.createElement("ul"));
            _list_area.append(_list_elem);

            var movie_ids = parsed_cookie.split(",");
            for (var i = 0; i < movie_ids.length; i++) {
                var _list_node = $(document.createElement("li"));
                var _d = $(document.createElement("div"));
                _d.css("float", "left");
                _list_node.append(_d);
                var _url = "http://www.nicovideo.jp/watch/" + movie_ids[i];
                _d.html("<div style='width:318px; border:solid 1px #CCC;'><iframe src='http://www.nicovideo.jp/thumb?v=" + movie_ids[i] + "' width='100%' height='198' scrolling='no' border='0' frameborder='0'><p style='font-size:12px; padding:4px;'>iframe対応ブラウザでご覧下さい。</p></iframe></div>");

                _list_node.append(document.createTextNode(movie_ids[i]));
                _list_node.append(document.createElement("br"));

                var _b = document.createElement("button");
                _b.addEventListener("click", (function(id){
                    return function() {
                        var ar = parse_cookie().split(",");
                        for (var j = 0;j < ar.length; j++) {
                            if (ar[j] == id) {
                                ar = ar.slice(0, j).concat(ar.slice(j + 1));
                                break;
                            }
                        }
                        document.cookie = _key + "=" + ar.join(",") + "; path=/; expires=Tue, 1-Jan-2030 00:00:00 GMT;";
                        this.parentNode.appendChild(document.createTextNode(" delete successfully : " + id), this.nextSibling);
                    }
                })(movie_ids[i]), false);
                _b = $(_b);

                _b.html("delete from in-cookie my-list");
                _b.css("margin", "3em 1em");
                _list_node.append(_b);
                var _clear_b = $(document.createElement("div"));
                _clear_b.css("clear", "both");
                _list_node.append(_clear_b);

                _list_elem.append(_list_node);
            }
        };

    }
}
)();