Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Imgur Stamp Menu
- // @author https://www.reddit.com/u/KKRdQFBU/
- // @copyright Copyright (c) 2016 KKRdQFBU
- // @license MIT License - https://osdn.jp/projects/opensource/wiki/licenses%2FMIT_license
- // @include https://www.reddit.com/r/lowlevelaware/comments/*
- // @version 16.01.13
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_listValues
- // @grant GM_deleteValue
- // ==/UserScript==
- //スタンプを読み込む最大個数, スペックに応じて増減してね
- var max_stamp = 1000;
- //サムネをキャッシュする場合はtrue, しない場合はfalse
- var cache_thumbnail = false;
- var req_list = [];
- var def_img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQIHWP4DwABAQEANl9ngAAAAABJRU5ErkJggg==";
- var utb = document.querySelectorAll(".usertext-buttons");
- if(utb[0]){ ISM_init(); }
- //現在のサブレ名をURLから取得(LLLならlowlevelaware, ばかにゅ~ならBakaNewsJP
- function SubRedditName(){
- return window.location.href.match(/.*reddit\.com\/r\/(.*?)\/.*/)[1];
- }
- //https://www.reddit.com/r/<現在のサブレ名>/wiki/imgurstamp.jsonを返す
- function StamplistURL(){
- return "https://www.reddit.com/r/"+SubRedditName()+"/wiki/imgurstamp.json";
- }
- //キャッシュを全部削除
- function deleteValueAll(){
- ret = confirm("キャッシュをすべて削除しますか?");
- if(ret != true){ return; }
- var list = GM_listValues();
- for(var i = 0;i < list.length;i++){
- // console.log("delete: "+list[i]);
- GM_deleteValue(list[i]);
- }
- }
- //urlを分解して画像IDを抽出, キャッシュに有ればbase64で返す
- //無い場合は非同期で取得を開始してurlをそのまま返す
- function GetThumbnail(url){
- if(!cache_thumbnail){return url;}
- var thum = GM_getValue(URL2ID(url));
- if(typeof(thum) == "undefined"){
- // console.log("no cached: "+URL2ID(url));
- var idx = CreateXHR();
- var req = req_list[idx][0];
- req.overrideMimeType("text/plain; charset=x-user-defined");
- req.open("GET",url,true);
- req.onreadystatechange = function(){ var arg0 = arguments[0]; var arg1 = arguments[1]; return function() { ReceiveThumbnail(arg0,arg1); }; }(idx,URL2ID(url));
- req.send(null);
- return url;
- }
- // else{
- // console.log("chached: "+URL2ID(url));
- // }
- return thum;
- }
- //受信したサムネをbase64に変換
- function ThumnailToBase64(raw){
- // console.log(raw.length);
- var bytes = [];
- for(var i = 0;i < raw.length;i++){
- bytes[i] = raw.charCodeAt(i) & 0xFF;
- }
- var bin_data = String.fromCharCode.apply(String,bytes);
- var base64 = btoa(bin_data);
- var header = bin_data.substring(0,9);
- var ext;
- var img;
- if(header.match(/^\x89PNG/)){ ext = "png";}
- else if(header.match(/^BM/)){ ext = "bmp"; }
- else if(header.match(/^GIF87a/) || header.match(/^GIF89a/)){ ext = "gif"}
- else if(header.match(/^\xFF\xD8/)){ ext = "jpeg"; }
- else{ ext = false; }
- if(ext != false){ img = "data:image/"+ ext +";base64,"+ base64; }
- else{ img = def_img }
- return img;
- }
- //サムネデータ受信callback, base64エンコードしてキャッシュし、<img>のsrcを差し替える
- function ReceiveThumbnail(idx,id){
- var req = req_list[idx][0];
- if(req.readyState == 4){
- var img;
- if(req.status == 200){
- var raw = req.responseText;
- req_list[idx][1] = false;
- img = ThumnailToBase64(raw);
- GM_setValue(id,img);
- }else{
- img = def_img;
- }
- document.getElementById("ISM_"+id).src = img;
- }
- }
- //[0]にurl、[1]にurlをサムネURLにした物を追加して配列で返す
- function GetThumbnailURLs(url){
- return [url,"https://i.imgur.com/"+ URL2ID(url) +"s."+url.match(/.*\.(.*)/)[1]];
- }
- //imgurURLのID部を返す, http://i.imgur.com/VfsdF9Ls.jpg なら"VfsdF9L"
- function URL2ID(url){
- return url.match(/.*imgur\.com\/([A-Za-z0-9]{7,8})\..*/)[1].substring(0,7);
- }
- //空いているreq_listのインデックスを返す, [i][1]がfalseなら使用可能
- function GetNewRequestIndex(){
- for (var i = 0; i < req_list.length; i++) {
- if(req_list[i][1] == false){return i;}
- };
- return req_list.length;
- }
- //空いているreq_listにXHRを生成してそのインデックスを返す
- function CreateXHR(){
- var idx = GetNewRequestIndex();
- // console.log("CreateXHR: "+idx);
- req_list[idx] = [];
- req_list[idx][0] = new XMLHttpRequest();
- req_list[idx][1] = true;
- return idx;
- }
- //wikiのスタンプリストを持ってくる
- function UpdateMenu(){
- var idx = CreateXHR();
- var req = req_list[idx][0];
- req.open("GET",StamplistURL(),true);
- req.onreadystatechange = function(){ var idx = arguments[0]; return function() { ReceiveStampList(idx); }; }(idx);
- req.send(null);
- }
- //スタンプリスト受信callback, 取得したjsonをキャッシュしてからGenerateMenuへ渡す
- function ReceiveStampList(idx){
- var req = req_list[idx][0];
- if(req.readyState == 4 && req.status == 200){
- var json_text = req.responseText;
- GM_setValue(SubRedditName()+"@imgurstamp.json",json_text);
- req_list[idx][1] = false;
- GenerateMenu(json_text);
- }
- }
- //.ISM_listの中身を全部削除
- function removeListAll(){
- var list = document.querySelector(".ISM_list");
- for(var i = list.childNodes.length-1;i >= 0;i--){
- list.removeChild(list.childNodes[i]);
- }
- }
- //stringのjson_textを元にメニュー化する
- //とりあえずすべての"i.imgur.com"のURLを抽出
- function GenerateMenu(json_text){
- var raw = JSON.parse(json_text)["data"]["content_md"];
- var m = raw.match(/(http.*i\.imgur\.com\/.*\.[A-Za-z0-9]*)/g);
- var imgur_list = [];
- var stamp = [];
- removeListAll();
- var list = document.querySelector(".ISM_list");
- // console.log(m.length);
- for (var i = 0; i < m.length && i < max_stamp; i++) {
- var img = GetThumbnailURLs(m[i]);
- stamp[i] = document.createElement("img");
- stamp[i].id = "ISM_"+URL2ID(img[0]);
- stamp[i].width = 90;
- stamp[i].height = 90;
- stamp[i].title = img[0];
- stamp[i].href = stamp[i].title;
- stamp[i].src = GetThumbnail(img[1]);
- stamp[i].style = "display: inline;margin: 2px;";
- stamp[i].setAttribute("onclick","ISM_func(this,3);return false;");
- list.appendChild(stamp[i]);
- };
- }
- //初期化
- function ISM_init(){
- var btn = [];
- btn[0] = document.createElement("button");
- btn[0].className = "ISM_stmp";
- btn[0].textContent = "istmp";
- btn[0].setAttribute("onclick","ISM_func(this,1);return false;");
- utb[0].appendChild(btn[0]);
- for(var i = 1;i < utb.length;i++){
- btn[i] = btn[0].cloneNode(1);
- btn[i].setAttribute("onclick","ISM_func(this,1);return false;");
- utb[i].appendChild(btn[i]);
- }
- var menu = document.createElement("div");
- menu.className = "ISM_menu ISM_hide";
- menu.title = "ISM "+ GM_info.script.version;
- menu.setAttribute("onclick","ISM_func(this,2);return false;");
- var style = document.createElement("style");
- style.textContent = ".ISM_menu{zoom:.8;z-index:99;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;background:#888;opacity:.8;padding:40px;}";
- style.textContent += ".ISM_hide{display:none;}.ISM_target{opacity:0.5;}";
- style.className = "ISM_style";
- menu.appendChild(style);
- btn_ud = document.createElement("button");
- btn_ud.className = "ISM_";
- btn_ud.textContent = "更新";
- btn_ud.title = "スタンプリストを更新";
- btn_ud.addEventListener("click",function(){UpdateMenu();return false;});
- menu.appendChild(btn_ud);
- var script = document.createElement("script");
- script.type = "text/javascript";
- script.textContent = function ISM_func(_this_,_type_){
- if(1 == _type_){
- document.querySelector(".ISM_menu").classList.remove("ISM_hide");
- _this_.parentNode.parentNode.parentNode.querySelector("textarea").classList.add("ISM_target");
- }else if(2 == _type_){
- document.querySelector(".ISM_menu").classList.add("ISM_hide");
- document.querySelector(".ISM_target").classList.remove("ISM_target");
- }else if(3 == _type_){
- document.querySelector(".ISM_target").value += _this_.title;
- }
- }.toString();
- menu.appendChild(script);
- var list = document.createElement("div");
- list.className = "ISM_list";
- menu.appendChild(list);
- btn_del = document.createElement("button");
- btn_del.className = "ISM_delcache";
- btn_del.textContent = "キャッシュを削除";
- btn_del.title = "基本的に使わなくていいと思う";
- btn_del.addEventListener("click",function(){deleteValueAll();return false;});
- menu.appendChild(btn_del);
- document.body.appendChild(menu);
- //前回取得したjsonデータを読み込む
- json_text = GM_getValue(SubRedditName()+"@imgurstamp.json");
- if(typeof(json_text) == "undefined"){//ない場合は取得
- UpdateMenu();
- }else{
- GenerateMenu(json_text);
- }
- }
- //// script-end ////
Add Comment
Please, Sign In to add comment