您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
还可以显示鸣叫来源标签。
当前为
// ==UserScript== // @name Show ctime of retweets // @name:ja リツイート自体の日時を表示します // @name:ko 리트윗 날짜와 시간을 표시합니다. // @name:zh-CN 显示转发的日期和时间。 // @name:zh-TW 顯示轉發的日期和時間。 // @namespace https://gf.qytechs.cn/en/scripts/462070-show-ctime-of-retweets // @version 1.1.0 // @description And shows tweet source labels. // @description:ja ツイートソースラベルも表示できます。 // @description:ko 트윗 소스 라벨도 표시할 수 있습니다. // @description:zh-CN 还可以显示鸣叫来源标签。 // @description:zh-TW 還可以顯示鳴叫來源標籤。 // @author AeamaN // @contributionURL bitcoin:1DC6uWJWzzwU3iRJDXhUquv6QAYaRvtfFJ // @match https://twitter.com/* // @match https://mobile.twitter.com/* // @match https://twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/* // @match https://mobile.twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/* // @grant GM.getValue // @grant GM.registerMenuCommand // @grant GM.setValue // @run-at document-idle // ==/UserScript== // // ES2017(ES8) or later. // // ES2017(ES8) 以降が必要です。 // // ES2017(ES8) 이상이 필요합니다. // // 需要 ES2017(ES8) 或更高版本。 // // 需要 ES2017(ES8) 或更高版本。 (async function() { /* START */ 'use strict'; // //////////// Settings //////////// // // No GUI Settings // Default values are used. const NOGUI = false; // ////////////////////////////////// // // ///////// Default valuse ///////// // // Date formats // 1. 31.12.70 23:59 // 2. 31.12.70(Th) 23:59 // 3. 31.12.70 23:59:59 // 4. 31.12.70(Th) 23:59:59 // // 5. 70-12/31 23:59 // 6. 70-12/31(Th) 23:59 // 7. 70-12/31 23:59'59 // 8. 70-12/31(Th) 23:59'59 // // 9. 70/12/31 23:59 // 10. 70/12/31(Th) 23:59 // 11. 70/12/31 23:59:59 // 12. 70/12/31(Th) 23:59:59 [ye/mo/da(we) ho:mi:se] // // 0. Not Shown const FMT = 10; // Show source labels // 1. Tweet only // 2. Tweet and (Retweet) // 0. Not shown const SSL = 2; // Loop interval(ms) // const INTL = 1000; const INTL = 800; // ////////////////////////////////// // const MYNAME = 'sctrt110'; const BTKN = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs' + '=1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'; const EBTKN = encodeURIComponent(BTKN); let top_sr = '1'; let json_sr = []; let json_sr_new = []; let timeout_sr = false; let s_mus = true; let observer = new MutationObserver(function(mutations) { s_mus = mutations; }); let fmt, ssl, intl; let dalg; let cookie = { // "https://qiita.com/aqril_1132/items/925a7cb04276d9f916d7" getObj: function() { let cookie = document.cookie; let cookieObj = {}; if (!!cookie) { Array.prototype.forEach.call(cookie.split(';'), function(c) { let array = [c][0].split('=').map(function(a) {return a.trim()}); let key = ~c.indexOf('=') ? unescape(array[0]) : ''; let val = ~c.indexOf('=') ? unescape(array[1]) : unescape(array[0]); if (!cookieObj.hasOwnProperty(key)) { cookieObj[key] = [val]; } else { cookieObj[key].push(val); } }); } return cookieObj; }, getByName: function(name) { let ret = []; let cookieObj = this.getObj(); if (cookieObj.hasOwnProperty(name)) { ret = cookieObj[name]; } return ret; }, deleteByName : function(name, path) { var str = escape(name) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (path ? '; path=' + path : ''); document.cookie = str; } }; async function main_track() { s_mus = null; // 不要? const SEL_END = 'main div[data-testid="primaryColumn"] section article span.css-cens5h.r-b88u0q:not([aria-label])'; const SEL_RTTO = `div[data-testid^="User-Name"] a.css-901oao.r-qvutc0:not(.us-${MYNAME})`; // UTL, HTL const SEL_RTTO_2 = 'main div[data-testid="primaryColumn"] section article ' + `div.css-1dbjc4n.r-1d09ksm.r-1471scf.r-18u37iz.r-1wbh5a2 a.css-901oao.r-qvutc0:not(.us-${MYNAME})`; // Retweet def-ja, def-en, ble-ja, ble-en const SEL_ADD = `a.us-${MYNAME}`; let elms; let pe, fpe, xpe, elm2, old, span, span2, a; let sn, rtto, date; let id, stats; elms = document.querySelectorAll(SEL_END); for(let elm of elms) { pe = elm.parentNode; fpe = elm.parentNode.parentNode.parentNode.parentNode; sn = pe.getAttribute('href').slice(1); xpe = elm.closest('article'); elm2 = xpe.querySelector(SEL_RTTO); if(!elm2) elm2 = xpe.querySelector(SEL_RTTO_2); rtto = elm2.getAttribute('href').split('/')[3]; id = await touid(sn); // screen name -> id, blue, created_at, screen_name, verified if(!id) continue; stats = await statsrt(id[0], rtto); // id, rtto -> tid, tca if(!fmt) continue; old = fpe.querySelector(SEL_ADD) if(!old) { span = document.createElement('span'); span.className = `us-${MYNAME}`; span.style.margin = '0px 3px 0px 3px'; span.textContent = '·'; span.style.color = getComputedStyle(elm, null).color; span.style.font = getComputedStyle(elm, null).font; span.style.lineHeight = getComputedStyle(pe, null).lineHeight; span2 = document.createElement('span'); span2.className = `us-${MYNAME}`; span2.style.lineHeight = getComputedStyle(pe, null).lineHeight; span2.style.display = 'inline-block'; a = document.createElement('a'); a.className = `us-${MYNAME}`; a.setAttribute('dir', 'ltr'); a.setAttribute('role', 'link'); a.setAttribute('href', `/${sn}/status/${stats[0]}`); a.setAttribute('target', '_blank'); a.setAttribute('rel', 'noopener noreferrer'); date = datef(new Date(stats[1]), fmt); a.textContent = date; a.style.color = getComputedStyle(elm, null).color; a.style.font = getComputedStyle(elm, null).font; a.style.textDecoration = getComputedStyle(elm, null).textDecoration; fpe.appendChild(span); fpe.appendChild(span2); span2.appendChild(a); s_mus = null; } else { date = datef(new Date(stats[1]), fmt); if(old.textContent != date) old.textContent = date; // TZ change } } } async function touid(sn) { if(localStorage.getItem(`${MYNAME}_idl`) === null) { // 無い時 let s = JSON.stringify(await getuid(sn)); // screen name -> id, blue, created_at, screen_name, verified if(s) { localStorage.setItem(`${MYNAME}_idl`, s); } else { console.log(`${MYNAME}: touid:error.`); return null; // エラー } } let str = localStorage.getItem(`${MYNAME}_idl`); // ある時はココから let json = JSON.parse(str); for(let e of json) { if(e[3] == sn) return e; } json = json.concat(await getuid(sn)); // あるけど、無い時 str = JSON.stringify(json); localStorage.setItem(`${MYNAME}_idl`, str); for(let e of json) { if(e[3] == sn) return e; } console.log(`${MYNAME}: touid:error:end.`); return null; // エラー } async function getuid(s_name) { let url = 'https://api.twitter.com/graphql/rePnxwe9LZ51nQ7Sn_xN_A/UserByScreenName'; if(/^[^:]+:\/\/[^/]+\.onion\//i.test(document.URL)) { url = 'https://api.twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/' + 'graphql/rePnxwe9LZ51nQ7Sn_xN_A/UserByScreenName'; } let q = '?variables={' + `"screen_name":"${s_name}",` + '"withSafetyModeUserFields":true,' + '"withSuperFollowsUserFields":true' + '}' + '&features={' + '"responsive_web_twitter_blue_verified_badge_is_enabled":true,' + '"responsive_web_graphql_exclude_directive_enabled":false,' // false + '"verified_phone_label_enabled":true,' // false + '"responsive_web_graphql_skip_user_profile_image_extensions_enabled":false,' + '"responsive_web_graphql_timeline_navigation_enabled":true' + '}'; let eq = encodeURI(q); let controller = new AbortController(); let req = mkreq(url, eq, EBTKN, controller); let res = {}; try { setTimeout(function() {controller.abort()}, 60000); res = await fetch(req); if(!res.ok) { console.log(`${MYNAME}: getuid:error:` + res.ok + '.'); return null; } // 失敗なら空で終わり } catch(err) { console.log(`${MYNAME}: getuid:error:` + err + '.'); return null; // 失敗なら空で終わり } let json = JSON.parse(await res.text()); let id, bl, ca, sn, vf; id = json.data.user.result.rest_id; bl = json.data.user.result.is_blue_verified; ca = json.data.user.result.legacy.created_at; sn = json.data.user.result.legacy.screen_name; vf = json.data.user.result.legacy.verified; return [[id, bl, ca, sn, vf]]; } async function statsrt(uid, rtto) { // 連続している事、entries[]の順序が正しい事 let num = localStorage.length; let keys = []; let str = ''; let time = null; top_sr = '1'; json_sr = []; json_sr_new = []; timeout_sr = false; // 初期化 for(let i = 0; i < num; i++) { keys.push(localStorage.key(i)); } if(!keys.includes(`${MYNAME}_tl_` + uid)) { // 無い時 let s = JSON.stringify(await gettl(uid, null)); // id, cursor -> tid, tca, s, rtid, rtca if(s) { localStorage.setItem(`${MYNAME}_tl_` + uid, s); } else { console.log(`${MYNAME}: statsrt:error.`); return ['0000000000000000000', 'Thu Jan 01 00:00:00 +0000 1970']; // エラー } } if(localStorage.getItem(`${MYNAME}_timerl`) === null) { time = Date.now(); localStorage.setItem(`${MYNAME}_timerl`, JSON.stringify([[uid, time]])); } else { let j = JSON.parse(localStorage.getItem(`${MYNAME}_timerl`)); for(let e of j) if(e[0] == uid) time = e[1]; if(!time) { // 項目が無い時 time = Date.now(); // この時点の保存値にセットされる j = j.concat([[uid, time]]); localStorage.setItem(`${MYNAME}_timerl`, JSON.stringify(j)); } } str = localStorage.getItem(`${MYNAME}_tl_` + uid); // ある時はココから json_sr = JSON.parse(str); for(let e of json_sr) { if(e[3] == rtto) return [e[0], e[1]]; // あれば終わり } for(let e of json_sr) { if(/^[0-9]/i.test(e[0])) { top_sr = e[0]; break; } } // 上作成 await statsrt_new(uid, rtto); // json_sr、json_sr_new更新 json_sr = json_sr_new.concat(json_sr); // json_sr更新 str = JSON.stringify(json_sr); // str更新 localStorage.setItem(`${MYNAME}_tl_` + uid, str); // とりあえず、ストレージに保存 for(let e of json_sr) { if(e[3] == rtto) return [e[0], e[1]]; // あれば終わり } let ret = await statsrt_old(uid, rtto); // json_sr更新、保存 if(ret) return ret; let j = JSON.parse(localStorage.getItem(`${MYNAME}_timerl`)); for(let e of j) if(e[0] == uid) time = e[1]; // time更新 if(!timeout_sr && Date.now() - time > 600000) { localStorage.removeItem(`${MYNAME}_tl_${uid}`); // センシティブ console.log(`${MYNAME}: statsrt:remove:${MYNAME}_tl_${uid}.`); j = j.filter(function(e) { return e[0] != uid; }); localStorage.setItem(`${MYNAME}_timerl`, JSON.stringify(j)); time = null; } console.log(`${MYNAME}: statsrt:end.`); return ['0000000000000000000', 'Thu Jan 01 00:00:00 +0000 1970']; // TLがとても古いか、センシティブか、エラー } async function statsrt_new(uid, rtto) { // json_sr、json_sr_new更新 let btmtmp = ''; outer_block: for(const start = Date.now(); 1;) { // 新しい方、top_srを見る let ret = await gettl(uid, btmtmp); json_sr_new = json_sr_new.concat(ret); // json_sr_new更新 for(let e of json_sr_new.slice().reverse()) { // 不要 if(/^[0-9]/i.test(e[0])) { btmtmp = e[0]; break; } } // 下更新 if(ret.length < 2) { json_sr = []; // 非連続 let j = JSON.parse(localStorage.getItem(`${MYNAME}_timerl`)); j = j.filter(function(e) { return e[0] != uid; }); j = j.concat([[uid, Date.now()]]); localStorage.setItem(`${MYNAME}_timerl`, JSON.stringify(j)); break; } // 空の時は終了、一回目は無い(一個の時以外) for(let e of json_sr_new) { if(e[0] == top_sr) break outer_block; // あれば終了 } if(Date.now() - start > 150000) { // 時間経過時打ち切り json_sr = []; // 非連続かも let j = JSON.parse(localStorage.getItem(`${MYNAME}_timerl`)); j = j.filter(function(e) { return e[0] != uid; }); j = j.concat([[uid, Date.now()]]); localStorage.setItem(`${MYNAME}_timerl`, JSON.stringify(j)); break; } await new Promise(resolve => setTimeout(resolve, 200)); } } async function statsrt_old(uid, rtto) { let btm = ''; for(const start = Date.now(); 1;) { // 古い方、rttoを見る for(let e of json_sr.slice().reverse()) { // 不要 if(/^[0-9]/i.test(e[0])) { btm = e[0]; break; } } // 下更新 let ret = await gettl(uid, btm); json_sr = json_sr.concat(ret); // json_sr更新 let s = JSON.stringify(json_sr); localStorage.setItem(`${MYNAME}_tl_` + uid, s); // とりあえず、ストレージに保存 if(ret.length < 2) { break; } // 空の時は終了 for(let e of json_sr) { if(e[3] == rtto) return [e[0], e[1]]; // あれば終わり } if(Date.now() - start > 300000) { timeout_sr = true; break; } // 時間経過時打ち切り await new Promise(resolve => setTimeout(resolve, 200)); } } async function gettl(id, cs) { let url = 'https://api.twitter.com/1.1/statuses/user_timeline.json'; if(/^[^:]+:\/\/[^/]+\.onion\//i.test(document.URL)) { url = 'https://api.twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/' + '1.1/statuses/user_timeline.json'; } let kav = ''; if(cs) kav = `&max_id=${cs}`; let q = `?user_id=${id}&count=50${kav}`; let eq = encodeURI(q); let controller = new AbortController(); let req = mkreq(url, eq, EBTKN, controller); let res = {}; let ret = []; try { setTimeout(function() {controller.abort()}, 60000); res = await fetch(req); if(!res.ok) { console.log(`${MYNAME}: gettl:error:` + res.ok + '.'); return null; } // 失敗なら空で終わり } catch(err) { console.log(`${MYNAME}: gettl:error:` + err + '.'); return null; // 失敗なら空で終わり } let json = JSON.parse(await res.text()); let num = Object.keys(json).length; let tid, tca, s, rtid, rtca; for(let i = 0; i < num; i++) { tid = json[i].id_str; tca = json[i].created_at; s = json[i].source; if(typeof(json[i].retweeted_status) !== 'undefined') { rtid = json[i].retweeted_status.id_str; rtca = json[i].retweeted_status.created_at; } else { rtid = 'none'; rtca = 'none'; } ret.push([tid, tca, s, rtid, rtca]); } return ret; } async function addsl() { s_mus = null; // 不要? const SEL_END = 'main div[data-testid="primaryColumn"] section article div.css-1dbjc4n.r-1d09ksm.r-1471scf.r-18u37iz.r-1wbh5a2'; const SEL_END_RT = 'main div[data-testid="primaryColumn"] section article span.css-cens5h.r-b88u0q:not([aria-label])'; const SEL_ADD = `span.us-${MYNAME}`; let old; let ca, span, span2, a, a2; let elms_end = document.querySelectorAll(SEL_END); for(let elm of elms_end) { let uid; let tid; let tsl = '?'; let rtsl = '(?)'; let thref = 'https://help.twitter.com/using-twitter/how-to-tweet#source-labels'; if(/^[^:]+:\/\/[^/]+\.onion\//i.test(document.URL)) { thref = 'https://help.twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/using-twitter/how-to-tweet#source-labels'; } let rthref = thref; ca = elm.querySelector('a'); tid = ca.getAttribute('href').split('/')[3]; let detl = await getdetl(tid); // tid -> tca, s, uid, sn, uca if(detl) { tsl = detl[1].split('<')[1].split('>')[1]; thref = detl[1].split('"')[1]; } let elm_end_rt = document.querySelector(SEL_END_RT); if(elm_end_rt) { let pe = elm_end_rt.parentNode; let sn = pe.getAttribute('href').slice(1); uid = await touid(sn); // screen name -> id, blue, created_at, screen_name, verified // リツイートした人のuid } if(ssl == 1 || !elm_end_rt) { ; } else if(uid && localStorage.getItem(`${MYNAME}_tl_${uid[0]}`) !== null) { let str = localStorage.getItem(`${MYNAME}_tl_${uid[0]}`); let json = JSON.parse(str); for(let e of json) { if(e[3] == tid) { rtsl = '(' + e[2].split('<')[1].split('>')[1] + ')'; rthref = e[2].split('"')[1]; } } } old = elm.querySelectorAll(SEL_ADD) if(!old.length) { span = document.createElement('span'); span.className = `us-${MYNAME}`; span.style.margin = '0px 3px 0px 3px'; span.textContent = '·'; span.style.color = getComputedStyle(ca, null).color; span.style.font = getComputedStyle(ca, null).font; span.style.lineHeight = getComputedStyle(elm, null).lineHeight; span2 = document.createElement('span'); span2.className = `us-${MYNAME}`; span2.style.lineHeight = getComputedStyle(elm, null).lineHeight; span2.style.display = 'inline-block'; a = document.createElement('a'); a.className = `us-${MYNAME}`; a.setAttribute('role', 'link'); a.setAttribute('href', thref); a.setAttribute('target', '_blank'); a.setAttribute('rel', 'nofollow noopener noreferrer'); a.textContent = tsl; a.style.color = getComputedStyle(ca, null).color; a.style.font = getComputedStyle(ca, null).font; a.style.textDecoration = getComputedStyle(ca, null).textDecoration; a2 = document.createElement('a'); a2.className = `us-${MYNAME}`; a2.setAttribute('role', 'link'); a2.setAttribute('href', rthref); a2.setAttribute('target', '_blank'); a2.setAttribute('rel', 'nofollow noopener noreferrer'); a2.textContent = rtsl; a2.style.color = getComputedStyle(ca, null).color; a2.style.font = getComputedStyle(ca, null).font; a2.style.textDecoration = getComputedStyle(ca, null).textDecoration; elm.appendChild(span); elm.appendChild(span2); span2.appendChild(a); if(ssl == 2 && elm_end_rt) span2.appendChild(a2); s_mus = null; } } } async function getdetl(tid) { let url = 'https://api.twitter.com/1.1/statuses/show.json'; if(/^[^:]+:\/\/[^/]+\.onion\//i.test(document.URL)) { url = 'https://api.twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/' + '1.1/statuses/show.json'; } let q = `?id=${tid}`; let eq = encodeURI(q); let controller = new AbortController(); let req = mkreq(url, eq, EBTKN, controller); let res = {}; try { setTimeout(function() {controller.abort()}, 60000); res = await fetch(req); if(!res.ok) { console.log(`${MYNAME}: getdtl:error:` + res.ok + '.'); return null; } // 失敗なら空で終わり } catch(err) { console.log(`${MYNAME}: getdtl:error:` + err + '.'); return null; // 失敗なら空で終わり } let json = JSON.parse(await res.text()); let num = 1; // 一個しかない let tca, s, uid, sn, uca; for(let i = 0; i < num; i++) { tca = json.created_at; s = json.source; if(typeof(json.user) !== 'undefined') { uid = json.user.id_str; sn = json.user.screen_name; uca = json.user.created_at; } else { uid = 'none'; sn = 'none'; uca = 'none'; } } return [tca, s, uid, sn, uca]; } function mkreq(url, eq, ebt, controller) { let req; if(cookie.getByName('gt').length && !cookie.getByName('twid').length) { req = new Request(`${url}${eq}`,{ headers: { 'authorization': `Bearer ${ebt}`, 'x-csrf-token': cookie.getByName('ct0')[0], 'x-guest-token': cookie.getByName('gt')[0] }, cache: 'force-cache', redirect: 'follow', signal: controller.signal }); } else { req = new Request(`${url}${eq}`,{ headers: { 'authorization': `Bearer ${ebt}`, 'x-csrf-token': cookie.getByName('ct0')[0], 'x-twitter-auth-type': 'OAuth2Session' }, cache: 'force-cache', redirect: 'follow', mode: 'cors', credentials: 'include', signal: controller.signal }); } return req; } function datef(date, f) { let week_l; let l = document.documentElement.getAttribute('lang'); l == 'ja' ? week_l = ['日', '月', '火', '水', '木', '金', '土'] : l == 'ko' ? week_l = ['일', '월', '화', '수', '목', '금', '토'] : l == 'zh-Hant' ? week_l = ['日', '一', '二', '三', '四', '五', '六'] : l == 'zh' ? week_l = ['日', '一', '二', '三', '四', '五', '六'] : l == 'ru' ? week_l = ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'] : l == 'de' ? week_l = ['Son', 'Mon', 'Die', 'Mit', 'Don', 'Fre', 'Sam'] : l == 'it' ? week_l = ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'] : l == 'fr' ? week_l = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'] : l == 'pt' ? week_l = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'] // Add your language : week_l = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; let ye, mo, da, we, ho, mi, se; ye = date.getFullYear().toString().slice(-2); mo = ('0' + (date.getMonth() + 1)).slice(-2); da = ('0' + date.getDate()).slice(-2); we = week_l[date.getDay()]; ho = ('0' + date.getHours()).slice(-2); mi = ('0' + date.getMinutes()).slice(-2); se = ('0' + date.getSeconds()).slice(-2); return f == 1 ? `${da}.${mo}.${ye} ${ho}:${mi}` : f == 2 ? `${da}.${mo}.${ye}(${we}) ${ho}:${mi}` : f == 3 ? `${da}.${mo}.${ye} ${ho}:${mi}:${se}` : f == 4 ? `${da}.${mo}.${ye}(${we}) ${ho}:${mi}:${se}` : f == 5 ? `${ye}-${mo}/${da} ${ho}:${mi}` : f == 6 ? `${ye}-${mo}/${da}(${we}) ${ho}:${mi}` : f == 7 ? `${ye}-${mo}/${da} ${ho}:${mi}'${se}` : f == 8 ? `${ye}-${mo}/${da}(${we}) ${ho}:${mi}'${se}` : f == 9 ? `${ye}/${mo}/${da} ${ho}:${mi}` : f == 10 ? `${ye}/${mo}/${da}(${we}) ${ho}:${mi}` : f == 11 ? `${ye}/${mo}/${da} ${ho}:${mi}:${se}` : f == 12 ? `${ye}/${mo}/${da}(${we}) ${ho}:${mi}:${se}` : `${ye}/${mo}/${da}(${we}) ${ho}:${mi}:${se}`; } function makeDialog() { let dalg = document.createElement('div'); dalg.className = `us-${MYNAME}`; dalg.style.all = 'initial'; dalg.style.backgroundColor = 'rgb(235, 235, 235)'; dalg.style.border = '3px outset'; dalg.style.borderRadius = '1%'; dalg.style.display = 'none'; dalg.style.fontFamily = 'monospace'; dalg.style.fontSize = '12px'; dalg.style.height = '340px'; dalg.style.width = '400px'; dalg.style.paddingLeft = '2px'; dalg.style.paddingRight = '2px'; dalg.style.position = 'fixed'; dalg.style.right = '8px'; dalg.style.top = '8px'; dalg.style.zIndex = '2147483647'; let html = '<span style="all: initial; font-size: 120%; line-height: 140%">' + `${GM.info.script.name} ${GM.info.script.version} Settings` + '</span><br />\n' + `<input type="radio" name="fmt" value="1" class="top_r" />31.12.70 23:59` + ` ` + `<input type="radio" name="fmt" value="9" class="top_r" />70/12/31 23:59<br />\n` + `<input type="radio" name="fmt" value="2" class="mid_r" />31.12.70(Th) 23:59` + ` ` + `<input type="radio" name="fmt" value="10" class="mid_r" />70/12/31(Th) 23:59<br />\n` + `<input type="radio" name="fmt" value="3" class="mid_r" />31.12.70 23:59:59` + ` ` + `<input type="radio" name="fmt" value="11" class="mid_r" />70/12/31 23:59:59<br />\n` + `<input type="radio" name="fmt" value="4" class="mid_r" />31.12.70(Th) 23:59:59` + ` ` + `<input type="radio" name="fmt" value="12" class="mid_r" />70/12/31(Th) 23:59:59<br />\n` + `<input type="radio" name="fmt" value="5" class="mid_r" />70-12/31 23:59` + ` ` + `<input type="radio" name="fmt" value="0" class="mid_r" />Not Shown<br />\n` + `<input type="radio" name="fmt" value="6" class="mid_r" />70-12/31(Th) 23:59<br />\n` + `<input type="radio" name="fmt" value="7" class="mid_r" />70-12/31 23:59'59<br />\n` + `<input type="radio" name="fmt" value="8" class="btm_r" />70-12/31(Th) 23:59'59<br />\n` + `<input type="radio" name="ssl" value="1" class="top_r" />Tweet source labels only` + ` ` + `<input type="radio" name="ssl" value="0" class="top_r" />Not shown<br />\n` + `<input type="radio" name="ssl" value="2" class="btm_r" />Tweet and (Retweet)<br />\n` + '<span style="all: initial; font-size: 100%">' + 'Loop interval(ms) ' + '</span><input type="text" name="intl" size="10" class="top_t" /><br />\n' + '<input type="button" class="top_b" value="Cancel" />\n' + '<input type="button" class="top_b" value="Set default" />\n' + '<input type="button" class="top_b" value="Save & Close" />\n'; dalg.innerHTML = html; for(let e of dalg.querySelectorAll('input.top_r')) { e.style.all = 'initial'; e.style.appearance = 'auto'; e.style.marginRight = '1px'; e.style.marginTop = '8px'; } for(let e of dalg.querySelectorAll('input.mid_r, input.btm_r')) { e.style.all = 'initial'; e.style.appearance = 'auto'; e.style.marginRight = '1px'; e.style.marginTop = '1px'; } for(let e of dalg.querySelectorAll('input.top_t')) { e.style.all = 'initial'; e.style.backgroundColor = 'rgb(255, 255, 255)'; e.style.fontFamily = 'monospace'; e.style.fontSize = '100%'; e.style.marginLeft = '1px'; e.style.marginRight = '1px'; e.style.marginTop = '8px'; e.style.marginBottom = '0px'; e.style.paddingLeft = '1px'; e.style.paddingRight = '1px'; e.style.paddingTop = '1px'; e.style.paddingBottom = '1px'; } for(let e of dalg.querySelectorAll('input.top_b')) { e.style.all = 'initial'; e.style.backgroundColor = 'rgb(190, 190, 190)'; e.style.borderRadius = '10%'; e.style.cursor = 'default'; e.style.fontSize = '110%'; e.style.marginTop = '10px'; e.style.marginBottom = '0px'; e.style.paddingTop = '6px'; e.style.paddingBottom = '6px'; e.style.textAlign = 'center'; e.style.width = '90px'; } return dalg; } function makeFunc(dalg) { dalg.addEventListener('click', function(event) { event.stopPropagation(); }, false); dalg.querySelector('input[value="Cancel"]').addEventListener('click', function() { dalg.style.display = 'none'; }, false); dalg.querySelector('input[value="Cancel"]').addEventListener('mouseenter', function(event) { event.target.style.backgroundColor = 'rgb(170, 170, 170)'; }, false); dalg.querySelector('input[value="Cancel"]').addEventListener('mouseleave', function(event) { event.target.style.backgroundColor = 'rgb(190, 190, 190)' }, false); dalg.querySelector('input[value="Set default"]').addEventListener('click', function() { dalg.querySelector(`input[name="fmt"][value="${FMT}"]`).checked = true; dalg.querySelector(`input[name="ssl"][value="${SSL}"]`).checked = true; dalg.querySelector('input[name="intl"]').value = INTL; }, false); dalg.querySelector('input[value="Set default"]').addEventListener('mouseenter', function(event) { event.target.style.backgroundColor = 'rgb(170, 170, 170)'; }, false); dalg.querySelector('input[value="Set default"]').addEventListener('mouseleave', function(event) { event.target.style.backgroundColor = 'rgb(190, 190, 190)' }, false); dalg.querySelector('input[value="Save & Close"]').addEventListener('click', async function() { for(let e of dalg.querySelectorAll('input[name="fmt"]')) { if(e.checked) { fmt = +e.value; break; } } for(let e of dalg.querySelectorAll('input[name="ssl"]')) { if(e.checked) { ssl = +e.value; break; } } intl = +dalg.querySelector('input[name="intl"]').value; await GM.setValue('fmt', fmt); await GM.setValue('ssl', ssl); await GM.setValue('intl', intl); dalg.style.display = 'none'; }, false); dalg.querySelector('input[value="Save & Close"]').addEventListener('mouseenter', function(event) { event.target.style.backgroundColor = 'rgb(170, 170, 170)'; }, false); dalg.querySelector('input[value="Save & Close"]').addEventListener('mouseleave', function(event) { event.target.style.backgroundColor = 'rgb(190, 190, 190)' }, false); } async function initgui() { if(await GM.getValue('fmt') === undefined) { await GM.setValue('fmt', FMT); } else { fmt = await GM.getValue('fmt'); } if(await GM.getValue('ssl') === undefined) { await GM.setValue('ssl', SSL); } else { ssl = await GM.getValue('ssl'); } if(await GM.getValue('intl') === undefined) { await GM.setValue('intl', INTL); } else { intl = await GM.getValue('intl'); } dalg = makeDialog(); makeFunc(dalg); document.body.appendChild(dalg); GM.registerMenuCommand('Settings', function() { if(dalg.style.display == 'none') { dalg.querySelector(`input[name="fmt"][value="${fmt}"]`).checked = true; dalg.querySelector(`input[name="ssl"][value="${ssl}"]`).checked = true; dalg.querySelector('input[name="intl"]').value = intl; dalg.style.display = 'block'; } }); } console.log(`${MYNAME}: start.`); fmt = FMT; ssl = SSL; intl = INTL; if(!NOGUI) await initgui(); observer.observe(document.documentElement, {childList:true, subtree:true}); while(1) { if(s_mus) { if(fmt || ssl == 2) await main_track(); if(ssl) await addsl(); s_mus = null; // 初期値がtrue、非同期処理用 } await new Promise(resolve => setTimeout(resolve, intl)); // intl は外から非同期に変更する } })(); /* END */
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址