您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add thumbnail of twitpic @twitter web site
当前为
// ==UserScript== // @id thumb_on_twitter // @name Thumb_on_Twitter // @version 2.24 // @namespace https://greasyfork.org/scripts/2584 // @homepageURL https://greasyfork.org/scripts/2584 // @license https://creativecommons.org/licenses/by-nc-sa/3.0/ // @author noi // @description Add thumbnail of twitpic @twitter web site // @include /https?:\/\/twitter.com\/.*$/ // @run-at document-end // @grant GM_getValue // @grant GM_setValue // @grant GM_log // @grant GM_registerMenuCommand // @grant GM_deleteValue // @grant GM_xmlhttpRequest // ==/UserScript== //============================================================== //GreaseForkがrequireの審査必要なのでいっそのこと埋め込みました。 //Copyright: JoeSimmons & Sizzlemctwizzle & IzzySoft //require (c)https://greasyfork.org/scripts/1884-gm-config //============================================================== //============================================================== //フリー音源 //Copyright: cajo (freesound.org) //(c)https://www.freesound.org/people/cajo/sounds/34207/ //============================================================== //============================================================== //Flikr用ソースコード参照 //Copyright:NeoCat //http://d.hatena.ne.jp/NeoCat/20091228/1262015896 //============================================================== //============================================================== //サムネURL参照 //http://blog.irons.jp/2009/12/23/twitter_thumb_url/ //他 //============================================================== /************************************************************** WEB版ツイッターで画像のサムネ表示を追加します。 (Add thumbnail @twitter) [概要(about)] gif動画なのに動かなかったり、ちゃんとした拡張子で保存できなかったり、 (gif movie not work?) (Can't save correct file extension?) という問題を解消します。多分・・・ (This script solves problems!...Maybe...) [対応サイト(supported)] droplr flickr(一部サイズ変更に対応せず) hatena img.ly imgur instagram Mobypicture 携帯百景movapic Ow.ly photozou tumblr twitpic twipple twitter(公式official pic.twitter.com) twitter(公式official p.twimg.com) twitter(公式official pbs.twimg.com) yfrog [サポート対象外(not supported)] ・flickr(staticflickr)の一部サイズ指定非対応 URL"http://flickr.com/photo.gne?id={id}"で元のURLを取得できずにyahooのloginを求められるため 画像のサイズ指定ができません。 更新履歴 08/19/2014 - v2.24 fix:投稿ミス 08/18/2014 - v2.23 fix:flickrのオリジナル画像が最大サイズじゃなかった場合表示できなかった不具合修正。v2.21の不具合修正 08/18/2014 - v2.22 fix:v2.21の不具合修正 08/15/2014 - v2.21 fix:twitter公式pic.twitter.comの複数画像に対応 08/15/2014 - v2.20 fix:twitter公式pbs.twimg.comで一部表示できなくなっていた不具合修正 08/14/2014 - v2.19 add:tumblrに対応。携帯百景movapicのuserIDが入ってくるURLにも対応。 08/14/2014 - v2.18 add:flickrに対応。設定画面起動アイコンをクリックで閉じる機能。ESC押したら設定画面閉じる機能追加 08/05/2014 - v2.17 fix:i.instagramに対応 08/05/2014 - v2.16 fix:instagramで一部表示できなかったサムネに対応 08/05/2014 - v2.15 fix:通知音設定の不具合修正。chromeでのエラー修正。他 08/02/2014 - v2.14 fix:2.13の修正 07/31/2014 - v2.13 fix:サムネ取得失敗時に拡張子がpngかどうかも試してみるように変更 07/20/2014 - v2.12 add:更新通知音 07/19/2014 - v2.11 add:簡易短縮URL展開 Expand URL(http://t.co/) 07/19/2014 - v2.10 fix:参照箇所をtitleからdata-expanded-urlに変更。読み込み失敗した画像のリロード時間をランダム変数に変更 07/11/2014 - v2.9 fix:サムネ画像の読み込み失敗でdeadlinkとなる不具合にリロード処理追加 07/06/2014 - v2.8 fix:設定画面を開いたままブラウザサイズを変更した時に最適な配置になるように変更 06/30/2014 - v2.7 add:画像がリンク切れだったらdead linkとお知らせする機能。一括でON・OFF設定する機能 06/29/2014 - v2.6 add:拡張子が画像系のURLにサムネ追加、imgurにサイズM追加 06/27/2014 - v2.5 fix:add twitter(公式official pbs.twimg.com)と、pic.twitter.comのサムネのピンボケ修正 06/27/2014 - v2.4 fix:文字修正&v2.2で追加した処理の位置ミスの修正 06/27/2014 - v2.3 fix:指摘してもらったバグの修正とか 06/26/2014 - v2.2 add:twitterが追加するサムネの表示設定追加 06/26/2014 - v2.1 fix:GreaseMonkeyでユーザー設定を取得できなかったバグ修正 06/25/2014 - v2.0 fix:大幅な構造変更と軽微なバグ修正 06/23/2014 - v1.5 fix:無駄な処理の整理 06/22/2014 - v1.4 add:imgur、携帯百景movapic、hatena、Ow.ly、Mobypicture 06/21/2014 - v1.3 add:droplr、pic.twitter.com、img.ly、photozou、p.twimg.com、twipple、yfrog 06/19/2014 - v1.2 fix:表示切り替えなどで無限に増えていくのを修正 06/18/2014 - v1.1 add:instagram 06/18/2014 - v1.0 release *************************************************************** 備忘録 ・GM_xmlhttpRequestは非同期処理なので、終了を待たずに次の処理に行ってしまい面倒 →そのうちajaxに変更するかもしれない ホントは短縮URLのt.coをtwitterのapiでinclude_entitiesをtrueにして 展開されたURLを取得しようと思ったけどすでに他スクリプトがあるのでスルー →twitter側が展開してくれてる場合data-expanded-urlのURLに変更 ・flickrについて http://www.flickr.com/services/rest?method=flickr.photos.getInfo&format=json&api_key=<APIキー>&photo_id=<写真ID>&jsoncallback=<コールバック関数名> コールバック関数名は指定しないとjsonFlickrApiになる APIキーはyahoo.comに申請しないといけない(申請しても使用する=キー公開という・・・) 取得データ jsonFlickrApi({"photo":{"id":"3488883246", "secret":"aa472bc65f", "server":"3342", "farm":4, "dateuploaded":"1241098701", "isfavorite":0, "license":"4", "rotation":0, "owner":{"nsid":"34944948@N03", "username":"neo_cat", "realname":"NeoCat", "location":""}, "title":{"_content":"Alpaca Mix CAFE"}, ... 修正後URL:http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[画像サイズ指定].jpg →apiキー使わない方法 oEmbedで画像取得→枚数多いと重くなるかも →FlickrQuickEmbedを使わせてもらう 58エンコードされたURLは駄目。デコードしたURLを使えばいいけどユーザー名がない・・・ BASE○○のデコードは、変数 = parseInt(文字列,36);でいける?(未確認) ・facebook(短縮URLは展開しないといけないので後回し) 指定方法は2種類 https://fbcdn-sphotos-h-a.akamaihd.net/hphotos-ak-snc7/画像ID_n.jpg https://scontent-a.xx.fbcdn.net/hphotos-xpa1/t1.0-9/q71/画像ID_o.jpg サイズ アルファベット オリジナル o 960px b または n または o 180px a または q または x 130px s 75px t https://scontent-a.xx.fbcdn.net/hphotos-xpa1/t1.0-9/q71/s640x640/画像ID_o.jpg サイズ 書き方 64px s64x64 80px s80x80 120px s120x120 320px s320x320 480px s480x480 640px s640x640 720px s720x720 facebookの短縮URLは2種類? http://fb.me/ http://fb.com/ ********************閉鎖? not found website****************************************** pic.im (ドキュメント)サービス終了? ページ: http://pic.im/<image-id> サムネイル画像: http://pic.im/website/thumbnail/<image-id> picplz閉鎖? http://picplz.com/画像ID http://picplz.com/user/[user-id]/pic/画像ID/ 100sh(200x200)/320rh(320x320スケール)/640r(640x640スケール) BigCanvas PhotoShare閉鎖? //短縮URL: http://bctiny.com/p<image-noのbase36> //ページ: http://www.bcphotoshare.com/photos/<user-id?>/<image-no> //サムネイル画像: http://images.bcphotoshare.com/storages/<image-no>/<size>.jpg //“thumbnail”, “large”, “thumb68″ or “thumb180″ Lockerz(旧Plixi, その前は TweetPhoto)画像サービス終了?全部ador.comのトップページに飛ぶので詳細不明 ページ: http://lockerz.com/s/<photo-no> ページ: http://plixi.com/p/<photo-no> ページ: http://tweetphoto.com/<photo-no> サムネイル: http://api.plixi.com/api/TPAPI.svc/imagefromurl?size=<size>&url=<ページURL> <size>: “thumbnail”, “small”, “mobile”, “medium” or “big” brightkite 終了確定 **************************************************************/ /**************************追加予定**************************************************************************** 可能ならTwitgoo ニコニコ動画やyoutubeの短縮URLを動画に変更 動画の拡張子の場合動画プレーヤーを埋め込み facebookの対応 GM_xmlhttpRequestでURL展開 HeartRails Captureでtumblrの複数画像かどうか確認できるようにする?それとも直接表示する? http://capture.heartrails.com/tiny?http://url … 60×45 ピクセル http://capture.heartrails.com/small?http://url … 120×90 ピクセル http://capture.heartrails.com/medium?http://url … 200×150 ピクセル http://capture.heartrails.com/large?http://url … 400×300 ピクセル http://capture.heartrails.com/huge?http://url … 640×480 ピクセル サイズ指定も可能 http://capture.heartrails.com/200x400/? 読み込みまでの待ち時間指定 http://capture.heartrails.com/64x64/delay=5? 拡張子pdfのスナップショット http://capture.heartrails.com/pdf? ページに合わせて縦サイズを縮める http://capture.heartrails.com/64x64/shorten? 装飾 http://capture.heartrails.com/64x64/shadow? http://capture.heartrails.com/64x64/border? http://capture.heartrails.com/64x64/round? ******************************************************************************************************/ (function() { //ifame内除外 if(location.href.match(/^https?:\/\/twitter.com\/i\/cards\//)){ return; } //定数---------------------------------------------------------------- const fileExt = ["gif","jpg","jpeg","png","bmp"]; const strIcon = '<img name=imgBtn id=imgBtn type=button style=max-width:12px;display:inline-block; ' + 'src=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABOSURBVChTjZG5DQAwCANJhs1QWZZgCSQUxHMNLs6NWSyQsq4GgY8Gx9Yb8EUjlcFfKGXgC60MrDCSAQpjGeuMZJuxlf3epfw/JpXjB4keFPsQEoUOdacAAAAASUVORK5CYII= ' + '>'; //グローバル変数セット------------------------------------------------ var cfgData = {}; //ユーザー設定画面の初期値 var localDB = {}; //初期値(ローカルストレージに保存されるデータと同じ形式のデータベース) var titleDB = {}; //タイトルDB(サーバーの名称) var optionDB = {}; //サムネサイズ選択肢DB //localStorageに格納されているデータを直接確認(localDBと同じもの) // var tmpDB = JSON.parse(localStorage.getItem("configthumbnailsize")); var flickrSrcDB ={}; //flickr専用 var twitter1DB ={}; //pic.twitter専用 var insertWhere = "afterend"; //サムネと保存リンクの追加位置指定 var audio = new Audio("https://www.freesound.org/data/previews/34/34207_229898-lq.mp3"); //更新通知音声 //プログラム起動------------------------------------------------ try{ //DB作成 makeDB(); //ユーザー設定画面初期値作成 makeInitData(); //ユーザーコンフィグ画面作成 userCfg(); //main起動------------------------------------------------ document.addEventListener("DOMContentLoaded", function(evt){ var node = evt.target; window.setTimeout( function() {main(node);}, 300 ); }, false); //継ぎ足し要素対応 document.addEventListener("DOMNodeInserted", function(e) { window.setTimeout( function() {main(e.target)}, 200 ); }, false); }catch(e){ throw(e); } if(localDB["alertnoticeLink"]){ document.addEventListener('DOMAttrModified', function (e) { window.setTimeout( function() {chime(e.target)}, 200 ); }, false); document.addEventListener("DOMNodeInserted", function(e) { window.setTimeout( function() {chime(e.target)}, 200 ); }, false); } //*************************************************** //DB入力 function makeDB(){ var name = ""; var title = ""; var def = ""; //空文字""を指定する場合注意 //--------------------------------------------- name = "AllThumbsAndLinks"; title = "すべてのサムネとリンク(All Thumbs & Links)"; def = true; makeServerDB(name,title,def); //固定 //--------------------------------------------- name = "alertnotice"; title = "更新通知音(alert notice by sound)"; def = false; makeServerDB(name,title,def); //固定 //--------------------------------------------- name = "droplr"; title = ""; def = "+"; makeServerDB(name,title,def); //固定 optionDB[name]["+"] = "full:original"; optionDB[name]["-"] = "thumb:100x100(gif stop)"; //--------------------------------------------- name = "flickr"; title = "flickr"; def = "q"; //sq:75x75、q:100x100、t:100x75、s:240x180、n:320x240、m:500x375、指定なし(none):500x500、z:640x480、c:800x600、l:1024x768、b:1024x1024、o:origin makeServerDB(name,title,def); //固定 optionDB[name]["o"] = "o:original"; optionDB[name]["b"] = "b:1024x1024"; optionDB[name]["l"] = "l:1024x768"; optionDB[name]["c"] = "c:800x600"; optionDB[name]["z"] = "z:640x480"; optionDB[name]["m"] = "m:500x375"; optionDB[name]["n"] = "n:320x240"; optionDB[name]["s"] = "s:240x180"; optionDB[name]["q"] = "q:100x100"; optionDB[name]["t"] = "t:100x75"; optionDB[name]["sq"] = "sq:75x75"; //--------------------------------------------- name = "hatena"; title = "はてなフォトライフf.hatena"; def = "_120"; makeServerDB(name,title,def); //固定 optionDB[name][""] = "original"; optionDB[name]["_120"] = "_120:120x77"; optionDB[name]["_m"] = "_m:60x39"; //--------------------------------------------- name = "imgly"; title = "img.ly"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["full"] = "full:original"; optionDB[name]["large"] = "large:550x620"; optionDB[name]["medium"] = "medium:320x240"; optionDB[name]["thumb"] = "thumb:150x150"; optionDB[name]["mini"] = "mini:75x75"; //--------------------------------------------- name = "imgur"; title = ""; def = "m"; makeServerDB(name,title,def); //固定 optionDB[name][""] = "original"; optionDB[name]["l"] = "l:640x480(gif stop)"; optionDB[name]["m"] = "m:180x320(gif stop)"; optionDB[name]["s"] = "s:90x90(gif stop)"; //--------------------------------------------- name = "instagram"; title = ""; def = "t"; makeServerDB(name,title,def); //固定 optionDB[name]["l"] = "large:612x612"; optionDB[name]["m"] = "medium:306x306"; optionDB[name]["t"] = "thumbnail:150x150"; //--------------------------------------------- name = "Mobypicture"; title = ""; def = "thumbnail"; makeServerDB(name,title,def); //固定 optionDB[name]["original"] = "original:original?"; optionDB[name]["full"] = "full:original?"; optionDB[name]["large"] = "large:original?"; optionDB[name]["medium"] = "medium"; optionDB[name]["small"] = "thumbnail:500x400"; optionDB[name]["thumbnail"] = "thumbnail:100x100"; optionDB[name]["square"] = "thumbnail:90x90"; //--------------------------------------------- name = "movapic"; title = "携帯百景movapic"; def = "t"; makeServerDB(name,title,def); //固定 // optionDB[name]["l"] = "large:612x612"; //removed this options? optionDB[name]["m"] = "medium:306x306"; optionDB[name]["t"] = "thumbnail:150x150"; //--------------------------------------------- name = "Owly"; title = "Ow.ly"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["original"] = "original"; optionDB[name]["normal"] = "normal"; optionDB[name]["thumb"] = "thumb:100x100"; //--------------------------------------------- name = "photozou"; title = "フォト蔵photozou"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["img"] = "img:original"; optionDB[name]["thumb"] = "thumb:120x120"; //--------------------------------------------- name = "tumblr"; title = "tumblr"; def = "100"; makeServerDB(name,title,def); //固定 optionDB[name]["1280"] = "1280:1280x1280"; optionDB[name]["500"] = "500:500x500"; optionDB[name]["400"] = "400:400x400"; optionDB[name]["250"] = "250:250x250"; optionDB[name]["100"] = "100:100x100"; optionDB[name]["75sq"] = "75sq:75x75"; //--------------------------------------------- name = "twipple"; title = "ついっぷるtwipple"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["orig"] = "orig:original"; optionDB[name]["large"] = "large:350x480"; optionDB[name]["thumb"] = "thumb:160x120"; //--------------------------------------------- name = "twitpic"; title = ""; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["full"] = "full:original"; optionDB[name]["large"] = "large:600x800"; optionDB[name]["thumb"] = "thumb:150x150"; optionDB[name]["mini"] = "mini:75x75"; //--------------------------------------------- name = "twitter1"; title = "Official(1):pic.twitter"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["large"] = "large:Original"; optionDB[name]["medium"] = "medium:600x450"; optionDB[name]["small"] = "small:340x244"; optionDB[name]["thumb"] = "thumb:150x150"; //--------------------------------------------- name = "twitter2"; title = "Official(2):p.twimg"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["large"] = "large:Original"; optionDB[name]["medium"] = "medium:600x450"; optionDB[name]["small"] = "small:340x244"; optionDB[name]["thumb"] = "thumb:150x150"; //--------------------------------------------- name = "twitter3"; title = "Official(3):pbs.twimg.com"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["large"] = "large:Original"; optionDB[name]["medium"] = "medium:600x450"; optionDB[name]["small"] = "small:340x244"; optionDB[name]["thumb"] = "thumb:150x150"; //--------------------------------------------- name = "yfrog"; title = ""; def = "small"; makeServerDB(name,title,def); //固定 optionDB[name]["medium"] = "medium:640x480"; optionDB[name]["iphone"] = "iphone:480x360"; optionDB[name]["small"] = "small:125x90"; //--------------------------------------------- name = "otherPic"; title = "その他の画像URL(Other ImageURL)"; def = "thumb"; makeServerDB(name,title,def); //固定 optionDB[name]["origin"] = "origin:original"; optionDB[name]["thumb"] = "thumb:100x100"; } //*************************************************** //main========================================================================================== function main(node){ var allLinks = document.evaluate('.//a', node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < allLinks.snapshotLength; i++){ var objLink = allLinks.snapshotItem(i); //短縮URLを簡易的に展開 if(localDB["AllThumbsAndLinksSize"] && objLink.hasAttribute("href")){ var tmpUrl = objLink.href; //展開 if(objLink.hasAttribute("data-expanded-url") && objLink.getAttribute("data-expanded-url").match(/^http/)){ tmpUrl = objLink.getAttribute("data-expanded-url"); //t.coリンクでテキストが展開URLだったら }else if(objLink.innerHTML.match(/[a-zA-Z0-9]..*\//) && objLink.href.match(/https?:\/\/t.co\//)){ tmpUrl = "http://" + objLink.innerHTML; } objLink.href = tmpUrl; objLink.rel = "noreferrer"; } //サムネ追加対象以外は除外 if(objLink.getAttribute("class") != "twitter-timeline-link" //hrefを含まないリンクは除外 || !objLink.hasAttribute("href") || objLink.href == "" || objLink.getAttribute("data-expanded-url") == "" //サムネ追加済みは除外 || objLink.hasAttribute("ToT_Link") || objLink.hasAttribute("ToT_Thumb") //サムネURL展開中も除外 || objLink.hasAttribute("ToT_URL") && objLink.getAttribute("ToT_URL").match(/^NowLoading:.*/) //追加後も除外 ||objLink.getAttribute("ToT_Thumb","added") || objLink.getAttribute("ToT_Link","added") ){ continue; } var href = objLink.href; //URL展開して取得したURLがセットされていたら if(objLink.hasAttribute("ToT_URL") && objLink.getAttribute("ToT_URL").match(/^http/)){ href = objLink.getAttribute("ToT_URL"); } var src = href; insertWhere = "afterend"; //投稿URL:http://d.pr/i/<photo_id> //元画像:http://d.pr/<photo_id> //元画像:http://d.pr/i/<photo_id>+ //元画像:http://d.pr/i/<photo_id>+#.jpg //サムネ:http://d.pr/i/<photo_id>- //サムネにするとgifは動かなくなる //マイナス-:100x100|プラス+:ORIGIN //Droplr---------------------------------------------------------------------- if(href.match(/^https?:\/\/d.pr\/i\/.*$/) && !href.match(/^https?:\/\/d.pr\/i\/.*?\//)){ var name = "droplr"; var picID = href.replace(/.*d.pr\/i\//,""); if(href.slice(-1) == "-" || href.slice(-1) == "+"){ href = href.slice(0,-1); } src = href + localDB[name +"Size"]; href = href + "+"; setLink(name); setThumb(name); //短縮URL:http://flic.kr/p/英数字(上記画像ID数値のBase58エンコード) //Flickr短縮URLの展開---------------------------------------------------------------------- }else if(href.match(/^https?:\/\/flic.kr\/(p|s)\/.*/) && !href.match(/^https?:\/\/flic.kr\/(p|s)\/.*?\/.*/)){ expandUrl('HEAD',objLink); //元のURL:http://www.flickr.com/photos/ユーザー名/画像ID数値/ //サムネhttps://yy(ファームID).staticflickr.com/サーバーID/画像ID数値_ランダム数値(ハッシュ?)_t.jpg //画像https://yy2.staticflickr.com/3844/画像ID数値_ランダム数値_h.jpg //画像http://farm4.static.flickr.com/3342/3488883246_aa472bc65f_s.jpg //sq:75x75、q:100x100、t:100x75、s:240x180、n:320x240、m:500x375、z:640x480、c:800x600、l:1024x768、b:1024x1024、o:origin //Flickr画像URLを展開する---------------------------------------------------------------------- }else if(href.match(/^https?:\/\/(www.|m.)?flickr.com\/(#\/)?photos\/.*?\/.*\//)){ var name = "flickr"; var size = localDB[name +"Size"]; //Flickr携帯URLならURL修正 if(href.match(/^https?:\/\/m.flickr.com\/(#\/)?photos\/.*?\/.*\//)){ href = href.replace(/\/\/m./,"//").replace(/\/#\//,"/"); } //サムネ一覧ページにアクセスする用URL var tmpUrl = href.replace(/^https?/,"https").replace(/^(https?:\/\/(www.)?flickr.com\/photos\/.*?\/.*?\/).*/i,"$1") + "sizes/" + size + "/"; //何故かサムネ一覧にあるサムネサイズ指定と画像URLのサムネサイズ指定部分が違うので修正 size = flickrSize(size); objLink.setAttribute("ToT_URL",tmpUrl,size); expandUrl('GET',objLink,size); //Flickr画像URL------------------------------------------------------------------ }else if(href.match(/^https?:\/\/.*static.?flickr.com\/.*?\//) //元URL取得失敗はスルーして画像拡張子の処理の方に回す && objLink.hasAttribute("ToT_URL") && !objLink.getAttribute("ToT_URL").match(/^Error/)){ //元から画像URLで投稿されていた場合、一度元のURLに戻す必要がある(画像URLのランダム数値を取得するため) if(Object.keys(flickrSrcDB).length == 0){ var tempUrl = "https://flickr.com/photo.gne?id=" + href.replace(/.*\/(.*?)_.*?(_[a-zA-Z])?..*/i,"$1"); objLink.setAttribute("ToT_URL",tempUrl); expandUrl('HEAD',objLink); //画像URLを展開した場合 }else{ var name = "flickr"; href = href.replace(/^https?/,"https"); src = flickrSrcDB[objLink.href]; //同じURLで再度取得しないように消さない方がいい? // delete flickrSrcDB[objLink.href]; setLink(name); setThumb(name); } //ページ: http://f.hatena.ne.jp/<user-id>/YYYYMMDD<image-id> //サムネイル画像:http://img.f.hatena.ne.jp/images/fotolife/<user-idの1文字目>/<user-id>/YYYYMMDD/YYYYMMDD<image-id>_<size>.jpg //_m:60x39 _120:120x77 無印:original //はてなフォトライフf.hatena---------------------------------------------------- }else if(href.match(/^https?:\/\/f.hatena.ne.jp\/.*?\/.*$/) && !href.match(/^https?:\/\/f.hatena.ne.jp\/.*?\/.*?\//)){ var name = "hatena"; //注意:httpsは使えない var commonUrl = "http://img.f.hatena.ne.jp/images/fotolife/"; var userId = href.replace(/.*f.hatena.ne.jp\/(.*?)\/.*$/i,"$1"); //ユーザーID var strTemp = href.replace(/.*f.hatena.ne.jp\/.*?\//,""); //yyyymmdd画像ID var strTime = strTemp.slice(0,8); //yyyymmdd if(strTemp != "" && !strTemp.match("fototime")){ src = commonUrl + userId.slice(0,1) + "/" + userId + "/" + strTime + "/" + strTemp + localDB[name +"Size"] + ".jpg"; href = commonUrl + userId.slice(0,1) + "/" + userId + "/" + strTime + "/" + strTemp + ".jpg"; setLink(name); setThumb(name); } //投稿URL:http://img.ly/<photo_id> //元画像:http://img.ly/show/full/<photo_id> //mini75x75|thumb150x150|medium320x240|large550x620|full //img.ly---------------------------------------------------------------------- }else if(href.match(/^https?:\/\/img.ly\/.*$/) && !href.match(/^https?:\/\/img.ly\/.*?\//)){ var name = "imgly"; var picID = href.replace(/.*img.ly\//,""); var commonUrl = "https://img.ly/show/"; src = commonUrl + localDB[name +"Size"] + "/" + picID; href = commonUrl + "full/" + picID; setLink(name); setThumb(name); //http://i.imgur.com/画像id //ページ: http://imgur.com/<image-id> //ページ: http://imgur.com/<image-id>.拡張子 //サムネイル画像: http://i.imgur.com/<image-id><size>.拡張子 //s(サムネ、gif動かない90x90) l(サムネ、gif動かない640x480) "無印"(オリジナル、gif動く) //imgur-------------------------------------------------------------------------- }else if(href.match(/^https?:\/\/(i.)?imgur.com\/.*$/) && !href.match(/^https?:\/\/(i.)?imgur.com\/.*?\//)){ var name = "imgur"; var commonUrl = href.replace(/^https?/,"https").replace("/imgur.com","/i.imgur.com"); var fileType = ""; //拡張子 fileType = href.replace(/.*imgur.com\/.*\.(.*$)/i,"$1"); //拡張子なし if(fileType == href){ src = commonUrl + localDB[name +"Size"] + ".gif"; //拡張子わからないのでとりあえずgif href = commonUrl + ".gif"; //拡張子わからないのでとりあえずgif //拡張子あり }else{ src = commonUrl.replace("." + fileType, localDB[name +"Size"] + "." + fileType); href = commonUrl; } setLink(name); setThumb(name); //http://instagr.am/p/UKCy2XOfD5/ //http://instagram.com/p/oMk34hmjwj/ //http://instagram.com/p/rN9lU5hEB4/?modal=true //http://instagram.com/p/oMk34hmjwj/media?size=t //sizeパラメータ t(thumbnail:150x150)、m(medium:306x306)、l(large:612x612) //instagram---------------------------------------------------------------------- }else if(href.match(/^https?:\/\/(i.)?(i|I)nstagr(am.com|.am)\/p\/.*?\//) && !href.match(/^https?:\/\/instagr(am.com|.am)\/p\/.*?\/.*\//)){ var name = "instagram"; var commonUrl = href.replace(/^https/,"http").replace("instagr.am","instagram.com").replace(/\/\?.*$/,"/"); src = commonUrl + "media?size=" + localDB[name +"Size"]; href = commonUrl + "media?size=l"; setLink(name); setThumb(name); //ページ: http://moby.to/<image-id> //サムネイル画像: http://moby.to/<image-id>:<size> //“square”90x90“thumbnail”100x100, “small”500x400, “medium” ,"large" ,"full","original" //Mobypicture (ドキュメント)------------------------------------------------- }else if(href.match(/^https?:\/\/moby.to\/.*$/) && !href.match(/^https?:\/\/moby.to\/.*?\/.*$/)){ var name = "Mobypicture"; src = href + ":" + localDB[name +"Size"]; href = href + ":original"; setLink(name); setThumb(name); //http://movapic.com/UserID/pic/PageID) //携帯百景movapic(ユーザーIDを含んだURL)展開---------------------------------------------- }else if(href.match(/^https?:\/\/movapic.com\/.*?\/pic\/.*$/) && !href.match(/^https?:\/\/movapic.com\/.*?\/pic\/.*?\/.*$/)){ expandUrl('GET',objLink); //ページ: http://movapic.com/pic/<image-id> //サムネイル画像: http://image.movapic.com/pic/<size>_<image-id>.jpeg //<size>: t(サムネ80x60)s(small320x240)m(オリジナル?) //携帯百景movapic-------------------------------------------------------------- }else if(href.match(/^https?:\/\/movapic.com\/pic\/.*$/) && !href.match(/^https?:\/\/movapic.com\/pic\/.*?\/.*$/) || href.match(/^https?:\/\/image.movapic.com\/pic\/.*$/)){ var name = "movapic"; var commonUrl = "http://image.movapic.com/pic/"; var picID; //サムネURL if(href.match(/^https?:\/\/image.movapic.com/)){ picID = href.replace(/.*pic\/.*?_(.*?)\..*/i,"$1"); }else{ picID = href.replace(/.*pic\//,""); } src = commonUrl + localDB[name +"Size"] + "_" + picID + ".jpeg"; href = commonUrl + "m_" + picID + ".jpeg"; setLink(name); setThumb(name); //ページ: http://ow.ly/i/<image-id> //サムネイル画像: http://static.ow.ly/photos/サイズ/<image-id>.jpg //'thumb'(100x100)/'normal'/'original' //Ow.ly------------------------------------------------------------------------ }else if(href.match(/^https?:\/\/ow.ly\/i\/.*$/) && !href.match(/^https?:\/\/ow.ly\/i\/.*?\/.*$/)){ var name = "Owly"; var picID = href.replace(/.*\/i\//,""); var commonUrl = "http://static.ow.ly/photos/"; src = commonUrl + localDB[name +"Size"] + "/" + picID + ".jpg"; href = commonUrl + "original/" + picID + ".jpg"; setLink(name); setThumb(name); //投稿URL: http://photozou.jp/photo/show/<User ID>/画像ID //画像URL: http://photozou.jp/p/サイズ/画像ID // thumb、img //フォト蔵---------------------------------------------------------------------- }else if(href.match(/^https?:\/\/photozou.jp\/photo\/show\/.*?\/.*$/) && !href.match(/^https?:\/\/photozou.jp\/photo\/show\/.*?\/.*?\//)){ var name = "photozou"; var picID = href.replace(/.*\/show\/.*?\//,""); var commonUrl = "http://photozou.jp/p/"; src = commonUrl + localDB[name +"Size"] + "/" + picID; href = commonUrl + "img/" + picID; setLink(name); setThumb(name); //http://tmblr.co/ZLYNzr1OJpp6R //http://www.tumblr.com/xdo3zozjgf //展開http://kiitakashi.tumblr.com/post/94821626267/1 //tumblr短縮URL展開---------------------------------------------------------------------- }else if(href.match(/^http:\/\/(www.)?tu?mblr.com?\/[a-zA-Z0-9].*$/)){ expandUrl('HEAD',objLink); //http://hisuix.tumblr.com/post/94823180344/dig-image-these-shacks-seen-sept-14-1945 //tumblr画像URL取得-------------------------------------------------------------------------- }else if(href.match(/^http:\/\/[\w\-]+.tumblr.com\/post\/[0-9]+.*$/)){ var tmpUrl = href.replace(/(.*tumblr.com)\/post\/([0-9]+).*/i,"$1/image/$2"); objLink.setAttribute("ToT_URL",tmpUrl); expandUrl('GET',objLink); //http://38.media.tumblr.com/1fc196798f1148541be4b24ea4f5fe68/tumblr_n91535WAqE1qz7j5oo1_1280.jpg //最大サイズ(ない場合もある):1280,500px:500, 400px:400, 250px:250, 100px:100, 75px:75sq //URL展開処理で最大サイズを取得してきているはず //tumblr-------------------------------------------------------------------------- }else if(href.match(/^http:\/\/\d+.media.tumblr.com\/.*?\/tumblr_.*?_\d+..*/)){ var name = "tumblr"; var size = parseInt(href.replace(/^http:\/\/\d+.media.tumblr.com\/.*?\/tumblr_.*?_(\d+)..*/,"$1")); var strSize = "_" + size +"."; src = href; //サムネサイズにオリジナルのサイズ以上の指定は無効(オリジナルサイズのまま)、それ以下のみ設定 if(parseInt(localDB[name +"Size"]) < size){ src = href.replace(strSize,"_" + localDB[name +"Size"] + "."); } setLink(name); setThumb(name); //投稿URL: http://p.twipple.jp/画像ID //画像URL: http://p.twipple.jp/show/サイズ/画像ID //thumb、large、orig //ついっぷる--------------------------------------------------------------------- }else if(href.match(/^https?:\/\/p.twipple.jp\/.*$/) && !href.match(/^https?:\/\/p.twipple.jp\/.*?\//)){ var name = "twipple"; var picID = href.replace(/.*twipple.jp\//,""); var commonUrl = "http://p.twipple.jp/show/"; src = commonUrl + localDB[name +"Size"] + "/" + picID; href = commonUrl + "orig/" + picID; setLink(name); setThumb(name); //ページ: http://twitgoo.com/<image-id> //サムネイル画像: http://twitgoo.com/show/<size>/<image-id> //サムネイル画像: http://twitgoo.com/<image-id>/<size> //飛ばされる画像http://i60.twitgoo.com/画像IDじゃない文字列.jpg //実際の画像http://i60.tinypic.com/画像IDじゃない文字列.jpg //サムネ画像http://i60.tinypic.com/画像IDじゃない文字列_th.jpg //“thumb”110x160, “img”オリジナル //“mini”thumbと変わらない? /* //Twitgoo //tinypicに直さないと表示されない。しかし最初からtinypicで指定してもサムネ表示できない }else if(href.match(/^https?:\/\/twitgoo.com\/.*$/) && !href.match(/^https?:\/\/twitgoo.com\/.*?\//)){ src = href + "/thumb"; href = href + "/img"; setLink(name); setThumb(name); //twitgooのURLをtinypicにする // window.setTimeout( function() {renameTwitgoo(node)}, 5000 ); */ //http://twitpic.com/画像ID //https://twitpic.com/show/thumb/画像ID.jpg //mini:75x75、thumb:150x150、large:600x800、full:768x1024 //twitpic------------------------------------------------------------------------ }else if(href.match(/^https?:\/\/twitpic.com\//) && !href.match(/^https?:\/\/twitpic.com\/.*?\//)){ var name = "twitpic"; var picID = href.replace(/.*twitpic.com\//,""); var commonUrl = "https://twitpic.com/show/"; src = commonUrl + localDB[name +"Size"] + "/" + picID + ".jpg"; href = commonUrl + "full/" + picID + ".jpg"; setLink(name); setThumb(name); //twitter公式1------------------------------------------------------------------- //フラグ関係はtwitter1に依存 }else if(href.match(/^https?:\/\/pic.twitter.com\/.*$/)){ if(twitter1DB[objLink.href] && twitter1DB[objLink.href] == ""){return;} twitter1DB[objLink.href] = []; expandUrl('GET',objLink); //投稿URL(何故か表示されない): http://p.twimg.com/画像ID.jpg:サイズ //https://p.twimg.com/As2fObICEAAXRT-.jpg //画像URL: http://pbs.twimg.com/media/画像ID.jpg:サイズ //thumb、small、medium、large(またはorig) //twitter公式2------------------------------------------------------------------- }else if(href.match(/^https?:\/\/p.twimg.com\/[\w]+/) && !href.match(/^https?:\/\/p.twimg.com\/.*?\//)){ var name = "twitter2"; var commonUrl = href.replace(/^https?/,"https").replace("p.twimg.com","pbs.twimg.com/media").replace(/(.*\/.*):.*$/i,"$1"); //画像の拡張子だったらその拡張子のまま fileExt.forEach(function(x){ if(href.match(x)){ src = commonUrl + ":" + localDB[name +"Size"]; href = commonUrl + ":large?." + x; } }); //画像の拡張子が無かったらjpg追加 if(!href.match(/:large/)){ src = commonUrl + ".jpg:" + localDB[name +"Size"]; href = commonUrl + ".jpg:large"; } setLink(name); setThumb(name); //http://pbs.twimg.com/media/BrHiRU5CMAE_yv-.png#twimg //twitter公式3 }else if(href.match(/^https?:\/\/pbs.twimg.com\/media\/.*$/)){ var name = "twitter3"; function setTwit(num){ var commonUrl = href.replace(/^https?/,"https").replace(/#.*$/,"").replace(/(.*\/.*):.*$/i,"$1"); src = commonUrl + ":" + localDB[name +"Size"]; href = commonUrl + ":large"; setLink(name,num); setThumb(name,num); } //twitter1で展開したURL if(objLink.href != href){ name = "twitter1"; //複数URLだったら if(twitter1DB[objLink.href] != ""){ for(t=twitter1DB[objLink.href].length -1;t >= 0;t--){ href = twitter1DB[objLink.href][t]; setTwit(t); } return; //複数URLはここで終了 } } //通常 setTwit(); //http://yfrog.com/画像ID //http://yfrog.com/画像ID:medium //small:125x90、iphone:480x360、medium:640x480 //サムネはサイズ指定の代わりに画像IDの直後に「.th.jpg」を追加。(ただしgifは動かない) //yfrog-------------------------------------------------------------------------- }else if(href.match(/^http:\/\/yfrog.com\/.*$/) && !href.match(/^http:\/\/yfrog.com\/.*?\/.*$/)){ var name = "yfrog"; var commonUrl = href.replace(/^https?/,"https"); src = commonUrl + ":" + localDB[name +"Size"]; href = commonUrl + ":medium"; setLink(name); setThumb(name); //その他------------------------------------------------------------------------- }else{ //拡張子ありのURLのサムネだけ追加------------------------------------- var comma = href.slice(-5).indexOf("."); var strFEx = ""; //拡張子 if(comma > -1 && comma < 2){ //その他の画像URLのサムネ追加 var name = "otherPic"; if(localDB[name + "Thumb"]){ strFEx = href.replace(/.*\./,""); //画像の拡張子だったらサムネ追加 fileExt.forEach(function(x){ if(x == strFEx){ setThumb(name); } }); } //動画の拡張子だったら・・・ } } }//for文ここまで //保存用のリンク追加---------------------------------------------------------------------------------- function setLink(name,num){ //ユーザー設定で追加しないなら終了 if(localDB["AllThumbsAndLinksLink"] == false || localDB[name +"Link"] == false){ return; } var className = ''; if(name == "twitgoo"){ var className = 'twitgooText'; } var ele = document.createElement("div"); var strLinkText = '<a class="' + className + '" target="_blank" href="' + href + '" >' +'<img src=\'chrome://browser/skin/tabbrowser/loading.png\'>now loading' //リンク切れ確認用imgタグ + '<img src="' + src + '" onError="function reloadimg(e,p,timer){setTimeout( ' //画像読み込み失敗でリロードをかける + 'function(){ ' + 'if(e.src.match(/\\?dummy=/)){ e.src = e.src.replace(/dummy=/,\'dummy=d\');' //1回ごとに拡張子を変更してみる(ow.lyに有効) + 'if(e.src.match(/.jpg/)){ e.src = e.src.replace(/.jpg/,\'.png\');p.href=p.href.replace(/.jpg/,\'.png\');' + '}else if(e.src.match(/.jpg/)){ e.src = e.src.replace(/.png/,\'.jpg\');p.href=p.href.replace(/.png/,\'.jpg\'); }' + '}else{ e.src = e.src + \'?dummy=d\' }' + '},timer); }' //5回試行でも読み込み失敗ならdead link + 'if(!this.src.match(\'dummy=ddddd\')){reloadimg(this,this.parentNode,~~(Math.random()*(5000-2000)+2000));' + '}else{this.parentNode.style=\'font-size:12px\';' + 'this.parentNode.innerHTML=\'' + strIcon + '<a href=' + href + '>dead link</a>\'}" ' + 'onload= "this.innerHTML=\'\';this.parentNode.innerHTML=\'' + strIcon + 'Save Image As...\';"' + 'Style="max-width:0px;max-height:0px;"></a><br>'; //サムネを追加しない場合改行追加 if(localDB["AllThumbsAndLinksThumb"] == false || localDB[name + "Thumb"] == false){ //複数画像指定じゃない。または複数画像指定の1枚目だったら改行追加 if(!num || num && num == 0){objLink.innerHTML = "<br>" + objLink.innerHTML; strLinkText = "<br>" + strLinkText;} } objLink.insertAdjacentHTML(insertWhere, strLinkText); objLink.setAttribute("ToT_Link","added"); objLink.removeAttribute("ToT_URL"); }//リンク追加ここまで //サムネ追加---------------------------------------------------------------------------------- function setThumb(name,num){ //ユーザー設定で追加しないなら終了 if(localDB["AllThumbsAndLinksThumb"] == false || localDB[name +"Thumb"] == false){ return; } var strMW = "400"; //max-width var className = ""; //サムネのピンボケ対策などサイズ指定 if(name == "twitter1"&& localDB[name + "Size"] == "thumb" || name == "otherPic" && localDB[name + "Size"] == "thumb"){ strMW = "150"; } if(name == "twitgoo"){ className = 'twitgooPhoto'; } var strThumbText = '<a id="' + href + '" class="' + className + '" target="_blank" href="' + href + '" Style="padding-right:5px;">' + '<img src="' + src + '" onerror="function reloadimg(e,p,timer){setTimeout( ' //画像読み込み失敗でリロードをかける + 'function(){ ' + 'if(e.src.match(/\\?dummy=/)){ e.src = e.src.replace(/dummy=/,\'dummy=d\');' //twitter公式で読み込み失敗時thumb自体がない?→サムネ指定削除 + 'if(e.src.match(/pbs.twimg.com/)){ p.href = p.href.replace(/:large.*/,\'\');' + 'e.src = e.src.replace(/(.*):.*/i,\'$1\');' + 'onload();}' //1回ごとに拡張子を変更してみる(ow.lyに有効) + 'if(e.src.match(/.jpg/)){ e.src = e.src.replace(/.jpg/,\'.png\');p.href=p.href.replace(/.jpg/,\'.png\');' + '}else if(e.src.match(/.png/)){ e.src = e.src.replace(/.png/,\'.jpg\');p.href=p.href.replace(/.png/,\'.jpg\'); }' //1回ごとにサムネサイズ変更(movapic) + 'if(e.src.match(/\\/t_/)){ e.src = e.src.replace(/\\/t_/,\'/s_\');' + '}else if(e.src.match(/\\/s_/)){ e.src = e.src.replace(/\\/s_/,\'/t_\'); }' + '}else{ e.src = e.src + \'?dummy=d\'; }' + '},timer); }' //5回試行でも読み込み失敗ならdead link + 'if(!this.src.match(\'dummy=ddddd\')){reloadimg(this,this.parentNode,~~(Math.random()*(5000-2000)+2000));' + '}else if(this.src.match(/dummy=ddddd$/)){this.parentNode.style=\'font-size:12px\';' + 'this.insertAdjacentHTML(\'afterend\',' + '\'' + strIcon + '<a href=' + href + '>dead link</a>\'' + ');' + 'this.setAttribute(\'onerror\',\'\');' + '}" Style="max-width:' + strMW + 'px;"></a>'; //複数画像の時の改行 if(num || num == 0){ if(num == 0){ strThumbText = "<br>" + strThumbText; objLink.innerHTML = "<br>" + objLink.innerHTML; } //通常 }else{ strThumbText = "<br>" + strThumbText + "<br>" //元のリンクも改行 objLink.innerHTML = "<br>" + objLink.innerHTML; } objLink.insertAdjacentHTML(insertWhere, strThumbText); objLink.setAttribute("ToT_Thumb","added"); //twitterが追加するサムネの表示設定 if(localDB["flgDefPic"] == false){ //2個上の要素(コメント1個分) var content = objLink.parentNode.parentNode; var expand = content.getElementsByClassName("expanded-content js-tweet-details-dropdown"); //下の入れ子(ない場合もある) var photo = content.getElementsByClassName("card2 js-media-container"); //twitter側画像展開 var card = content.getElementsByClassName("cards-base cards-multimedia"); //twitter側画像展開その2 //要素削除 var delPic = function(obj){ if(obj[0]){ obj[0].parentNode.removeChild(obj[0]); } }; delPic(expand); delPic(photo); delPic(card); var view = content.getElementsByClassName("details with-icn js-details"); //画像を表示するリンク if(view[0]){ view[0].className="ToTChanged_details with-icn js-details"; } } objLink.removeAttribute("ToT_URL"); }//サムネ追加ここまで }//mainここまで==================================================================================== //ユーザー設定画面(userconfig)------------------------------------------------------------- function userCfg(){ //============================================================== //GreaseForkがrequireの審査必要なのでいっそのこと埋め込みました。 //Copyright: JoeSimmons & Sizzlemctwizzle & IzzySoft //require (c)https://greasyfork.org/scripts/1884-gm-config //============================================================== //============================引用開始=================================== var GM_config = { storage: 'GM_config', init: function(){ for(var i=0,l=arguments.length,arg; i<l; ++i) { arg=arguments[i]; switch(typeof arg) { case 'object': for(var j in arg) { switch(j) { case "open": GM_config.onOpen=arg[j]; delete arg[j]; break; // called when frame is gone case "close": GM_config.onClose=arg[j]; delete arg[j]; break; // called when settings have been saved case "save": GM_config.onSave=arg[j]; delete arg[j]; break; // store the settings objects default: var settings = arg; } } break; case 'function': GM_config.onOpen = arg; break; // passing a bare function is set to open // could be custom CSS or the title string case 'string': if(arg.indexOf('{') !== -1 && arg.indexOf('}') !== -1) var css = arg; else GM_config.title = arg; break; } } if(!GM_config.title) GM_config.title = 'Settings - Anonymous Script'; // if title wasn't passed through init() // give the script a unique saving ID for non-firefox browsers GM_config.storage = GM_config.title.replace(/\W+/g, "").toLowerCase(); var stored = GM_config.read(); // read the stored settings GM_config.passed_values = {}; for(var i in settings) { GM_config.doSettingValue(settings, stored, i, null, false); if(settings[i].kids) for(var kid in settings[i].kids) GM_config.doSettingValue(settings, stored, kid, i, true); } GM_config.values = GM_config.passed_values; GM_config.settings = settings; if (css) GM_config.css.stylish = css; }, open: function() { if(document.evaluate("//iframe[@id='GM_config']",document,null,9,null).singleNodeValue) return; // Create frame document.body.appendChild((GM_config.frame=GM_config.create('iframe',{id:'GM_config', style:'position: fixed; top: 0; left: 0; opacity: 0; display: none; z-index: 999999; width: 75%; height: 75%; max-height: 95%; max-width: 95%; border:3px ridge #000000; overflow: auto;'}))); GM_config.frame.src = 'about:blank'; // In WebKit src cant be set until it is added to the page GM_config.frame.addEventListener('load', function() { var obj = GM_config, doc = this.contentDocument, frameBody = doc.getElementsByTagName('body')[0], create=obj.create, settings=obj.settings, anch, secNo; obj.frame.contentDocument.getElementsByTagName('head')[0].appendChild(create('style',{type:'text/css',textContent:obj.css.basic + "\n\n" + obj.css.stylish})); // Add header and title frameBody.appendChild(create('div', {id:'header',className:'config_header block center', innerHTML:obj.title})); // Append elements anch = frameBody; // define frame body secNo = 0; // anchor to append elements for(var i in settings) { var type, field = settings[i], value = obj.values[i], section = (field.section ? field.section : ["Main Options"]), headerExists = doc.evaluate(".//div[@class='section_header_holder' and starts-with(@id, 'section_')]", frameBody, null, 9, null).singleNodeValue; if(typeof field.section !== "undefined" || headerExists === null) { anch = frameBody.appendChild(create('div', {className:'section_header_holder', id:'section_'+secNo, kids:new Array( create('a', {className:'section_header center', href:"javascript:void(0);", id:'c_section_kids_'+secNo, textContent:section[0], onclick:function(){GM_config.toggle(this.id.substring(2));}}), create('div', {id:'section_kids_'+secNo, className:'section_kids', style:obj.getValue('section_kids_'+secNo, "")==""?"":"display: none;"}) )})); if(section[1]) anch.appendChild(create('p', {className:'section_desc center',innerHTML:section[1]})); secNo++; } anch.childNodes[1].appendChild(GM_config.addToFrame(field, i, false)); } // Add save and close buttons frameBody.appendChild(obj.create('div', {id:'buttons_holder', kids:new Array( obj.create('button',{id:'saveBtn',textContent:'Save',title:'Save options and close window',className:'saveclose_buttons',onclick:function(){GM_config.close(true)}}), obj.create('button',{id:'cancelBtn', textContent:'Cancel',title:'Close window',className:'saveclose_buttons',onclick:function(){GM_config.close(false)}}), obj.create('div', {className:'reset_holder block', kids:new Array( obj.create('a',{id:'resetLink',textContent:'Restore to default',href:'#',title:'Restore settings to default configuration',className:'reset',onclick:obj.reset}) )}))})); obj.center(); // Show and center it window.addEventListener('resize', obj.center, false); // Center it on resize if (obj.onOpen) obj.onOpen(); // Call the open() callback function // Close frame on window close window.addEventListener('beforeunload', function(){GM_config.remove(this);}, false); }, false); }, close: function(save) { if(save) { var type, fields = GM_config.settings, typewhite=/radio|text|hidden|password|checkbox/; for(f in fields) { var field = GM_config.frame.contentDocument.getElementById('field_'+f), kids=fields[f].kids; if(typewhite.test(field.type)) type=field.type; else type=field.tagName.toLowerCase(); GM_config.doSave(f, field, type); if(kids) for(var kid in kids) { var field = GM_config.frame.contentDocument.getElementById('field_'+kid); if(typewhite.test(field.type)) type=field.type; else type=field.tagName.toLowerCase(); GM_config.doSave(kid, field, type, f); } } if(GM_config.onSave) GM_config.onSave(); // Call the save() callback function GM_config.save(); } if(GM_config.frame) GM_config.remove(GM_config.frame); delete GM_config.frame; if(GM_config.onClose) GM_config.onClose(); // Call the close() callback function }, set: function(name,val) { GM_config.values[name] = val; }, get: function(name) { return GM_config.values[name]; }, isGM: (typeof window.opera === "undefined" && typeof window.chrome === "undefined" && typeof GM_info === "object" && typeof GM_registerMenuCommand === "function"), log: function(str) { if(this.isGM) return GM_log(str); else if(window.opera) return window.opera.postError(str); else return console.log(str); }, getValue : function(name, d) { var r, def = (typeof d !== "undefined" ? d : ""); switch(this.isGM === true) { case true: r = GM_getValue(name, def); break; case false: r = localStorage.getItem(name) || def; GM_log("test:" + typeof GM_info); break; } return r; }, setValue : function(name, value) { switch(this.isGM === true) { case true: GM_setValue(name, value); break; case false: localStorage.setItem(name, value); break; } }, deleteValue : function(name) { switch(this.isGM === true) { case true: GM_deleteValue(name); break; case false: localStorage.removeItem(name); break; } }, save: function(store, obj) { try { var val = JSON.stringify(obj || GM_config.values); GM_config.setValue((store||GM_config.storage),val); } catch(e) { GM_config.log("GM_config failed to save settings!\n" + e); } }, read: function(store) { var val = GM_config.getValue((store || GM_config.storage), '{}'); switch(typeof val) { case "string": var rval = JSON.parse(val); break; case "object": var rval = val; break; default: var rval = {}; } return rval; }, reset: function(e) { e.preventDefault(); var type, obj = GM_config, fields = obj.settings; for(f in fields) { var field = obj.frame.contentDocument.getElementById('field_'+f), kids=fields[f].kids; if(field.type=='radio'||field.type=='text'||field.type=='checkbox') type=field.type; else type=field.tagName.toLowerCase(); GM_config.doReset(field, type, null, f, null, false); if(kids) for(var kid in kids) { var field = GM_config.frame.contentDocument.getElementById('field_'+kid); if(field.type=='radio'||field.type=='text'||field.type=='checkbox') type=field.type; else type=field.tagName.toLowerCase(); GM_config.doReset(field, type, f, kid, true); } } }, addToFrame : function(field, i, k) { var elem, obj = this, anch = this.frame, value = obj.values[i], Options = field.options, label = field.label, create=obj.create, isKid = (k !== null && k === true); switch(field.type) { case 'textarea': elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('span', {textContent:label, className:'field_label'}), create('textarea', {id:'field_'+i,innerHTML:value, cols:(field.cols?field.cols:20), rows:(field.rows?field.rows:2)}) ), className: 'config_var'}); break; case 'radio': var boxes = new Array(); for (var j = 0,len = Options.length; j<len; j++) { boxes.push(create('span', {textContent:Options[j]})); boxes.push(create('input', {value:Options[j], type:'radio', name:i, checked:Options[j]==value?true:false})); } elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('span', {textContent:label, className:'field_label'}), create('span', {id:'field_'+i, kids:boxes}) ), className: 'config_var'}); break; case 'select': var options = []; if(typeof Options === "object" && typeof Options.push !== "function") for(var j in Options) options.push(create('option',{textContent:Options[j],value:j,selected:(j==value)})); else options.push(create("option", {textContent:"Error - \"options\" needs to be a JSON object.", value:"error", selected:"selected"})); elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('span', {textContent:label, className:'field_label'}), create('select',{id:'field_'+i, kids:options}) ), className: 'config_var'}); break; case 'checkbox': elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('label', {textContent:label, className:'field_label', "for":'field_'+i}), create('input', {id:'field_'+i, type:'checkbox', value:value, checked:value}) ), className: 'config_var'}); break; case 'button': var tmp; elem = create(isKid ? "span" : "div", {kids:new Array( (tmp=create('input', {id:'field_'+i, type:'button', value:label, size:(field.size?field.size:25), title:field.title||''})) ), className: 'config_var'}); if(field.script) obj.addEvent(tmp, 'click', field.script); break; case 'hidden': elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('input', {id:'field_'+i, type:'hidden', value:value}) ), className: 'config_var'}); break; case 'password': elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('span', {textContent:label, className:'field_label'}), create('input', {id:'field_'+i, type:'password', value:value, size:(field.size?field.size:25)}) ), className: 'config_var'}); break; default: elem = create(isKid ? "span" : "div", {title:field.title||'', kids:new Array( create('span', {textContent:label, className:'field_label'}), create('input', {id:'field_'+i, type:'text', value:value, size:(field.size?field.size:25)}) ), className: 'config_var'}); } if(field.kids) { var kids=field.kids; for(var kid in kids) elem.appendChild(obj.addToFrame(kids[kid], kid, true)); } return elem; }, doSave : function(f, field, type, oldf) { var isNum=/^[\d\.]+$/, set = oldf ? GM_config.settings[oldf]["kids"] : GM_config.settings; switch(type) { case 'text': GM_config.values[f] = ((set[f].type=='text') ? field.value : ((isNum.test(field.value) && ",int,float".indexOf(","+set[f].type)!=-1) ? parseFloat(field.value) : false)); if(set[f]===false) { alert('Invalid type for field: '+f+'\nPlease use type: '+set[f].type); return; } break; case 'hidden': case 'password': GM_config.values[f] = field.value.toString(); break; case 'textarea': GM_config.values[f] = field.value; break; case 'checkbox': GM_config.values[f] = field.checked; break; case 'select': GM_config.values[f] = field.options[field.selectedIndex].value; break; case 'span': var radios = field.getElementsByTagName('input'); if(radios.length>0) for(var i=radios.length-1; i>=0; i--) { if(radios[i].checked) GM_config.values[f] = radios[i].value; } break; } }, doSettingValue : function(settings, stored, i, oldi, k) { var set = k!=null && k==true && oldi!=null ? settings[oldi]["kids"][i] : settings[i]; if(",save,open,close".indexOf(","+i) == -1) { // The code below translates to: // if a setting was passed to init but wasn't stored then // if a default value wasn't passed through init() then use null // else use the default value passed through init() // else use the stored value try { var value = (stored[i]==undefined ? (set["default"]==undefined ? null : set["default"]) : stored[i]); } catch(e) { var value = (stored[i]=="undefined" ? (set["default"]=="undefined" ? null : set["default"]) : stored[i]); } // If the value isn't stored and no default was passed through init() // try to predict a default value based on the type if (value === null) { switch(set["type"]) { case 'radio': case 'select': value = set.options[0]; break; case 'checkbox': value = false; break; case 'int': case 'float': value = 0; break; default: value = (typeof stored[i]=="function") ? stored[i] : ""; } } } GM_config.passed_values[i] = value; }, doReset : function(field, type, oldf, f, k) { var isKid = k!=null && k==true, obj=GM_config, set = isKid ? obj.settings[oldf]["kids"][f] : obj.settings[f]; switch(type) { case 'text': field.value = set['default'] || ''; break; case 'hidden': case 'password': field.value = set['default'] || ''; break; case 'textarea': field.value = set['default'] || ''; break; case 'checkbox': field.checked = set['default'] || false; break; case 'select': if(set['default']) { for(var i=field.options.length-1; i>=0; i--) if(field.options[i].value==set['default']) field.selectedIndex=i; } else field.selectedIndex=0; break; case 'span': var radios = field.getElementsByTagName('input'); if(radios.length>0) for(var i=radios.length-1; i>=0; i--) { if(radios[i].value==set['default']) { radios[i].checked=true; } } break; } }, values: {}, settings: {}, css: { basic: 'body {background:#FFFFFF;}\n' + '.indent40 {margin-left:40%;}\n' + '* {font-family: arial, tahoma, sans-serif, myriad pro;}\n' + '.field_label {font-weight:bold; font-size:12px; margin-right:6px;}\n' + '.block {display:block;}\n' + '.saveclose_buttons {\n' + 'margin:16px 10px 10px 10px;\n' + 'padding:2px 12px 2px 12px;\n' + '}\n' + '.reset, #buttons_holder, .reset a {text-align:right; color:#000000;}\n' + '.config_header {font-size:20pt; margin:0;}\n' + '.config_desc, .section_desc, .reset {font-size:9pt;}\n' + '.center {text-align:center;}\n' + '.section_header_holder {margin-top:8px;}\n' + '.config_var {margin:0 0 4px 0; display:block;}\n' + '.config_var {font-size: 13px !important;}\n' + '.section_header {font-size:13pt; background:#414141; color:#FFFFFF; border:1px solid #000000; margin:0;}\n' + '.section_desc {font-size:9pt; background:#EFEFEF; color:#575757; border:1px solid #CCCCCC; margin:0 0 6px 0;}\n' + 'input[type="radio"] {margin-right:8px;}', stylish: '' }, create: function(a,b) { var ret=window.document.createElement(a); if(b) for(var prop in b) { if(prop.indexOf('on')==0) ret.addEventListener(prop.substring(2),b[prop],false); else if(prop=="kids" && (prop=b[prop])) for(var i=0; i<prop.length; i++) ret.appendChild(prop[i]); else if(",style,accesskey,id,name,src,href,for".indexOf(","+prop.toLowerCase())!=-1) ret.setAttribute(prop, b[prop]); else ret[prop]=b[prop]; } return ret; }, center: function() { var node = GM_config.frame, style = node.style, beforeOpacity = style.opacity; if(style.display=='none') style.opacity='0'; style.display = ''; style.top = Math.floor((window.innerHeight/2)-(node.offsetHeight/2)) + 'px'; style.left = Math.floor((window.innerWidth/2)-(node.offsetWidth/2)) + 'px'; style.opacity = '1'; }, run: function() { var script=GM_config.getAttribute('script'); if(script && typeof script=='string' && script!='') { func = new Function(script); window.setTimeout(func, 0); } }, addEvent: function(el, ev, scr) { if(el) el.addEventListener(ev, function() { typeof scr === 'function' ? window.setTimeout(scr, 0) : eval(scr) }, false); }, remove: function(el) { if(el && el.parentNode) el.parentNode.removeChild(el); }, toggle : function(e) { var node=GM_config.frame.contentDocument.getElementById(e); node.style.display=(node.style.display!='none')?'none':''; GM_config.setValue(e, node.style.display); }, }; //============================引用ここまで=================================== //ユーザー設定(User's settings)------------------------------------------------------------------------------------- //設定ボタンの位置調整 var setPos = "margin:0 0 3px 10px"; //ログイン時の設定ボタン(Twitterのアイコンがログインしてるかどうかで位置が変わる) var twitBtn = document.getElementsByClassName("Icon Icon--bird bird-topbar-etched")[0]; if(twitBtn == undefined){ //ログアウト時の設定ボタン twitBtn = document.getElementsByClassName("home")[0]; setPos = "margin:20px 0 0 20px"; } //設定ボタン追加 if(twitBtn != undefined && twitBtn.getAttribute("ToT") != "set"){ twitBtn.insertAdjacentHTML('afterend','<img name="setBtn" id="setBtn" type="button" ' + 'src="data:image/gif;base64,R0lGODlhCwALAIABAACZ/////yH5BAEAAAEALAAAAAALAAsAAAIaBHKha6j5TmrRIdqmkTLu7HHWVmlMZ5XLWgAAOw==" ' + 'title="Config - Thumbnail size">'); twitBtn.setAttribute("ToT","set") ; } //設定ボタンクリックで設定画面を呼び出す(Open Config Window,when click the Config Button) var setBtn = document.getElementById("setBtn"); if(setBtn != undefined){ setBtn.addEventListener('click', function(){openClose()}, true); setBtn.setAttribute("Style",setPos); } //画像クリックで設定画面の開く閉じる切り替え function openClose(){ if(document.evaluate("//iframe[@id='GM_config']",document,null,9,null).singleNodeValue){ GM_config.close(); }else{ GM_config.open(); } } //設定画面(Config Window) GM_config.init('Config - Thumbnail size' /* Script title */, /* Settings object */ //initを連装配列に変更 cfgData, { open: function() { //config window var cfg_Window = document.getElementById("GM_config"); var cfg_body = cfg_Window.contentDocument.getElementsByTagName("body")[0]; cfgClose(document); cfgClose(cfg_body); //ESC押したら設定画面閉じる function cfgClose(doc){ try{ doc.onkeydown = function(evt){ if (evt){ var kc = evt.keyCode; }else{ var kc = event.keyCode; } //GM_log(kc); if(kc!=27){ return; } GM_config.close(); } }catch(e){ GM_log("escClose:"+e); } }//cfgCloseここまで //説明書き var cfg_exSect = cfg_Window.contentDocument.getElementById("c_section_kids_0"); var cfg_importantPoint = cfg_Window.contentDocument.getElementById("field_ImportantPoint"); cfg_exSect.setAttribute("style", "display:block;"); cfg_importantPoint.setAttribute("style", "border:none;resize: none;height:150px;width:100%;disabled:;"); cfg_importantPoint.setAttribute("readonly", ""); //各サムネ設定の配置指定-------------------------------------------------- //共通 var cssCommon = '#buttons_holder{ position:fixed; right:10px; bottom:8px;}'; //解像度低い場合2列表示(幅1280以上を目安。800以下は1列のまま) var css1280 = '@media screen and (min-width: 800px) and (max-width: 1399px){' + '.section_header_holder:nth-child(2n + 3){ height:80px;width:350px;margin:10px 0 0 20px; }' + '.section_header_holder:nth-child(2n + 4){ height:0;width:350px;position:relative;top:-87px;left:400px; }' + '}';//ここまで //解像度高い場合3列表示(幅1600以上を目安) var css1600 = '@media screen and (min-width: 1400px) {' + '.section_header_holder:nth-child(3n+3){ height:80px;width:350px;margin:10px 0 0 20px; }' + '.section_header_holder:nth-child(3n+4){ height:0;width:350px;position:relative;top:-87px;left:400px; }' + '.section_header_holder:nth-child(3n+5){ height:0;width:350px;position:relative;top:-96px;left:800px; }' + '}';//ここまで addStyle(cfg_Window.contentDocument,cssCommon); addStyle(cfg_Window.contentDocument,css1280); addStyle(cfg_Window.contentDocument,css1600); }//openここまで }); //GreaseMonkeyとScriptishのオプション追加(add Option) GM_registerMenuCommand("Config - Thumbnail size", GM_config.open); /* //もしlocalstorageにユーザー設定があったらlocalDBにセット if(tmpDB != null){ localDB = {}; localDB = tmpDB; //greasemonkeyはプロファイルフォルダに独自DBを作成していて、内容を見るにはMySQLなどが必須 }else if(GM_config.get("twitter2Thumb") != undefined && GM_config.get("twitter2Thumb") != null){ */ for(name in titleDB){ if(GM_config.get(name + "Link") != undefined && GM_config.get(name + "Link") != null){ localDB[name + "Link"] = GM_config.get(name + "Link") ; localDB[name + "Thumb"] = GM_config.get(name + "Thumb") ; localDB[name + "Size"] = GM_config.get(name + "Size") ; } } if(GM_config.get("flgDefPic") != undefined && GM_config.get("flgDefPic") != null){ localDB["flgDefPic"] = GM_config.get("flgDefPic"); } }//userCfgここまで //ユーザー関数===================================================================================== function renameTwitgoo(document){ //リンクの修正 var twitgooLinks = document.getElementsByClassName("twitgooText"); for (i = 0; i < twitgooLinks.length; i++){ if(twitgooLinks[i].href.match("twitgoo.com")){ twitgooLinks[i].href = twitgooLinks[i].href.replace("twitgoo","tinypic"); } } //サムネの修正 var twitgooPics = document.getElementsByClassName("twitgooPhoto"); for (i = 0; i < twitgooPics.length; i++){ } } //サーバーDB作成 function makeServerDB(name,title,def){ //localDBに初期値をセット localDB[name + "Link"] = true; localDB[name + "Thumb"] = true; localDB[name + "Size"] = def; localDB["flgDefPic"] = false; //タイトルDB作成 if(title == ""){title = name;} titleDB[name] = title; //サムネサイズDBのひな形作成 if(name != "AllThumbsAndLinks" && name != "alertnotice"){ optionDB[name] = {}; } }//サーバーDB作成ここまで //コンフィグ画面の初期値設定 function makeInitData(){ //メインタイトルのラベル欄-------------------------------------------------- cfgData["ImportantPoint"] = {}; cfgData["ImportantPoint"]["section"] = ['注意点 important point']; cfgData["ImportantPoint"]["type"] = "textarea"; cfgData["ImportantPoint"]["default"] = '1,「名前を付けてリンク先を保存」でオリジナルサイズで保存できます。(「名前を付けて画像を保存」だとサムネ保存)\r\n' + ' "Save Link As..." can save Original size. ("Save Image As..." save Thumbnail)\r\n' + '2,大きいサイズにするとはみ出るので最大400pxにしています。\r\n' + ' max-width 400px,because Large-Thumbnail overflows the frame. \r\n' + '3,サイズ数値は大体の目安です。The size is approximate value \r\n' + '4,この解説を読み終わったらタイトルバーをクリックしてSAVEすると非表示にできます。 \r\n' + ' If finished reading, clicked title bar and saved, it can do undisplayed next-time. \r\n'; //alert(JSON.stringify(optionDB["droplr"])); //twtitterが追加するサムネの表示設定 cfgData["flgDefPic"] = {}; cfgData["flgDefPic"]["section"] = ['twitter側のサムネ Thumbs added by twitter']; cfgData["flgDefPic"]["label"] = "表示する show"; cfgData["flgDefPic"]["type"] = "checkbox"; cfgData["flgDefPic"]["default"] = false; //サービス名ごとに作成 for(key in titleDB){ initSet(key); } //サービス設定欄初期値作成 function initSet(name){ //リンク欄-------------------------------------------------- //その他の画像URLにサムネ追加対応(リンク追加設定は除外) if(name == "alertnotice"){ var strLink = name + "Link"; cfgData[strLink] = {}; cfgData[strLink]["section"] = [titleDB[name]]; cfgData[strLink]["label"] = '通知音を鳴らす(pray alert sound)'; cfgData[strLink]["type"] = "checkbox"; cfgData[strLink]["default"] = localDB[name + "Size"]; return; }else if(name != "otherPic"){ var strLink = name + "Link"; cfgData[strLink] = {}; cfgData[strLink]["section"] = [titleDB[name]]; cfgData[strLink]["label"] = "保存用リンク追加 Add Save Link"; cfgData[strLink]["type"] = "checkbox"; cfgData[strLink]["default"] = true; } //サムネ欄-------------------------------------------------- var strThumb = name + "Thumb"; cfgData[strThumb] = {}; //その他の画像URLにサムネ追加対応 if(name == "otherPic"){ cfgData[strThumb]["section"] = [titleDB[name]]; } cfgData[strThumb]["label"] = 'サムネ追加 Add Thumb'; cfgData[strThumb]["type"] = "checkbox"; cfgData[strThumb]["default"] = true; //サムネサイズ欄-------------------------------------------------- if(name == "AllThumbsAndLinks"){ var strSize = name + "Size"; cfgData[strSize] = {}; cfgData[strSize]["label"] = '短縮URL展開 Expand URL(t.co)'; cfgData[strSize]["type"] = "checkbox"; cfgData[strSize]["default"] = localDB[name + "Size"]; }else{ var strSize = name + "Size"; cfgData[strSize] = {}; cfgData[strSize]["label"] = 'サイズ変更 size of thumb'; cfgData[strSize]["type"] = "select"; cfgData[strSize]["options"] = optionDB[name]; //選択肢を配列でセット cfgData[strSize]["default"] = localDB[name + "Size"]; //デフォルト値 } }//サービス設定欄初期値作成ここまで }//コンフィグ画面の初期値設定ここまで //CSSを追加------------------------------------------------ function addStyle(document,css) { var head = document.getElementsByTagName('head')[0]; if (!head) { return }; var style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } //新着通知 function chime(node){ if(!node && !node.hasAttribute("class")){return;} //検索結果 var newSearch = document.evaluate('.//div[@class="new-tweets-bar js-new-tweets-bar "]', node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); try{ var nClass = node.getAttribute("class"); }catch(e){ switch( e.name ){ case 'TypeError': // GM_log("NewTweet-TypeError:" + e); return; default: GM_log("NewTweet-Error:" + e); } } if(nClass != "Grid" //ユーザーページの更新以外 && newSearch.snapshotItem(0) == null){ //検索やタイムラインの更新以外 return; }else{ audio.play(); // alert(newSearch.snapshotItem(0).innerHTML); } } //url展開 function expandUrl(type,obj,size){ var url = obj.href; if(obj.hasAttribute("ToT_URL") && obj.getAttribute("ToT_URL").match(/^http/)){ url = obj.getAttribute("ToT_URL"); obj.setAttribute("ToT_URL","NowLoading:" + url); } GM_xmlhttpRequest({ method: type, url: url, onload: function (res) { try{ //短縮URLの展開用 if(type == "HEAD"){ //Flickr短縮URL if(url.match(/^https?:\/\/flic.kr\/(p|s)\/.*/)){ //GM_log(res.finalUrl); obj.setAttribute("data-expanded-url",res.finalUrl.replace(/\?.*/,"")); //Fickr画像URLから元のURL取得 }else if(url.match(/^https:\/\/flickr.com\/photo.gne\?id=/)){ //何故かURLが取得できずにyahooにログインを求められるパターンがあるので元URLが取得できない if(res.finalUrl.match(/^https?:\/\/login.yahoo.com\/config\/login/)){ obj.setAttribute("ToT_URL","Error:" + url); }else{ obj.setAttribute("ToT_URL",res.finalUrl.replace(/\?.*/,"")); } //tumblr短縮URL }else if(url.match(/^https?:\/\/(www.)?tu?mblr.com?\/[a-zA-Z0-9].*$/)){ obj.setAttribute("data-expanded-url",res.finalUrl.replace(/#.*/,"")); } //メインに戻す main(obj.parentNode); return; //画像URLの取得用 }else if(type == "GET"){ //twitter1 if(!obj.hasAttribute("ToT_URL") && url.match(/^https?:\/\/pic.twitter.com/)){ obj.setAttribute("ToT_URL",res.responseText.replace(/.*\;URL\=(http.*?)\"\>.*/i,"$1")); expandUrl('GET',obj); return; } //twitter1の展開した後さらに展開して画像URL取得 if(obj.hasAttribute("ToT_URL") && obj.getAttribute("ToT_URL").match(/^NowLoading:https?:\/\/twitter.com.*\/photo\//)){ //GM_log(res.responseText); var num = res.responseText.match(/<div class="multi-photos photos-(.*?)">/); if(num){ num = num[1]} //複数枚なら var array = res.responseText.match(/<img src="(https?:\/\/pbs.twimg.com\/media.*?)"/g); var reg = new RegExp('<img src="(.*)"$'); var strTmp = array[0].replace(reg,"$1"); //複数画像対応 if(array.length>1){ for(t=0;t < num;t++){ twitter1DB[obj.href].push(array[t].replace(reg,"$1")); } } obj.setAttribute("ToT_URL",strTmp); main(obj.parentNode); return; } //Flickr(メイン関数→サムネ入手後→オリジナル入手→メイン関数へ) if(obj.hasAttribute("ToT_URL") && url.match(/^https?:\/\/(www.)?flickr.com\/photos\//)){ //サムネ側のURL if(size || size == ""){ var tmpReg = new RegExp('<img src="(https?:\/\/.*?static.?flickr.*?' + size + '..*)">'); flickrSrcDB[obj.href] = res.responseText.match(tmpReg)[1]; //オリジナルサイズを取得へ obj.setAttribute("ToT_URL",url.replace(/\/sizes\/.*/,"\/sizes/o/")); expandUrl('GET',obj); return; //オリジナルサイズ側のURL }else if(url.match(/\/sizes\/o\//)){ var tsize = "o"; //オリジナルサイズがoじゃなかったら変更 if(!res.finalUrl.match(/sizes\/o\/?$/)){ tsize = res.finalUrl.replace(/.*sizes\/(.*?)\/$/i,"$1"); tsize = flickrSize(tsize); } var reg = new RegExp('<img src="(https?:\/\/.*?static.?flickr.*?' + tsize + '..*?)">'); obj.setAttribute("ToT_URL",res.responseText.match(reg)[1]); main(obj.parentNode); return; } } //携帯百景movapic if(url.match(/^https?:\/\/movapic.com\/.*?\/pic\/.*$/)){ obj.setAttribute("ToT_URL",res.responseText.match(/<img class="image" src="(https?:\/\/image.movapic.com\/pic\/.*?..*?)"\/>/)[1]); main(obj.parentNode); return; } //tumblr if(url.match(/^http:\/\/[\w\-]+.tumblr.com\/image\/[0-9]+.*$/)){ //オリジナルサイズ var tempUrl = res.responseText.match(/data-src="(http:\/\/\d+.media.tumblr.com\/(.*?\/)?.*_\d+..*)" data-height/)[1]; obj.setAttribute("ToT_URL",tempUrl); main(obj.parentNode); return; } } }catch(e){ GM_log(e); return; } }//onloadここまで }); } //flickrのサイズ修正 function flickrSize(size){ if(size == "sq"){ size = "_s"; }else if(size == "s"){ size = "_m"; }else if(size == "m"){ size = ""; }else if(size == "l"){ size = "_b"; }else{ size = "_" + size; } return size; } //ユーザー関数ここまで============================================================================ //引用開始=================================================================================== //============================================================== //すでに組まれている方がいたのでソースを拝借(少し書き換え) //Copyright:NeoCat //http://d.hatena.ne.jp/NeoCat/20091228/1262015896 //============================================================== /* //base58デコード function decodeBase58(snipcode) { var base58_letters = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'; var ret = 0; for (var i = snipcode.length, m = 1; i; i--, m *= 58) ret += base58_letters.indexOf(snipcode.substr(i-1,1)) * m; return ret; } //画像ID取得(マッチしないとundefined) function flickrPhotoID(url) { if (url.match(/^http:\/\/(?:www\.flickr\.com\/photos\/[\w-_@]+\/(\d+)|flic\.kr\/p\/(\w+)$)/)) return RegExp.$2 ? decodeBase58(RegExp.$2) : RegExp.$1; } //URL整形 function getUrl(response){ var p = response.photo; if (!p) return; var url = 'http://farm' + p.farm + '.static.flickr.com/' + p.server + '/' + p.id + '_' + p.secret + '_s.jpg'; // このurlを使って何かする } */ //引用ここまで=============================================================================== })();