- // ==UserScript==
- // @name ヤフオクで非表示とメモ
- // @description q:非表示 w:アンドゥ b:NGワード Shift+Q:NG編集 12:メモを追加 34:自由メモ 56:定型文をメモ Shift+!:メモを編集 Shift+":自動メモのみ全削除 Shift+#:メモを一時非表示 Shift+56:定型文を設定 .:上限価格 t:半透明モード
- // @version 0.5.97
- // @match *://auctions.yahoo.co.jp/search/*
- // @match *://page.auctions.yahoo.co.jp/jp/auction/*
- // @match *://auctions.yahoo.co.jp/seller/*
- // @match *://auctions.yahoo.co.jp/category/list/*
- // @match *://cpu.userbenchmark.com/*
- // @match *://webcomics.jp/*
- // @match *://www.amazon.co.jp/*
- // @exclude *://www.amazon.co.jp/*/cart/*
- // @exclude *://www.amazon.co.jp/*/buy/*
- // @exclude *://www.amazon.co.jp/*/huc/*
- // @exclude *://www.amazon.co.jp/*/css/*
- // @exclude *://www.amazon.co.jp/ap/*
- // @exclude *://www.amazon.co.jp/gp/*
- // @exclude *://www.amazon.co.jp/auto-deliveries*
- // @match *://booklive.jp/index/no-charge*3
- // @match *://ebookjapan.yahoo.co.jp/free*
- // @match *://ebookjapan.yahoo.co.jp/ranking/free/*
- // @match *://ebookjapan.yahoo.co.jp/ranking/details/free/*
- // @match *://ebookjapan.yahoo.co.jp/viewer*
- // @match *://sokuyomi.jp/*
- // @match *://csbs.shogakukan.co.jp/free*
- // @match *://www.rtings.com/*/tools/table*
- // @match *://www.rtings.com/*/reviews/*
- // @match *://www.nicovideo.jp/search/*
- // @match *://www.nicovideo.jp/tag/*
- // @match *://www.nicovideo.jp/user/*
- // @match *://www.nicovideo.jp/series/*
- // @match *://www.nicovideo.jp/my/*
- // @match *://www.nicovideo.jp/ranking*
- // @match *://www.nicovideo.jp/watch/*
- // @match *://*.5ch.net/*
- // @match *://www.ebay.com/sch/*
- // @match *://www.ebay.com/itm/*
- // @match *://jmty.jp/*
- // @match *://gf.qytechs.cn/*/scripts*
- // @match *://*.aliexpress.com/af/*
- // @match *://*.aliexpress.com/item/*
- // @match *://*.aliexpress.com/wholesale*
- // @match *://www.cmoa.jp/freecontents*
- // @match *://piccoma.com/*
- // @match *://www.mangaz.com/*
- // @match *://www.sukima.me/*
- // @match *://*.userbenchmark.com/*
- // @match *://www.hellowork.mhlw.go.jp/kensaku/*
- // @match *://kakaku.com/*
- // @match *://seiga.nicovideo.jp/*
- // @match *://tsugimanga.jp/*
- // @match *://www.yodobashi.com/*
- // @match *://www.youtube.com/*
- // @match *://*.iherb.com/*
- // @match *://www.suruga-ya.jp/*
- // @match *://twitter.com/*
- // @match *://www.nicovideo.me/*
- // @match *://www.nicochart.jp/*
- // @match *://pubmed.ncbi.nlm.nih.gov/?term=*
- // @match *://pubmed.ncbi.nlm.nih.gov/?linkname=*
- // @match *://pubmed.ncbi.nlm.nih.gov/*
- // @match *://a-timesale.com/*
- // @match *://rrws.info/*
- // @match *://commons.nicovideo.jp/*
- // @match *://scholar.google.tld/*
- // @match *://hibiki-radio.jp/*
- // @match *://www.onsen.ag/
- // @match *://www.freem.ne.jp/*
- // @match *://shopping.yahoo.co.jp/search*
- // @match *://360life.shinyusha.co.jp/*
- // @match *://omocoro.jp/*
- // @match *://minsoku.net/*
- // @match https://refind2ch.org/search*
- // @match *://chiebukuro.yahoo.co.jp/*
- // @match *://www.msdmanuals.com/*
- // @match *://ff5ch.syoboi.jp/?q=*
- // @match *://todo-ran.com/*
- // @match *://booth.pm/*
- // @match *://sakura-checker.jp/category/*
- // @match https://chrome.google.com/webstore/search/*
- // @match https://chrome.google.com/webstore/detail/*
- // @match *://twicomi.com/*
- // @match *://twiman.net/*
- // @match *://free.arinco.org/*
- // @match *://workman.jp/shop/*
- // @match *://www.uniqlo.com/*
- // @match *://*.shitaraba.net/bbs/read.cgi/*
- // @match *://*.shitaraba.net/bbs/read_archive.cgi/*
- // @match *://*.ftbucket.info/*
- // @match *://kuzure.but.jp/*
- // @match *://*.2chan.net/*
- // @match *://anige.horigiri.net/*
- // @match *://futapo.futakuro.com/*
- // @match *://kako.futakuro.com/futa/*
- // @match https://kakaku.com/pc/note-pc/itemlist.aspx
- // @match https://kakaku.com/pc/desktop-pc/itemlist.aspx
- // @match *://btopc-minikan.com/*
- // @match *://pcfreebook.com/*
- // @match *://search.bilibili.com/*
- // @match *://www.mcdonalds.co.jp/menu/*
- // @match *://*.2chan.net/b/futaba.php*
- // @match *://nitter.cz/*
- // @match *://nitter.net/*
- // @match *://www.uexpress.com/*
- // @match https://find.5ch.net/search
- // @match https://tsumanne.net/*/data/*
- // @match *://zzzsearch.com/*
- // @match *://review.kakaku.com/review/*
- // @match *://www.netoff.co.jp/*
- // @match *://jp.daisonet.com/*
- // @noframes
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_deleteValue
- // @grant GM_addStyle
- // @grant GM.addStyle
- // @grant GM.setClipboard
- // @grant GM.openInTab
- // @run-at document-idle
- // @namespace https://gf.qytechs.cn/users/181558
- // @require https://code.jquery.com/jquery-3.7.1.min.js
- // @require https://code.jquery.com/ui/1.13.2/jquery-ui.min.js
- // ==/UserScript==
-
- (function() {
- const FUTAPO_CRAM_TITLE = 1; // 1:futapoでboxの横幅が狭いときでもタイトルを詰め込む
- const FUTAPO_89_NOTIFY = "notify"; // futapoで8/9登録がヒットした時にどう通知するか "notify"でnotification API(推奨)、"sound"で効果音。"notify sound"で両方、""で通知しない
- const FUTABA_SET_56MEMO_TO_ANCHORED = 3; // 1:ふたばで監視ワードヒットレスと自分のレスに自動的に5メモを付ける 2:1に加え5メモへのレスに6メモを付ける 3:1+2に加え遠くても5メモに連鎖するレスには6メモをつける(推奨) 4:1+2+3に加え遠くても6メモに連鎖するレスにも6メモをつける
- const FUTABA_NOTIFY_NEWRES_SOUND_MEMO_QUOTED = "5 6 m"; // ふたばで新着レスのNotification通知でメモのついたレスが引用された時に音で知らせるか "5"で○メモに鳴らす、"6"で×メモに鳴らす、"m"で監視ワードに鳴らす、""で鳴らさない、"5 6 m"などで複数設定可能
- const FUTABA_Z_TO_COPY_TO_CLIPBOARD_AS_TEXT_TOO = "${num1} ${name1} ${name2} ${time} ${num2} ${soudane}\n${text}\n"; // ふたばでzキーかレス右上の□のクリック時についでに内容をテキストとしてクリップボードにコピーする、その書式 "":コピーしない
- const FUTABA_FLOAT_RELOAD_BUTTON = 1; // 1:ふたばでリロードボタンを浮遊させる
- const FUTABA_HOVER_POPUP_REPLACE = 1; // 1:ふたばで>引用ポップアップを置き換える
- const FUTABA_HOVER_POPUP_DELAY = 1; // ふたばで>引用の上に静止してn/60秒間後にポップアップを表示する -1:瞬間&低負荷(mousemove) 1:瞬間(interval) 2~:n/60秒(interval) 0:無効
- const FUTABA_REPLACE_RES0 = 1; // 1:ふたばでスレ本文をレス番号0のように置き換える 引用ポップアップ等が働くために必要
- const FUTABA_QUOTE_LEAD_FOR_NUMBER_ONLY = 1; // 1:ふたばで>no.○○や>○○.jpgや>fu○○.jpgといった引用にも本文のバルーン引用を追加する(要「5chサムネイル表示他」併用)
- const FUTABA_EXPERIMENTAL_DISPLAY_CHAINED = 1; // 1:ふたばでレス右上の□に引用連鎖数を書き入れていく ※現状重い処理
- const FUTABA_AUTO_RELOAD_INTERVAL = 1; // 1-10:ふたばでnキーオン時の自動リロードする最短間隔(分) ※新着がなく無操作だと自動的に10分まで伸びる
- const FUTABA_ALTZ_FILENAME_SUFFIX = "●"; // ふたばでAlt+Z時にファイル名の末尾に付ける文字
- const FUTABA_PLAY_GIF_INLINE = 0; // 1:ふたばのgifをインラインで動かす
- const FUTABA_POPUP_PADDING_RATE = 169; // ふたばの引用ポップアップの額縁の太さ(大きいほど細い)
- const FUTABA_REMOVE_REDIRECT_PAGE = 1; // 1:ふたばでリンクからクッションページを省略
-
- const IN5CH_REMOVE_AKABAN = 1; // 1:5chで垢版ボタンをとりあえず隠す 0:そのまま
- const dniCancel = 1; // DNIがobserve(ms)以上連続して発火しても途切れるのを待ち続ける
- const FUTABA_DEBUG = 0; // 1-2:ふたばで開発用情報を表示 1:最下行ログ 2:1+タブタイトル
- const DEBUG_CATCH = 0; // 1:catchしたエラーをalert
- const KEYCHANGE_DEBUG = "disable"; // 押す度にdebugを0~3に切り替えるキー "Shift+D","disable"等
- const ENABLE_HELP = 1; // 1:操作ガイドを表示 0:無効
- const ENABLE_AUTOMEMO = 7; // 0:自動メモを無効 1でオン 2~7:大きくするほど一時的に表示が崩れる代わりに確実
- const REPLACE_LINK_IN_YOUTUBE = 1; // 1:YouTubeで投稿者のチャンネルのホームタブへのリンクをチャンネルの動画タブへのリンクに置き換える
- const ENABLE_EXCEPT_YAJ = 1; // 1:ヤフオク以外でも有効 0:ヤフオクでのみ動作
- var debug = 0; // 1~だとデバッグモード V&&dc(text) 1:非対応ページでその旨表示など/コンソールにverbose表示 2:verboseをポップアップ(速度測定して表示 debug&&sw("項目"))&非表示にした原因に枠追加 3:Q/1/2等の対象要素を目立たせる
- const ENABLE_MEASURE_TIME_SPENT = 0; // 1で速度測定して表示 debug&&sw("項目")
-
- const fasttest = 1; // 1:高速モードを試用
- const FUTABA_BGC = 0 ? "#f0e0d6" : "#ffffee"
-
- const ISCHROME = window.navigator.userAgent.toLowerCase().indexOf('chrome') != -1
- var futabapopupscale;
- const futabapicksizeDefault = 84
- var futabapicksizeL = futabapicksizeDefault;
- var futabapicksize = 100;
- var hovertimer = 0;
- var swb = new Date();
- var prefCache = []
-
- GM_addStyle("span.yhmMyMemo{all:initial; word-wrap:break-word;cursor:pointer; font-size:14px; font-weight:bold; margin:0px 1px; text-align:center; padding:0px 6px 0px 6px; border-radius:12px; color:white;font-family:sans-serif;}")
- debug && sw("reset")
-
- String.prototype.match0 = function(re) { let tmp = this.match(re); if (!tmp) { return null } else if (tmp.length > 1) { return tmp[1] } else return tmp[0] } // gフラグ不可
- String.prototype.match1 = function(re) { return this?.match(re)?.slice(1)?.find(v => v) } // this./a(bc)|d(ef)/ 等の()でキャプチャした最初の1つを返す gフラグ不可
- //String.prototype.nfd = function() { return SITE.nfd ? this?.normalize("NFD") : String(this) } // 文字列をNFDエンコードにまとめる
- String.prototype.sanit = function() { return this.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/`/g, '`') }
-
- function adja(place = document.body, pos, html) {
- return place ? (place.insertAdjacentHTML(pos, html), place) : null;
- }
- let addstyle = {
- added: new Set(),
- add: function(str) {
- if (this.added.has(str)) return;
- end(document.head, `<style>${str}</style>`);
- this.added.add(str);
- },
- }
-
- var SITE = {}
- let inYOUTUBE = location.hostname.match0(/^www\.youtube\.com|^youtu\.be/);
-
- $.fn.animate2 = function(properties, duration, ease) {
- ease = ease || 'ease';
- var $this = this;
- var cssOrig = { transition: $this.css('transition') };
- return $this.queue(next => {
- properties['transition'] = 'all ' + duration + 'ms ' + ease;
- $this.css(properties);
- setTimeout(function() {
- $this.css(cssOrig);
- next();
- }, duration);
- });
- };
-
- if (window != parent) return;
- const WAIT = performance.now(); // ページ開始後のウエイト用 delayAutoWeightingをかける
- /* const COLOR1 = "#6080ff",
- COLOR2 = "#c03020",
- COLOR3 = "#808080",
- COLOR5 = "#6080ff",
- COLOR6 = "#c03020",
- COLORVIDEOTIME = "#204020",
- COLORCPUSCORE = "#a08000",
- */
- const OLD_COLOR1 = "#6080ff",
- OLD_COLOR2 = "#c03020",
- OLD_COLOR3 = "#808080",
- OLD_COLOR5 = "#6080ff",
- OLD_COLOR6 = "#c03020",
- OLD_COLORVIDEOTIME = "#204020",
- OLD_COLORCPUSCORE = "#a08000",
- COLOR1 = "#57f", //"#6080ff",
- COLOR2 = "#c32", //"#c03020",
- COLOR3 = "#888", //"#808080",
- COLOR5 = "#57f", //"#6080ff",
- COLOR6 = "#c32", //"#c03020",
- COLORVIDEOTIME = "#242", //"#204020",
- COLORCPUSCORE = "#970", //"#a08000",
- COLOR_ALERT_WORD = "#882", //"#a08000",
- KEYHIDE = "q",
- KEYUNDO = "w",
- KEYBW = "b",
- KEYEDIT = "Shift+Q",
- // KEYEDIT2 = "Shift+B",
- KEYMAXP = ".",
- KEYMEMO1 = "1",
- KEYMEMO2 = "2",
- KEYMEMO1S = "3",
- KEYMEMO2S = "4",
- KEYMEMO5 = "5",
- KEYMEMO6 = "6",
- KEYMEMO5EDIT = "Shift+%",
- KEYMEMO6EDIT = "Shift+&",
- KEYTOGGLEtranslucent = "t",
- KEYRESETMEMO = "Shift+!",
- KEYRESETMEMOAUTO = "Shift+\"";
- var MEMO5WORD = "", // 5キーの定型文初期値 ""なら現在年月日
- MEMO6WORD = ""; // 6キーの定型文初期値 ""なら現在年月日
-
- var pauseAll = 0;
- let kaisuuU = 0;
- var GF = {}
- GF.yhmSortType = 0
- GF.isNico = location.host == "www.nicovideo.jp"
- var memofast = false;
-
- // 上が優先
- const SITEINFO = [{
- id: "DAISONET",
- urlRE: '//jp.daisonet.com/',
- title: 'h1.product-meta__title.heading.h1.text--strong , a.product-item__title',
- box: 'div.product-block-list , div.product-item--vertical',
- forceTranslucentFunc: e => lh('daisonet.com/products/'),
- redoWhenRefocused: 1,
- }, {
- id: `NETOFF`,
- urlRE: '//www.netoff.co.jp/',
- box: 'li.clearfix',
- title: 'p > a.fw',
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- var sorttype = GF.yhmSortType || 0
- let menu = [
- { t: "安い→新しい", f: () => { sortdom(elegeta('li.clearfix'), v => +eleget0('.price', v)?.textContent?.replace(/,/g, "")?.match0(/\d+/) * 1000000000 + (1000000 - +(eleget0('.subinfo', v)?.textContent?.replace(/(\d+).(\d+).*/, "$1$2")))) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- }
- }]
- }, {
- id: 'KAKAKU',
- urlRE: 'https://review.kakaku.com/review/',
- title: 'h2[itemprop="name"]',
- box: 'div#main',
- forceTranslucentFunc: e => 1,
- memoFunc: e => e?.parentNode?.parentNode,
- }, {
- id: 'zzzsearch.com',
- urlRE: '//zzzsearch.com/',
- title: '//div[@class="gs-title"]/a[@dir="ltr"]',
- box: 'div.gsc-webResult.gsc-result',
- observe: 333,
- keyFunc: [{
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- // func: () => { searchWithHistory("find5ch", "find5ch", ['https://find.5ch.net/search?q=***',`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`], " OR ") },
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- // func: () => { searchWithHistory("REFIND2CH", "re.Find2ch", 'https://refind2ch.org/search?q=***&sort=rate', " OR ") },
- }],
- }, {
- id: 'uexpress',
- urlRE: /\/\/www\.uexpress\.com\//,
- keyFunc: [{
- key: 'Shift+F', // Shift+F::キーワード検索
- func: () => { searchWithHistory("uexpress", "UExpress", 'https://www.google.co.jp/search?q=***%20site:www.uexpress.com/life/miss-manners', "|") },
- }],
- }, {
- id: 'nitter',
- urlRE: /\/\/nitter\.cz\/|\/\/nitter.\.net\//,
- title: '.username',
- box: '.timeline-item',
- observe: 500,
- }, {
- id: 'futaba_catalog',
- urlRE: /https?:\/\/[^\.]+\.2chan\.net\/[^/]+\/futaba\.php\?mode=cat/,
- title: '.tdDiv small',
- box: '#cattable tbody tr td',
- isHidePartialMatch: 1,
- titleSubstr: true,
- hideSelectedWord: 1,
- disableKeyB: 0,
- listTitleXPIgnoreNotExist: 1,
- funcOnlyFirst: () => {
-
- $('#cattable td').wrapInner('<div class="tdDiv"></div>')
-
- // レス数とvボタンを下の帯に固定
- elegeta('.pdmc').forEach(e => e.closest('td')?.appendChild(e))
- addstyle.add(`.pdmc { margin-top:auto; margin-bottom:auto; right: 0em; bottom:0.2em; position:absolute; z-index:99; opacity:1; padding:0.15em; background-color:#ffffee; }`)
- GF.imgw = Math.max(eleget0('#cattable img')?.offsetWidth, eleget0('#cattable img')?.offsetHeight) || 40
- GF.boxw = eleget0('#cattable td')?.offsetWidth || 40
-
- setSlider(eleget0('//body/span[1]'), 0, 320, 0, "画像サイズ:***px", "futaba_catalog_imagesize", (val) => {
- eleget0('#imagesizecss')?.remove()
- $("#boxs").remove();
- GF.imgw = val
- if (val) end(document.head, `<style id="imagesizecss" data-val="${val}">#cattable img{max-width:${val}px; width:auto; height:auto; max-height:${val}px; }</style>`)
- if (val) { end(document.head, `<style id="boxs">${GF.boxw<2*GF.imgw?"#cattable img{display:block; height:auto !important; max-width:100% !important; margin-bottom:5px; margin-right:auto; margin-left:auto;}":"#cattable img{float:left; margin-bottom:5px; margin-right:5px;}"}</style>`) }
-
- }, 0, '')
- setSlider(eleget0('#setSliderfutaba_catalog_imagesize'), 0, 300, 0, "box高さ:***px", "futaba_catalog_boxheight", (val) => {
- eleget0('#futaba_catalog_imagesize')?.remove()
- if (val) end(document.head, `<style id="boxheightcss">#cattable td{height:calc(${val - 2}px - 0.5em); } #cattable tbody{display:grid !important;} #cattable tr,#cattable td{ display:inline-block; overflow:hidden; min-height:${val - 2}px !important; max-height:${val - 2}px !important; height:${val - 2}px !important;}</style>`) // レス数とvボタンを下の帯に固定
- if (val) addstyle.add(`#cattable img{border:black solid 1px;}`); //$("#cattable img").wrap('<div class="imgDiv"></div>') eleget0('#futaba_catalog_imagesize')?.remove()
-
- }, 0, '')
- setSlider(eleget0('#setSliderfutaba_catalog_imagesize'), 0, 300, 0, "box横幅:***px", "futaba_catalog_boxwidth", (val) => {
- eleget0('#boxwidthcss')?.remove()
- $("#boxs").remove();
- $('#cattable td a+br').remove()
- GF.boxw = val - 5
- if (val) end(document.head, `<style id="boxwidthcss">.tdDiv{margin:5px;} #cattable small{line-break: anywhere; } #cattable td{vertical-align:top; word-break:break-all; width:${1+val}px !important;}</style>`)
- if (val) { end(document.head, `<style id="boxs">${GF.boxw<2*GF.imgw?"#cattable img{display:block; height:auto !important; max-width:100% !important; margin-bottom:5px; margin-right:auto; margin-left:auto;}":"#cattable img{float:left; margin-bottom:5px; margin-right:5px;}"}</style>`) }
-
- }, 0, '')
- setSlider(eleget0('#setSliderfutaba_catalog_imagesize'), 0, 24 * 3, 0, "文字サイズ:***/3px", "futaba_catalog_fontsize", (val) => {
- eleget0('#textsizecss')?.remove()
- if (val) end(document.head, `<style id="textsizecss">#cattable small{font-size:${val/3}px; }</style>`)
- }, 0, '')
- },
- }, {
- id: 'search.bilibili.com',
- urlRE: '//search.bilibili.com/',
- listTitleXP: '//h3[@class="bili-video-card__info--tit"]',
- listTitleSearchXP: '//h3[@class="bili-video-card__info--tit"][**title**]/ancestor::div[contains(@class,"video-list-item")]',
- listTitleMemoSearchXP: '//h3[@class="bili-video-card__info--tit"][**title**]',
- listGen: 7,
- observe: 999,
- useText: 1,
- }, {
- id: 'mcdonaldsmenu',
- urlRE: '//www.mcdonalds.co.jp/menu/',
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- var sorttype = GF.yhmSortType || 0
- let menu = [
- { t: "安い順", f: () => { sortdom(elegeta('//span[@class="product-list-card-price-number text-2xl font-extrabold"]/../../..'), v => eleget0('//span[@class="product-list-card-price-number text-2xl font-extrabold"]', v)?.textContent) } },
- { t: "高い順", f: () => { sortdom(elegeta('//span[@class="product-list-card-price-number text-2xl font-extrabold"]/../../..'), v => eleget0('//span[@class="product-list-card-price-number text-2xl font-extrabold"]', v)?.textContent, 1) } },
- { t: "タイトル", f: () => { sortdom(elegeta('//span[@class="product-list-card-price-number text-2xl font-extrabold"]/../../..'), v => eleget0('.product-list-card-name', v)?.textContent) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- }],
- func: () => popup3("A:ソート", 5),
- }, {
- id: 'pcfreebook.com',
- urlRE: '//pcfreebook.com/',
- listTitleXP: '//td[1]/a[@target="_blank" and @rel="noopener nofollow noreferrer"]',
- listTitleSearchXP: '//td[1]/a[@target="_blank" and @rel="noopener nofollow noreferrer"][+++]/ancestor::tr',
- listTitleMemoSearchXP: '//td[1]/a[@target="_blank" and @rel="noopener nofollow noreferrer"][+++]',
- listGen: 3,
- listTitleMemoSearchXPSameGen: 1,
- listTitleXPIgnoreNotExist: 1,
- observe: 2500,
- }, {
- id: 'btopc-minikan.com',
- urlRE: '//btopc-minikan.com/',
- titleProcessFunc: (title) => { return title.replace(/\n|\s/gmi, " ").trim() },
- listTitleXP: '//span[@class="itemname"]',
- listTitleSearchXP: '//span[@class="itemname"][++title++]/ancestor::tr',
- listTitleMemoSearchXP: '//span[@class="itemname"][++title++]',
- listTitleMemoSearchXPSameGen: 1,
- useTitle: 1,
- listGen: 4,
- func: () => {
- elegeta('//td[1]/div[@class="notranslate"]|.//td[@class="CPUgrease-GraphCell-Maker"]').forEach(e => e.insertAdjacentHTML("beforeend", `<span class="itemname" title="${e.textContent.replace(/\n|\s/gmi," ").trim()}"> </span>`))
- },
- listTitleXPIgnoreNotExist: 1,
- observe: 2500,
- }, {
- urlRE: /^https:\/\/kakaku.com\/pc\/note-pc\/itemlist\.aspx|https:\/\/kakaku\.com\/pc\/desktop-pc\/itemlist.aspx|\/\/kakaku.com\/pc\/gaming-pc\/itemlist.aspx|\/\/kakaku.com\/pc\/gaming-note\/itemlist.aspx|\/\/kakaku.com\/pc\/stick-pc\/itemlist.aspx/,
- WhateverFirstAndEveryAPFunc: () => {
- if (!elegeta('//th[@class="sub thHeader" and contains(text(),"CPUスコア(PassMark) ")]')[0]) return;
- popup3("A:CPUスコア単価で絞り込み", 4)
- //$(".cps").remove()
- // let arr = lh("gaming") ? elegeta('//table/tbody/tr[@class="tr-border"]/td[11]') : elegeta('//table/tbody/tr[@class="tr-border"]/td[10]')
- let arr = lh("gaming") ? elegeta('table tbody tr.tr-border td:nth-child(11):not([data-scorecost])') : elegeta('table tbody tr.tr-border td:nth-child(10):not([data-scorecost])')
- arr.forEach(e => {
- e.dataset.scorecost = 1
- // let p = elegeta('//td[2]/ul/li[@class="pryen"]/a', e?.closest("tr"))[0]
- let p = elegeta('td:nth-child(2) ul li.pryen a', e?.closest("tr"))[0]
- let b = e.parentNode
- let cpu = parseInt(e.innerText.replace(/\D/g, ""))
- let price = parseInt(p.innerText.replace(/\D/g, ""))
- if (e.textContent.match(/\d/)) {
- e.insertAdjacentHTML("beforeend", `<div title="Aキーでこの上限で絞り込み" class="cps" style="color:#F00;" >価格/スコア<br><span class="cputanka">${((price/cpu).toFixed(2))}</span></div>`)
- } else {
- end(e, '<span class="cputanka"></span>')
- }
- })
- },
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- if (!elegeta('//th[@class="sub thHeader" and contains(text(),"CPUスコア(PassMark) ")]')[0]) return;
- GF.base = proInput("CPUスコア単価上限を入力してください", $('#CPS').data("cps") || 10) || 0;
- autoPagerizedD("cpsAP", () => {
- $('#CPS').remove();
- $(document.body).append(`<span id="CPS" data-cps="${GF.base}" style="background-color:#"></span>`)
- $(elegeta('table tbody tr.tr-border')).show()
- if (GF.base <= 0) return
- elegeta('.cputanka').forEach(e => {
- let cps = Number(e?.innerText || 0)
- let b = e.closest("tr.tr-border")
- if (!cps || cps > GF.base) {
- $([b, b.previousSibling, b.previousSibling.previousSibling]).hide()
- }
- })
- })
- }
- }, ],
- }, {
- urlRE: /\/\/www.ftbucket.info\/scrapshot\/ftb\/index\.php|\/\/www.ftbucket.info\/scrapshot\/ftb\/?$|\/\/www.ftbucket.info\/scrapshot\/ftb\/\?favo=/,
- id: 'FUTACHAN_CATALOG',
- listTitleXP: '//div[@class="tdDiv"]/span/div',
- listTitleSearchXP: '//div[@class="tdDiv"]/span/div[***]/../..',
- listTitleMemoSearchXP: '//td/div[@class="tdDiv"]/span/div[***]',
- listGen: 5,
- listTitleXPIgnoreNotExist: 1,
- listGen: 4,
- WhateverFirstAndEveryAPFunc: () => {
- popup3("Shift+F:FTBucket検索", 8, 5000)
- },
- // WhateverFirstAndEveryAPFunc: () => { SITEINFO[SITEINFO.findIndex(c => c.id == "FUTACHAN")].WhateverFirstAndEveryAPFunc() },
- keyFunc: [{
- key: 'Shift+F', // Shift+F::FTBucketでキーワード検索
- func: () => { searchWithHistory("FUTACHAN", "FTBucket", 'https://www.ftbucket.info/scrapshot/ftb/index.php?mode=c&favo=0&ord=1&s=***', "|") },
- // func: () => { SITEINFO[SITEINFO.findIndex(c => c.id == "FUTACHAN")].keyFunc[0].func() },
- }],
- // memoStyle:'display:inline-block;',
- //listTitleMemoSearchXPSameGen: 1,
- delay: 333,
- funcOnlyFirst: () => {
- //if (!lh("mode=c")) return;
-
- eleget0('//html/body/table[2]')?.setAttribute("id", "cattable")
- $('#cattable td').wrapInner('<div class="tdDiv"></div>')
- begin(document.body, `<div id="slidersP" style="position:fixed;z-index:999; top:1em; right:1em;"><div id="sliders1"></div><br><div id="sliders2"></div><br><div id="sliders3"></div><br><div id="sliders4"></div><br></div>`)
- $('#cattable td>a>img').css({ "border": "black solid 1px" }).wrap('<div class="imgDiv"></div>')
- // $('#cattable td').wrapInner('<div class="tdDiv"></div>')
-
- setSlider(eleget0('#sliders4'), 0, 300, 0, "box高さ:***px", "futabucket_catalog_boxheight", (val) => {
- eleget0('#boxheightcss')?.remove()
- if (val) end(document.head, `<style id="boxheightcss">#cattable tbody tr td{height:calc(${val - 2}px - 0.5em); } tbody{display:grid !important;} #cattable tbody tr { display:inline-block; overflow:hidden; margin:0 auto; min-height:${val - 2}px !important; max-height:${val - 2}px !important; height:${val - 2}px !important;}</style>`)
- }, 0, '')
-
- setSlider(eleget0('#sliders3'), 0, 500, 0, "box横幅:***px", "futabucket_catalog_boxwidth", (val) => {
- eleget0('#boxwidthcss')?.remove()
- $('#cattable td a+br').remove()
- if (val) end(document.head, `<style id="boxwidthcss">.tdDiv{margin:5px;} #cattable tbody tr td{line-break: anywhere; } #cattable tbody tr td img{float:left; margin-bottom:5px; margin-right:5px;} #cattable tbody tr td{vertical-align:top; word-break:break-all; width:${1+val}px !important; max-width:${1+val}px !important;}</style>`)
- if (val) elegeta('td div span[title] div').forEach(e => e.textContent = e.parentNode.title)
- }, 0, '')
-
- //setSlider(eleget0('#sliders'), 1, 24 * 3, 12 * 3, "文字サイズ:***/3px", "futabucket_catalog_fontsize", (val) => {
- // eleget0('#textsizecss')?.remove()
- // end(document.head, `<style id="textsizecss">#cattable div{font-size:${val/3}px !important; }</style>`)
- //}, 0, '')
-
- setSlider(eleget0('#sliders2'), 0, 320, 0, "画像サイズ:***px", "futabucket_catalog_imagesize", (val) => {
- eleget0('#imagesizecss')?.remove()
- if (val) end(document.head, `<style id="imagesizecss">#cattable img{ object-fit: cover !important; max-width:${val}px !important; width:auto !important; height:auto !important; max-height:${val}px !important; }</style>`)
- }, 0, '')
-
- setSlider(eleget0('#sliders1'), 0, 20, 0, "タイトル行数:***行", "futabucket_catalog_titlerow", (val) => {
- eleget0('#catalogrowscss')?.remove()
- if (val) end(document.head, `<style id="catalogrowscss">#cattable .tdDiv span div{ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${val} !important;; overflow: hidden; }</style>`)
- if (val) elegeta('td div span[title] div').forEach(e => e.textContent = e.parentNode.title)
- }, 0, '')
-
- /*elegeta('//div/input[@type="search" and @id="searchword"]').forEach(e => e.style.width = "calc(100% - 4em)") // 検索フォームを大きく
- if (location.href.match0("//www.ftbucket.info/scrapshot/ftb/")) {
- setSlider(eleget0('//html/body/div[2]/a/img/..'), 4, 255, 16, "タイトル表示:***文字", "FTBTitleLength", (val) => elegeta('//td/span[@title]/div').forEach(e => e.textContent = e.parentNode.title.substr(0, val)))
- setSlider(eleget0('//html/body/div[2]/a/img/..'), 4, 30, 8, "セル幅:***em", "FTBcallWidth", (val) => elegeta('//td/span[@title]/div/../..').forEach(e => e.style.width = `${val}em`))
- }*/
- },
- }, {
- urlRE: "\/\/futapo.futakuro.com", // futapo::
- id: 'FUTACHAN_CATALOG',
- listTitleXP: '//div[@class="thread-text"]',
- listTitleSearchXP: '//div[@class="thread-text"][***]/../..|.//span[@class="emph"][***]/../../..',
- listTitleMemoSearchXP: '//div[@class="thread-text"][***]|.//span[@class="emph"][***]/..',
- listGen: 5,
- Bsyntax2: 1,
- memoStyle: 'word-break:break-all; font-size:10px !important; line-height:130%; padding:0px 4px 0px 4px; line-break:anywhere;',
- preventMemo: m => ["★", "◎", "○"].includes(m),
- QRule: "\n\n非表示化に関しては正規表現は使えませんが\nこのサイトではここで登録した内容で8/9メモの追加動作の抑制ができ、\nその抑制に関してだけは正規表現が使え、全角/半角、大文字/小文字も区別しません\n",
- listTitleXPIgnoreNotExist: 1,
- observe: 666,
- observeClass: ["box", "box ", "yhmMyMemo"], //2022年07月12日
- WhateverFirstAndEveryAPFunc: () => {
- popup3("Shift+F:FTBucket検索\n7:左上優先配置タイトルを設定\n8:左上優先配置(+通知)タイトルを設定\n9:左上優先配置(+開く)タイトルを設定\nShift+789:独自構文使用版789\n0:789メモ一括削除画面\nE:更新 D:下まで読み込む\nG:画像でNG H:画像でピックアップ", 8, 5000) // ↻
- },
- listTitleMemoSearchXPSameGen: 1,
- funcOnlyFirst: () => {
- GF.latestReload = Date.now() - 3000
- GF.FUTAPO_AUTO_RELOAD_DEFAULT = pref("FUTAPO_AUTO_RELOAD_DEFAULT") || 0;
- GM_addStyle('.graybutton{ cursor:pointer; position: fixed; z-index:100; opacity:1; font-size:12px; margin:0px 1px; padding:1px 6px 1px 6px; word-break: break-all !important; border-radius:12px; border:solid 1px #888; background-color:#fff; color:#888;}')
- GM_addStyle('.popuptext,.popuptext-back{z-index:1000000000000;}')
- GM_addStyle(".boxpri1{animation: pulse1 5s 1; } @keyframes pulse1 { 0% { outline:5px solid #0000ffff; } 40% { outline:5px solid #0000ffff; } 100% { outline:5px solid #0000ff00; } }")
- document.querySelector(`head`).insertAdjacentHTML('beforeend', `<style>.waiting{ display: inline-block; vertical-align: middle; color: #666; line-height: 1; width: 1em; height: 1em; border: 0.12em solid currentColor; border-top-color: rgba(102, 102, 102, 0.3); border-radius: 50%; box-sizing: border-box; -webkit-animation: rotate 1s linear infinite; animation: rotate 1s linear infinite; } @-webkit-keyframes rotate { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } } @keyframes rotate { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }</style>`)
-
- if (FUTAPO_CRAM_TITLE) GM_addStyle("div.thread-contents { padding-left: 0px !important;} div.thumbnailContainer { min-width:3em; position:inherit !important; margin-left: 0px !important;}") // boxの横幅が狭いときでもタイトルを詰め込む
-
- // フィルタフォームでEscで削除して抜ける
- document.addEventListener("keydown", e => {
- if (document.activeElement.matches("input#cat_text_search") && e.key == "Escape" && !e.isComposing) {
- $("input#cat_text_search").val("").blur()
- }
- }, true)
-
- var lastope = Date.now()
- var cdID
- //if (eleget0('#reload') && !cdID) {
- function waitAndDo(checkFunc, func) { // checkFuncがtrueになったらfuncを実行
- if (!checkFunc()) setTimeout(waitAndDo, 500, checkFunc, func);
- else func();
- }
- waitAndDo(() => eleget0('#reload'), () => {
- document.body.insertAdjacentHTML("beforeend", `<tt id="cdsw" class="graybutton" style="cursor:pointer;left:1em; bottom:2em; position:fixed;" title="左クリックで無操作時60秒毎に自動更新開始\nもう一度左クリックで停止">⏻無操作<br>自動更新</tt>`)
-
- $(document).on("mousedown", `#cdsw`, (e) => {
- if (e?.button != 0) return;
- cdon()
- })
-
- function cdon() {
- pref("FUTAPO_AUTO_RELOAD_DEFAULT", 1)
- $('#cdsw').fadeOut(222);
- var lastope = Date.now()
- $(document).on("mousemove mousedown keydown", () => { lastope = Date.now() })
-
- clearInterval(GF?.cdID);
- GF.cdID = setInterval(() => {
- $('#cd,#cdsw').remove();
- document.body.insertAdjacentHTML("beforeend", `<tt id="cd" class="graybutton" style="left:1em; bottom:2em; opacity:0.9; ">${Math.max(0,~~(60.9-(Date.now()-lastope)/1000))}</tt>`) //⏽
- if (Date.now() - lastope > 60 * 1000 && !eleget0('.blinkingOL')) { // 開き待ちのが1つでもあれば押さない
- lastope = Date.now();
- eleget0('//li[1]/a[@id="reload"]')?.click()
- }
- }, 333)
- }
-
- $(document).on("mousedown", `#cd`, (e) => {
- if (e?.button != 0) return;
- cdoff()
- })
-
- function cdoff() {
- pref("FUTAPO_AUTO_RELOAD_DEFAULT", "")
- clearInterval(GF?.cdID);
- $('#cd,#cdsw').remove() //text("停止")//.hide(999);
- document.body.insertAdjacentHTML("beforeend", `<tt id="cdsw" class="graybutton" style="cursor:pointer;left:1em; bottom:2em; position:fixed;" title="左クリックで無操作時60秒毎に自動更新開始\nもう一度左クリックで停止\n\n9:${GF?.opened2?.size||0}\n8:${GF?.opened1?.size||0}\n7:${GF?.opened?.size||0}\n">⏻無操作<br>自動更新</tt>`)
- }
-
- if (GF.FUTAPO_AUTO_RELOAD_DEFAULT >= 1) cdon() //$("#cdsw").click()
- if (GF.FUTAPO_AUTO_RELOAD_DEFAULT >= 2) scr(0)
- })
- setTimeout(() => {
-
- function scr(i) {
- let last = eleget0('#kako-search')
- window.scroll({ left: 0, top: last ? 0 : 99999, behavior: i % 2 == 1 ? "instant" : "smooth" })
- if (!last && i < 99) setTimeout(() => { scr(++i) }, 100)
- }
- // setTimeout(() => {
- elegeta("#reload,#logo,#cdsw").forEach(e => e.title = e?.title + "\nE:更新\nD/右クリック:更新+下まで読み込み") // ↻
- $(document).on("contextmenu", '#reload,#logo,#cdsw,#cd', () => { // d::
- let r = eleget0('//a[@id="reload"]');
- if (r) {
- if (!GF.latestReload || new Date().getTime() - GF.latestReload > 5000) {
- r.click();
- scr(0)
- GF.latestReload = new Date().getTime();
- } // 要5秒インターバル
- }
- return false
- })
-
- $('a#server.pulldown').attr("title", ($("a#server.pulldown").attr("title") || "") + "\n右クリック:may←→img") // ↻
- $('a#server.pulldown').on("contextmenu", () => {
- let url = location.href == 'https://futapo.futakuro.com/?server=img_b' ? 'https://futapo.futakuro.com/?server=may_b' : 'https://futapo.futakuro.com/?server=img_b'
- location.href = url;
- return false
- })
- $('a#mode.pulldown').on("contextmenu", () => {
- let url = lh(/\&mode=6_0/) ? location.href.replace("&mode=6_0", "&mode=4_0") : lh(/\&mode=4_0/) ? location.href.replace("&mode=4_0", "&mode=6_0") : `https://futapo.futakuro.com/?server=may_b&mode=4_0&search=&searchMode=0&kako=0`
- location.href = url;
- return false
- })
- /* if (FUTAPO_AUTO_RELOAD_DEFAULT >= 1) $("#cdsw").click()
- if (FUTAPO_AUTO_RELOAD_DEFAULT >= 2) scr(0)
- */
- }, 500)
-
- GM_addStyle("div.thread-text{display:inline;line-break: anywhere;} .thread-text{word-break:break-all;}") // html{line-height:1.2;}
- setTimeout(() => {
- setSlider(eleget0('//div[@id="boxArea"]'), 54, 300, 54, "box高さ:***", "boxheight", (val) => {
- eleget0('#boxheightcss')?.remove()
- end(document.head, `<style id="boxheightcss">div.thread-contents{height:${val - 2}px !important;} a.box{height:${15 + val}px !important;}</style>`)
- }, 0, 'style="width:7em;height:0.5em;"')
- setSlider(eleget0('//div[@id="boxArea"]'), 0, 10, 5, "タイトル行間:***", "lineheight", (val) => {
- eleget0('#boxlineheightcss')?.remove()
- end(document.head, `<style id="boxlineheightcss">html{line-height:${1+val/10} !important;}</style>`)
- }, 0, 'style="width:7em;height:0.5em;"')
- }, 999)
- },
- funcMemo: () => { SITE.funcFinally() },
- funcFinally: (disableHide, numberOfHidden) => {
- setTimeout(() => {
- let found = 0;
-
- // 7::8::9:: メモが付いたものを左上に優先整列
- // ここの7/8/9動作は正規表現対応や大文字小文字全角半角非区別のために標準のメモが付く動作(正規表現非対応)や非表示動作(正規表現非対応)とは一致しない点に注意
- try {
- // メモをクリックで消す&ESC/パネル外をクリックでパネルを消す動作を登録
- if (!GF.yhmMemoDeleteButton) {
- GF.yhmMemoDeleteButton = 1
- $(document).on("keydown", e => {
- if (e.key === "Escape") $('#yhmMemoDeletePanel').hide(200).queue(function() {
- $(this).remove();
- run("observed");
- })
- })
- $(document).on("mousedown", e => {
- if (!e?.target?.closest("#yhmMemoDeletePanel") || e?.target?.matches("#yhmMemoDeletePanelClose")) $('#yhmMemoDeletePanel').hide(200).queue(function() {
- $(this).remove();
- run("observed");
- })
- })
- $(document).on("click", ".yhmMemoDeleteButton,.yhmNoSelect", e => { // クリックで削除
- let ele = e.target?.closest(".yhmMemoDeleteButton")
- if (!ele) return;
- // 非表示
- if (ele?.dataset?.qword) {
- var str = pref(SITE.id + ' : SearchHideTitle') || [];
- let qword = str.find(v => escape(v) === ele?.dataset?.qword)
- if (qword) {
- $(ele).hide(200).queue(function() { $(this).remove() }); // これは削除パネル用の動作
- //elegeta('.yhmMyMemo').filter(e => e === escape(qword)).forEach(e => { $(e).hide(200).queue(function() { $(this).remove() }) })
- //adja(document.body, "afterbegin", "<yhmmymemoremoved></yhmmymemoremoved>");
- //eleget0('yhmmymemoremoved')?.remove(); // 学園祭用に消去を告知
- GM.setClipboard(qword)
- showByTitle(qword)
- pref(SITE.id + ' : SearchHideTitle', (pref(SITE.id + ' : SearchHideTitle') || []).filter(n => n != qword))
- }
- e.preventDefault()
- return false
- } else {
- // メモ
- var str = pref(SITE.id + ' : SearchMyMemo') || [];
- let memo = str.find(v => escape(v.t + v.m + v.c) === ele.id)
- if (memo) {
- $(ele).hide(200).queue(function() { $(this).remove() }); // これは削除パネル用の動作
- elegeta('.yhmMyMemo').filter(e => e.id === escape(memo.t + memo.m + memo.c)).forEach(e => { $(e).hide(200).queue(function() { $(this).remove() }) })
- //adja(document.body, "afterbegin", "<yhmmymemoremoved></yhmmymemoremoved>");
- //eleget0('yhmmymemoremoved')?.remove(); // 学園祭用に消去を告知
- document.body.dispatchEvent(new Event('yhmMyMemoRemoved'))
- GM.setClipboard(memo.t)
- pref(SITE.id + ' : SearchMyMemo', (pref(SITE.id + ' : SearchMyMemo') || []).filter(n => JS(n) !== JS(memo)))
- }
- e.preventDefault()
- return false
- }
- })
- document.addEventListener("scroll", e => {
- let my = eleget0('#yhmMemoDeletePanel')?.getBoundingClientRect()?.bottom + window.scrollY - clientHeight() + 15
- if (window.scrollY > my) window.scrollTo({ left: 0, behavior: "smooth", top: my })
- })
- }
-
- let memoa = pref(SITE.id + ' : SearchMyMemo') || [];
- memoa = memoa.filter(v => SITE?.preventMemo(v.m)).map(v => {
- v.than = han(v.t);
- if (isValidRE(v.t)) v.re = new RegExp(v.t, "mi");
- return v
- }) // 重いので計算を最内周でせず1回で済ます
- let hide = disableHide ? [] : pref(SITE.id + ' : SearchHideTitle') || []
- hide = hide.map(v => { return { word: v, re: isValidRE(v) ? new RegExp(v, "mi") : null } }) // 重いので計算を最内周でせず1回で済ます
-
- var hit = new Set()
- for (let e of elegeta('.box:not([relocatedByMemo])')) {
- let tt = eleget0('.thread-text', e)?.textContent
- for (let v of memoa) {
- if (v.re && v.re.test(han(tt)) ||
- tt?.indexOf(v.t) !== -1) { // u/U/jメモ登録ワードが正規表現として有効なら正規表現としてチェック、また単純文字列としてヒットしてもヒットとする
- hit.add(e)
- e.dataset.vip = Math.max("○◎★".indexOf(v.m), e.dataset?.vip || 0) // 9>8>7の順で強い結果を残す
- e.title = `${e.title?e.title+" ":""}${v.m}${v.t}`
- e.dataset.hitwords = `${e.dataset.hitwords?e.dataset.hitwords+" ":""}${v.m}${v.t}`;
- if (v?.t?.length > 3) { if (!eleget0(`*[id="${escape(v.t+v.m+v.c)}"]`, e)) after(eleget0('.thread-text', e), `<span class="ignoreMe yhmMyMemo yhmMemoDeleteButton" id="${escape(v.t+v.m+v.c)}" title="『${sani(v.t)}』についたメモ\nクリックで削除&クリップボードにコピー" style="${MEMOSTYLE} cursor:pointer; background-color:${v.c}; border-radius:1em; color:#fff;">${sani(v.m)}${sani(v.t)?.substr(0,25)+(v?.t?.length>25?"…":"")}</span>`) } else {
- if (!eleget0(`*[id="${escape(v.t+v.m+v.c)}"]`, e)) after(eleget0('.thread-text', e), `<ruby class="ignoreMe yhmMyMemo yhmMemoDeleteButton" id="${escape(v.t+v.m+v.c)}" title="『${sani(v.t)}』についたメモ\nクリックで削除&クリップボードにコピー"><span class="ignoreMe yhmMyMemo" style="${MEMOSTYLE} cursor:pointer; background-color:${v.c}; border-radius:1em; color:#fff;">${sani(v.m)}${sani(v.t)?.substr(0,25)+(v?.t?.length>25?"…":"")}</span></ruby>`)
- }
- }
- }
- eleget0('.thumbnail', e)?.setAttribute("title", `${tt}\n${e.title}`)
- }
- GF.opened = GF.opened || new Set()
- GF.opened1 = GF.opened1 || new Set()
- GF.opened2 = GF.opened2 || new Set()
-
- while (1) {
- var b = elegeta('.box:not([relocatedByMemo])')
- var e = b.find(v => hit.has(v))
- if (!e) break;
-
- //GF.opened.push(e.href)
-
- let vip = Number(e.dataset.vip)
- e.setAttribute("relocatedByMemo", "")
- let memoEle = e
- let firstBox = elegeta('.box:not(.boxpri,.boxpri2)').filter(e => e.style.backgroundColor !== "rgb(255, 255, 0)")[0]
- if (vip == 1) {
- firstBox = elegeta('.box:not(.boxpri2,.boxpri3)').filter(e => e.style.backgroundColor !== "rgb(255, 255, 0)")[0]
- eleget0('.thread-text', memoEle).style.color = "#12e";
- memoEle.style.boxShadow = "4px 4px 4px 0px #0006";
- memoEle.style.zIndex = 2;
- memoEle.style.fontWeight = "bold"
- memoEle.classList.add("boxpri2")
- } else if (vip == 2) {
- firstBox = elegeta('.box:not(.boxpri3)').filter(e => e.style.backgroundColor !== "rgb(255, 255, 0)")[0]
- eleget0('.thread-text', memoEle).style.color = "#12e";
- memoEle.style.boxShadow = "4px 4px 4px 0px #0006";
- memoEle.style.zIndex = 3;
- memoEle.style.fontWeight = "bold"
- memoEle.classList.add("boxpri3")
- } else {
- memoEle.style.boxShadow = "4px 4px 4px #0006";
- memoEle.style.zIndex = 1;
- }
- memoEle.classList.add("boxpri")
-
- firstBox.parentNode.insertBefore(memoEle, firstBox)
-
- // Qの非表示にヒットしたものは除外、正規表現対応・全角半角非区別・大文字小文字非区別
- let tt = eleget0('.thread-text', e)?.textContent;
- let hitPreventWord = hide.find(q => {
- return q.re && q.re.test(han(tt)) || tt?.indexOf(q.word) !== -1
- }) // Q非表示登録ワードが正規表現として有効なら正規表現としてもチェック、また単純文字列としてヒットしてもヒットとする
- if (!(disableHide || !hitPreventWord)) {
- e.title += `\n\nブロックワード『${hitPreventWord?.word}』で抑制`
- } else {
- if (vip == 0 && e.offsetHeight && !GF.opened.has(e.href)) {
- GF.opened.add(e.href);
- //GF.opened = GF.opened.slice(0, 1000)
- }
-
- if (vip == 1 && e.offsetHeight && !GF.opened1.has(e.href)) {
- GF.opened1.add(e.href);
- // GF.opened1 = GF.opened1.slice(0, 1000)
- found = memoEle.cloneNode(true);
- if (FUTAPO_89_NOTIFY.split(" ").includes("notify")) notifyMe(eleget0(".thread-text", found)?.innerText, e.dataset.hitwords, e => {
- e.preventDefault(); //`${"\n\n"+eleget0('//a[@id="server"]')?.innerText||""}`
- window.open(memoEle.href, "", "noreferrer");
- }, eleget0('img', found)?.src)
- }
- if (vip == 2 && e.offsetHeight && !GF.opened2.has(e.href)) {
- GF.opened2.add(e.href);
- //GF.opened2 = GF.opened2.slice(0, 1000)
- // GF.open = GF.open || []
- found = memoEle.cloneNode(true);
- if (FUTAPO_89_NOTIFY.split(" ").includes("notify")) notifyMe(eleget0(".thread-text", found)?.innerText, e.dataset.hitwords, e => {
- e.preventDefault();
- window.open(memoEle.href, "", "noreferrer");
- }, eleget0('img', found)?.src)
- memoEle.classList.add('blinkingOL')
- addstyle.add('@keyframes outline { 0% { outline: 2px solid #f0f; } 100% { outline: 2px solid #c8f; } } .blinkingOL{ animation: outline 1s ease infinite alternate; }')
-
- function opentab(href) {
- if (Date.now() - (GF.latest || 0) > (ISCHROME ? 7000 : 5000)) {
- GF.latest = Date.now()
- GM.openInTab(href, true)
- memoEle.classList.remove('blinkingOL')
- } else {
- setTimeout(() => { opentab(href) }, 333)
- }
- }
- opentab(memoEle.href)
- //}
- }
- }
- }
- if (found) {
- //if (FUTAPO_SOUND_NOTIFY) sound("sine", 0.1);
- if (FUTAPO_89_NOTIFY.split(" ").includes("sound")) sound("sine", 0.1);
- }
- } catch (e) { if (DEBUG_CATCH) alert(e) }
- }, 200)
- if (numberOfHidden) window.dispatchEvent(new CustomEvent('scroll')) // 非表示をしてスレアイテム数が画面に入り切るようになるとスクロールができなくて続きがあっても読み込めなくなるのでスクロールイベントだけ起こす
- },
- keyFunc: [{
- key: /^g$|^h$/, // g::画像でNG h::画像でピックアップ
- func: (k) => {
- e = eleget0('img.thumbnail:hover')
- if (e) {
- eleget0('div.cat-menu', e?.closest(".box"))?.click()
- eleget0(k == "h" ? 'a#th_img_pickup' : 'a#th_img_ng')?.click()
- /* waitdo(() => eleget0('select[name="img_match"]'), e => e.value = "100")
- waitdo(() => eleget0('input#all_board'), e => e?.click())
- waitdo(() => eleget0('input#save.submit.option-button'), e => e?.focus())
- */
- waitdo(() => eleget0('select[name="img_match"]'), e => e.value = pref("FUTAPO_IMAGE_NG_PERCENT") || "100")
- waitdo(() => eleget0('input#all_board'), e => e?.click())
- waitdo(() => eleget0('input#save.submit.option-button'), e => e?.focus())
- waitdo(() => eleget0('select[name="img_match"]'), () => {
- eleget0('select[name="img_match"]')?.addEventListener("change", e => {
- pref("FUTAPO_IMAGE_NG_PERCENT", e.target.value)
- })
- })
- }
- }
- }, {
- key: 'd', // d::
- func: (e) => {
- let r = eleget0('//a[@id="reload"]');
- if (r) {
- let scr = (i) => {
- let last = eleget0('#kako-search')
- window.scroll({ left: 0, top: last ? 0 : 99999, behavior: i % 2 == 1 ? "instant" : "smooth" })
- if (!last && i < 100) setTimeout(() => { scr(++i) }, 100) // 10秒まで
- //if (!last && i < 150) setTimeout(() => { scr(++i) }, 100) // 15秒まで
- }
- scr(0)
- //} // 要5秒インターバル
- }
- },
- }, {
- key: 'e', // e::リロード
- func: () => {
- let r = eleget0('//a[@id="reload"]');
- if (r) {
- if (!GF.latestReload || new Date().getTime() - GF.latestReload > 4000) {
- r.click();
- GF.latestReload = new Date().getTime();
- } // 要4秒インターバル
- }
- },
- }, {
- key: 'Shift+F', // Shift+F::FTBucketでキーワード検索
- func: () => { searchWithHistory("FUTACHAN", "FTBucket", 'https://www.ftbucket.info/scrapshot/ftb/index.php?mode=c&favo=0&ord=1&s=***', "|") },
- }, {
- key: /^7$|^8$|^9$|^Shift\+\'$|^Shift\+\($|^Shift\+\)$/, // 7::8::9::Shift+789
- func: (e) => {
- let shift = e.match0("Shift+");
- var str = pref(SITE.id + ' : SearchMyMemo') || [];
- let memostr = (e == "9" || e == "Shift+)") ? "★" : (e == "7" || e == "Shift+'") ? "○" : "◎"
- var newstr = str.filter(e => e.m === memostr).map(e => e.t)
- GF.sorttype = ((GF.sorttype || 0) % 3 + 1)
- var [order, finstrfunc] = [
- ["登録順", a => a.join(" ")],
- ["abc順", a => a.sort(new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare).join(" ")],
- ["長さ→abc順", a => a.sort((a, b) => a.length === b.length ? (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a, b) : a.length > b.length ? 1 : -1).join(" ")]
- ][GF.sorttype - 1]
- let tips = shift ? "独自構文Tips:\n「ABCやDEFを含まず、GHIかJKLを含み、かつMNOとPQRも含む」\n!ABC|DEF GHI|JKL MNO PQR" : "複数の単語をスペースで区切って入力するとまとめて登録できます";
- var target = (window.getSelection() && window.getSelection().toString().trim()) || (prompt(`${memostr}メモを付けるキーワードを入力してください\n\nこのサイトではここで設定した項目、メモが付く項目を左上に優先配置します\n(部分一致、正規表現使用可)\n\n${"7:○メモではヒットした項目を左上に優先配置します\n8:◎メモではさらに音声とNotificationで通知します\n9:★メモでは更に自動的に新しいタブで開きます"}\n\nすでに登録されている文字列を入力するとそれを削除します\n\n${tips}\n\n現在登録済み(${newstr.length}): (${order})\n${finstrfunc(newstr)}\n\n`) || "").trim();
- if (!target) return;
- let targets = shift ? [target.replace(/^S$/, "??").replace(/^S([\s \||])/, "??$1").replace(/([\s \||!!])S([\s \||])/, "$1??$2").replace(/([\s \||!!])S$/, "$1??").replace(/|/gm, "|").replace(/^[\!|!](\S*)/, "^(?!.*($1)).*").replace(/(\S*)[ ](\S*)/gm, "^(?=.*($1))(?=.*\($2\))").replace(/\s| /gm, ".*")] // 独自構文を正規表現に変換
- :
- target.split(/\s| /)
-
- var dele = 0;
- targets.forEach(targetc => {
- targetc = targetc.trim()
- var str = pref(SITE.id + ' : SearchMyMemo') || [];
- var str2 = str.filter(e => { return e.t != targetc })
- if (str.length != str2.length) {
- if (confirm(`『${targetc}』(${str.find(e=>e.t==targetc)?.m})は既に存在します\n削除しますか?`)) {
- if (debug) V && dc(`『${targetc}』をメモから削除しました`)
- pref(SITE.id + ' : SearchMyMemo', JSON.stringify(str2));
- dele = 1;
- elegeta('[relocatedByMemo]').forEach(v => v.removeAttribute("relocatedByMemo"))
- $(".yhmMyMemo").remove()
- run("returned")
- }
- } else {
- storeMemo(targetc.trim(), memostr, COLOR1)
- elegeta('[relocatedByMemo]').forEach(v => v.removeAttribute("relocatedByMemo"))
- run("returned")
- }
- })
- if (dele) run(document.body, "returned")
- },
- }, {
- key: /^0$/, // 0::メモ一覧一括削除画面
- func: (e) => {
- var str = pref(SITE.id + ' : SearchMyMemo') || [];
- var newstr = str
- GF.sorttype = eleget0("#yhmMemoDeletePanel") ? ((GF.sorttype) + 1) : 1
- var [order, finstrfunc] = [
- ["登録順", a => a.reverse()],
- ["abc順→種別", a => a.sort((a, b) => a.m == b.m ? 0 : a.m < b.m ? 1 : -1).sort((a, b) => (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a.t, b.t))],
- ["長さ→abc順→種別", a => a.sort((a, b) => a.m == b.m ? 0 : a.m < b.m ? 1 : -1).sort((a, b) => a.t.length === b.t.length ? (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a.t, b.t) : a.t.length > b.t.length ? 1 : -1)],
- ["種別→登録順", a => a.reverse().sort((a, b) => a.m == b.m ? 0 : a.m < b.m ? 1 : -1)],
- ["種別→abc順", a => a.sort((a, b) => (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a.t, b.t)).sort((a, b) => a.m == b.m ? 0 : a.m < b.m ? 1 : -1)],
- ["種別→長さ→abc順", a => a.sort((a, b) => a.t.length === b.t.length ? (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a.t, b.t) : a.t.length > b.t.length ? 1 : -1).sort((a, b) => a.m == b.m ? 0 : a.m < b.m ? 1 : -1)]
- ][(GF.sorttype - 1) % 6]
- var words = finstrfunc(newstr)
- $("#yhmMemoDeletePanel").remove()
- end(document.body, `<div id="yhmMemoDeletePanel" style="width:85%; font-size:95%; position:absolute; top:1em; left: 50%; transform: translate(-50%, 0%); box-shadow:0px 0px 2em #0008; word-break:keep-all; z-index:${Number.MAX_SAFE_INTEGER}; padding:2em; margin:auto; background-color:#fff; line-height:1.8em;"><span id="yhmMemoDeletePanelClose" style="cursor:pointer;float:right;">×(Esc)</span>0:メモ&非表示一括削除<br>メモ(${words.length})(${order})をクリックすると削除してクリップボードにコピーします<br><div>`)
- let dup = [] // 重複しているものは暗い色にする
- let list = ""
- words.forEach(w => {
- // list += `<span class="yhmMemoDeleteButton" id="${escape(w.t+w.m+w.c)}" data-m="${escape(w.m)}" data-t="${escape(w.t)}" data-c="${escape(w.c)}" style="cursor:pointer; background-color:${w.c}; ${dup.includes(w.t)?"filter:saturate(0.66);":""} padding:1px 0.4em 1px 0.3em; margin:0; border-radius:1em; color:#fff;"><font class="yhmNoSelect" style="user-select:none;" ${dup.includes(w.t)?'data-gakusai="1"':''}>${sani(w.m)}</font>${sani(w.t)}</span> `
- list += `<span class="yhmMemoDeleteButton" id="${escape(w.t+w.m+w.c)}" style="cursor:pointer; background-color:${w.c}; ${dup.includes(w.t)?"filter:saturate(0.66);":""} padding:1px 0.4em 1px 0.3em; margin:0; border-radius:1em; color:#fff;"><font class="yhmNoSelect" style="user-select:none;" ${dup.includes(w.t)?'data-gakusai="1"':''}>${sani(w.m)}</font>${sani(w.t)}</span> `
- dup.push(w.t)
- })
-
- var [order, finstrfunc] = [
- ["登録順", a => a.reverse()],
- ["abc順", a => a.sort((a, b) => (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a, b))],
- ["長さ→abc順", a => a.sort((a, b) => a.length === b.length ? (new Intl.Collator("ja", { numeric: true, sensitivity: 'base' }).compare)(a, b) : a.length > b.length ? 1 : -1)],
- ][(GF.sorttype - 1) % 3]
- var words = pref(SITE.id + ' : SearchHideTitle') || [];
- words = finstrfunc(words)
- list += `<br><br>非表示登録(${words.length})(${order})をクリックすると削除してクリップボードにコピーします<br>`;
- words.forEach(w => {
- list += `<span class="yhmMemoDeleteButton" id="${escape(w)}" data-qword="${escape(w)}" style="cursor:pointer; background-color:#444;font-weight:500; ${dup.includes(w)?"filter:saturate(0.66);":""} padding:1px 0.5em 1px 0.5em; margin:0; border-radius:1em; color:#fff;">${sani(w)}</span> `;
- })
-
- end(eleget0("#yhmMemoDeletePanel"), list)
- },
- }, {
- key: 'a', // a::ソート
- func: () => {
- var sorttype = Number($('.yhmSortType')?.attr("id") || 0);
- $('.yhmSortType').remove(), $(document.body).append(`<span class="yhmSortType" id="${++sorttype%4}"></span>`)
- popup2("A:ソート\n" + (["レス数", "勢い", "タイトル", "元"].map((c, i) => " " + c + (i + 1 == sorttype ? " ←\n" : "\n")).join("")), 6, "min-width:6em;")
- sorttype == 1 && sortdom(elegeta('.box:not(#kako-search)'), v => Number(eleget0('.rescnt', v)?.textContent), 1)
- sorttype == 2 && sortdom(elegeta('.box:not(#kako-search)'), v => Number(0 + eleget0('.ikioi-icon', v)?.textContent) + Number((eleget0('span.red', v)?.textContent + 0 || 0)) * 10, 1)
- sorttype == 3 && sortdom(elegeta('.box:not(#kako-search)'), v => (eleget0('.thread-text', v)?.textContent))
- sorttype == 4 && sortdom(elegeta('.box:not(#kako-search)'), v => v?.dataset?.idx)
- }
- }, ],
- wholeHelp: [() => 1, " A:ソート"],
- hideSelectedWord: 1,
- selectedHelp: { help: [KEYHIDE + ":NGワードに追加", "7/8/9:左上に優先配置(8:+通知/9:+開く)"] }, //, multi: "複数行に渡る文字列は NG に入れられません" },
- },
- {
- id: 'FUTACHAN_CATALOG',
- urlRE: /\/\/anige\.horigiri\.net\/?$|\/\/anige\.horigiri\.net\/\?cat=|\/\/anige\.horigiri\.net\/\?paged=/,
- listTitleXP: '//div/h3[@class="entry-title"]/a',
- listTitleSearchXP: '//div/h3[@class="entry-title"]/a[+++]/../../../..',
- hideSelectedWord: 1,
- listTitleMemoSearchXP: '//div/h3[@class="entry-title"]/a[+++]',
- listGen: 5,
- delat: 500,
- listTitleMemoSearchXPSameGen: 1,
- WhateverFirstAndEveryAPFunc: () => { SITEINFO[SITEINFO.findIndex(c => c.id == "FUTACHAN_CATALOG")].WhateverFirstAndEveryAPFunc() },
- keyFunc: [{
- key: 'Shift+F', // Shift+F::FTBucketでキーワード検索
- func: () => { searchWithHistory("FUTACHAN", "FTBucket", 'https://www.ftbucket.info/scrapshot/ftb/index.php?mode=c&favo=0&ord=1&s=***', "|") },
- }],
- },
- {
- id: 'FUTACHAN',
- urlRE: '//kuzure.but.jp/f/$',
- WhateverFirstAndEveryAPFunc: () => { popup3(`Shift+F:FTBucket検索`, 8, 5000) },
- keyFunc: [{
- key: 'Shift+F', // Shift+F::FTBucketでキーワード検索
- func: () => { searchWithHistory("FUTACHAN", "FTBucket", 'https://www.ftbucket.info/scrapshot/ftb/index.php?mode=c&favo=0&ord=1&s=***', "|") },
- }],
- },
- {
- id: 'FUTACHAN', // futaba::
- urlRE: '//.*.ftbucket.info/|//kuzure.but.jp/f/b/|//[^.]+.2chan.net\/|//anige.horigiri.net|//kako.futakuro.com/futa/|https:\/\/tsumanne\.net\/.*\/data\/',
- title: '.thre table .cno',
- box: '.thre table',
- disableKeyB: 0,
- redoWhenRefocused: 1,
- funcMemo: () => GF.resChained = [],
- // isMemoPartialMatch:1,
- isHidePartialMatch: 1,
- memoFunc: titleEle => eleget0('.memo', titleEle.closest('tr')),
- memoPosition: "afterbegin",
- listHelpJQS: '.thre table',
- delay: 111,
- memoStyle: 'display:table !important; margin-bottom:2px;',
- //memoStyle: 'display:block !important; width:fit-content; margin-bottom:2px;',
- detailURLRE: /$^/,
- detailTitleXP: '',
- hideSelectedWord: 1,
- selectedHelp: { help: [KEYHIDE + ":NGワードに追加", "y:YouTubeで検索"], multi: "y:YouTubeで検索" },
- detailTitleSearchXP: '',
- listTitleSearchFunc: (title) => { // q::レス中キーワードNG // todo:リロードで追加されたレスにも非表示を適用
- let resHit = [];
- if (typeof title === "string" && !/^No\.\d+$/gmi.test(title)) { // textContentでサーチする
- for (let res of elegeta('.thre table:not(.ftbpu table,#respopup_area table)')) { // レス全体(ID:~も対象)
- if (res.textContent.indexOf(title) !== -1) resHit.push(res?.closest('table'));
- }
- }
- return resHit;
- },
-
- // WhateverFirstAndEveryAPFunc: () => { popup3(`Shift+F:FTBucket検索\nA:画像順/そうだね順/引用順でソート${location.href.match0(/^https?:\/\/[^.]+\.2chan\.net\//)?"\nE:新着チェック\nD:新着チェック+新着に移動":""}`, 7, 5000) },
- //WhateverFirstAndEveryAPFunc: () => { popup3(`Shift+F:FTBucket検索\na:画像順/そうだね順/引用順でソート${location.href.match0(/^https?:\/\/[^.]+\.2chan\.net\//)?"\ne:新着チェック\nd:新着チェック+新着に移動\nc:ホバー中レスにそうだね\nn:自動更新&通知":""}`, 7, 5000) },
- WhateverFirstAndEveryAPFunc: () => { popup3(`Shift+F:FTBucket検索\na:画像順/そうだね順/引用順でソート${location.href.match0(/^https?:\/\/[^.]+\.2chan\.net\//)?"\ne:新着チェック\nd:新着チェック+新着に移動\nc:ホバー下にそうだね\nn:自動リロード&新着通知\nm:監視ワード設定":""}`, 7, 5000) },
- //WhateverFirstAndEveryAPFunc: () => { popup3(`Shift+F:FTBucket検索\nA:画像順/そうだね順/引用順でソート${location.href.match0(/^https?:\/\/[^.]+\.2chan\.net\//)?"\nE:新着チェック\nD:新着チェック+新着に移動\nC:ホバー下にそうだね\nN:自動リロード&新着通知\nM:監視ワード設定":""}`, 7, 5000) },
- funcD: () => { // d::
- // let r = eleget0("#contres>a,#fvw_loading");
- let r = eleget0("#contres>a,#fvw_loading,a#akahuku_reload_button");
- if (r) {
- if (!GF.latestReload || new Date().getTime() - GF.latestReload > 4000) {
- r.click();
- GF.latestReload = new Date().getTime();
- } // 要4秒インターバル
- setTimeout(() => { eleget0('.reloadline')?.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" }) }, 200);
- }
- },
- keyFunc: [{
- key: "y", // y::
- func: e => {
- let str = window.getSelection()?.toString()?.trim()
- if (!str) return;
- let strs = str.split("\n").map(v => v.trim())?.slice(0, 6)
- let urls = strs.map(str => `https://www.youtube.com/results?search_query=${(str)}`)
- let urls2 = strs.map(str => `https://www.youtube.com/results?search_query=${encodeURI(str)}`)
- if (confirm(`${strs.join("\n")}\nをYouTube検索します(安全のため一度に最大6行にしています)\n\nまたついでに下記をクリップボードにコピーします\nよろしいですか?\n\n${urls.join("\n")}\n`)) {
- GM.setClipboard(strs.map((v, i) => `${v} - YouTube\n${urls2[i]}\n`).join(""))
- urls2.forEach((v, i) => {
- setTimeout(() => {
- GM.openInTab(v, true)
- }, i * 5000)
- })
- }
- }
- }, {
- key: /^(?:Shift\+)?(?:Alt\+)?(?:z|Z)$/, // z::ポップアップを画像として「名前を付けて保存」 Shift+で高画質、Alt+でメモを反映 Alt+だとクリップボードには○メモが付いたものだけコピーする
- id: "z",
- func: (e) => {
- elegeta('.relpost').forEach(e => e.classList.remove("relpost"))
- if (document.elementFromPoint(mousex, mousey)?.matches("video,img")) return;
- let isZ = e.indexOf("Shift+") != -1;
- let target = eleget0('.ftbpu') ? ".ftbpu" : eleget0('#pickbox') ? "#presentPick" : ""
- let orgtarget = eleget0('.ftbpu') ? ".ftbpu" : eleget0('#pickbox') ? "#pickbox" : ""
- if (!target || !orgtarget) return;
- if (target == "#presentPick") {
- let p = end(document.body, `<div id="presentPick" class="ignoreMe" style="padding:5px; width:max-content; max-width:100%; background-color:#ffffeecc; "></div>`)
- if (GF.presentPick) GF.presentPick.forEach(v => p.append(v.cloneNode(true)))
- sortdom(elegeta('#presentPick table[data-rsc]'), v => v.getAttribute("data-rsc"))
- } else {
- let p = eleget0(target).cloneNode(true);
- p.id = "presentPick";
- p.className = "ignoreMe"
- target = "#presentPick"
- document.body.appendChild(p)
- // end(document.body, `<div id="presentPick" class="ignoreMe" style="padding:5px; width:max-content; max-width:100%; background-color:#ffffeecc; "></div>`)
- }
- if (elegeta(`${target} img:not(.quoteSpeechBalloonImg)`).length) { // 画像が1つでもあったら
- if (1 || !eleget0("#contdisp font:text*=スレッドがありません")) {
- let imgs = ld('kuzure.but.jp') ? elegeta(`${target} a>img[src*="s."]:not([data-rep-lar])`).filter(e => e.src.match(/s\./)) :
- elegeta(`${target} a>img[src*="thumb/"]:not([data-rep-lar])`).filter(e => e.src.match(/thumb\/\d+s\./))
- imgs.forEach(img => {
- let orgHref = img?.parentNode?.href
- if (orgHref?.match(/\.(jpe?g|png|bmp|gif|webp)/)) {
- cldt("head");
- img.dataset.repLar = 2;
- $.ajax({
- url: orgHref,
- type: 'HEAD',
- error: (function(img) {
- return function() {
- img.dataset.repLar = 0;
- cldt(`404`);
- }
- })(img),
- success: (function(img) {
- return function() {
- img.src = orgHref;
- img.dataset.repLar = 1
- cldt(`replace`);
- }
- })(img),
- });
- }
- })
- }
- let zwait = () => {
- cldt("compele?");
- if (!eleget0(`${target} table a>img[data-rep-lar="2"]`) && elegeta(`${target} table a>img[data-rep-lar="1"]`).every(e => e.complete)) { z(e, isZ ? 3 : 2, isZ ? 3 : 2) } else { setTimeout(zwait, 50) }
- }
- setTimeout(zwait, 100 + elegeta(`${target} img:not(.quoteSpeechBalloonImg)`)?.length * 10)
- } else { z(e, isZ ? 2 : 1.5, isZ ? 2 : 1.5) }
-
- if (FUTABA_Z_TO_COPY_TO_CLIPBOARD_AS_TEXT_TOO) { // 文字としてもクリップボードにコピー
- let txt = elegeta('table[data-rsc]', eleget0(orgtarget)).filter(v => e.indexOf("Alt+") == -1 || eleget0('.yhmMyMemoO', v)).map(t => FUTABA_Z_TO_COPY_TO_CLIPBOARD_AS_TEXT_TOO.replace("${num1}", eleget0('.rsc', t)?.innerText || "").replace("${name1}", eleget0('.csb', t)?.innerText || "").replace("${name2}", eleget0('.cnm', t)?.innerText || "").replace("${time}", eleget0('.cnw', t)?.innerText || "").replace("${num2}", eleget0('.cno', t)?.innerText || "").replace("${soudane}", eleget0('.sod', t)?.innerText || "").replace("${text}", eleget0('blockquote', t)?.innerText || ""))
- //let txt = elegeta('table[data-rsc]', eleget0(orgtarget)).map(t => FUTABA_Z_TO_COPY_TO_CLIPBOARD_AS_TEXT_TOO.replace("${num1}", eleget0('.rsc', t)?.innerText || "").replace("${name1}", eleget0('.csb', t)?.innerText || "").replace("${name2}", eleget0('.cnm', t)?.innerText || "").replace("${time}", eleget0('.cnw', t)?.innerText || "").replace("${num2}", eleget0('.cno', t)?.innerText || "").replace("${soudane}", eleget0('.sod', t)?.innerText || "").replace("${text}", eleget0('blockquote', t)?.innerText || ""))
- GM.setClipboard(txt.join("\n"))
- popup3(elegeta('table[data-rsc]', eleget0(orgtarget)).map(t => `${eleget0('.rsc',t)?.innerText}`).join(","), 0, 5000, "top")
- }
- return;
-
- function z(key, SCALE_MIN = 1, SCALE_MAX = 2) {
- //var SCALE_MIN = 1 // 保存最低倍率
- //var SCALE_MAX = scaleLimit || 2 // 保存最大倍率
- //var D_FILENAME_MAXLENGTH = 87 // ファイル名の最大長
- var D_FILENAME_MAXLENGTH = 83 // ファイル名の最大長
- if (!eleget0(target)) return;
- let filenameSuffix = (key.indexOf("Alt+") != -1) ? FUTABA_ALTZ_FILENAME_SUFFIX : ""
-
- GF?.zFunc && GF?.zFunc()
-
- let honbun = elegeta(`${target} blockquote`).map(e => e.innerText)?.join(" ")?.replace(/\s+|\n+/gm, " ")?.trim()
- honbun = honbun?.replace(/\s*\>+[^\s]+/gm, "")?.trim() || res
- honbun = honbun?.slice(0, 100); // ?.replace(/キタ━+\(゚\∀゚\)━+\!+/gm,"");
-
- if (key.indexOf("Alt+") == -1) {
- $(`${target} .yhmMyMemo,${target} .relallArea,${target} .adddel`).remove()
- $(`${target} .sod`).css({ "font-size": "100%" }).removeClass("sodmypush") //,"float":"right" })
- }
- $(`${target} .relallArea`).remove()
-
- $(`${target}`).css({ "box-shadow": "none", "transform": "scale(1)" })
-
- if (orgtarget == "#pickbox") {
- $(`${target} table`).css({ "margin-right": "auto", "margin-left": "0" })
- $(`${target} a img`).css({ "max-height": "" }) // pickの画像縦圧縮を解放する
- }
- $(`${target} .revQuote`).after("<br>"); //css({ "display": "inline-block" })
-
- addstyle.add(`.yendotsaveElement .GM_FRRS_Counter,.yendotsaveElement .GM_FRRS_own_res{display:none}`)
- elegeta(`${target} .rsc`).forEach(e => e.style = "")
-
- var hrefName = ""
- // var fn = `${signzen(document.title?.replace(/\s+|\n+/gm," ")?.trim()+" "+location.href).substr(0, D_FILENAME_MAXLENGTH-hrefName.length-1)} ${hrefName}`?.trim()
- var fn = `${signzen(document.title?.replace(/\s+|\n+/gm," ")?.trim()+" "+location.href).substr(0, D_FILENAME_MAXLENGTH-hrefName.length)}`?.trim()
- var res = honbun
- res = res?.replace(/^\s*\>.*\s*$/gm, "")?.replace(/キタ━+\(゚\∀゚\)━+\!+/gm, "")?.trim() || res;
- // if (res) fn = `${signzen(document.title+" "+location.href).substr(0, D_FILENAME_MAXLENGTH/2-hrefName.length-1)} ${signzen(res).substr(0, D_FILENAME_MAXLENGTH/2-1)} ${hrefName}`.trim()
- if (res) fn = `${signzen(document.title+" "+location.href).substr(0, D_FILENAME_MAXLENGTH/2-hrefName.length)} ${signzen(res).substr(0, D_FILENAME_MAXLENGTH/2)}`.trim()
- //if(filenameSuffix&&fn.length>D_FILENAME_MAXLENGTH)fn=fn.slice(-1,1)
- fn += filenameSuffix
-
- function signzen(str) { return str.replace(/^\s+/, "").replace(/\\|\/|\:|\;|\,|\+|\&|\=|\*|\?|\"|\'|\>|\<|\./g, c => { return String.fromCharCode(c.charCodeAt(0) + 0xFEE0) }) }
-
- let puele = eleget0(`${target}`)
- puele.classList.add('yendotsaveElement')
-
- let scale = Math.max(1, Math.min(SCALE_MAX, SCALE_MIN + (elegeta('img:not(.quoteSpeechBalloonImg)', puele).length * 0.5)))
- popup3(`z:ポップアップ(ピックアップ)を保存\n(Shift+で高画質、Alt+でメモを維持)\nScale = ${scale}`, 12)
- // document.dispatchEvent(new CustomEvent('saveDOMAsImage', { detail: { element: puele, filename: fn, scale: scale, hd: (key.indexOf("Shift+") != -1) ? 1 : 0, eleToFlash: target == ".ftbpu" ? eleget0(".ftbpu") : eleget0("#pickbox") } }))
- document.dispatchEvent(new CustomEvent('saveDOMAsImage', { detail: { element: puele, filename: fn, scale: scale, hd: (key.indexOf("Shift+") != -1) ? 1 : 0, eleToFlash: orgtarget == ".ftbpu" ? eleget0(".ftbpu") : eleget0("#pickbox") } }))
- $('#presentPick').remove()
- //if (orgtarget == "#pickbox") setTimeout(() => window.dispatchEvent(new Event('resize')), 1000)
- }
- },
- }, {
- key: 'e', // e::リロード
- func: () => {
- let r = eleget0("#contres>a,#fvw_loading,a#akahuku_reload_button");
- if (r) {
- if (!GF.latestReload || new Date().getTime() - GF.latestReload > 4000) {
- r.click();
- GF.latestReload = new Date().getTime();
- } // 要4秒インターバル
- }
- }
- }, {
- key: 'd', // d::
- func: (e) => {
- if (eleget0("a:hover,video:hover,img:hover")) return
- SITE.funcD()
- },
- }, {
- key: 'Shift+F', // Shift+F::FTBucketでキーワード検索
- func: () => { searchWithHistory("FUTACHAN", "FTBucket", 'https://www.ftbucket.info/scrapshot/ftb/index.php?mode=c&favo=0&ord=1&s=***', "|") },
- }, {
- key: 'n', // n::Notificationで新着レスを通知on/off
- func: (key, opt = null, changeto = null) => {
- if (changeto === null) {
- GF.reloadAndNotifyNewArrival = ((GF.reloadAndNotifyNewArrival || 0) + 1) % 5;
- pref("FUTABA_RELOAD_AND_NOTIFY_NEWRES_DEFAULT", GF.reloadAndNotifyNewArrival)
- } else {
- GF.reloadAndNotifyNewArrival = Number(changeto);
- }
- $('#notiApiOn').remove();
- let mess = `N:自動リロードと新着通知…${GF.reloadAndNotifyNewArrival}\n${["オフ","自動リロード","自動リロード+新着レスをNotificationで通知(メモ付きのみ)","自動リロード+新着レスをNotificationで通知(画像かメモ付きのみ)","自動リロード+新着レスをNotificationで通知(全て)"][GF.reloadAndNotifyNewArrival]}`
- //if (opt != "automation") popup2(`${mess}`, 8);
- if (opt != "automation") popup2(`N:自動リロードと新着通知\n${["オフ","自動リロード","自動リロード+新着レスをNotificationで通知(メモ付きのみ)","自動リロード+新着レスをNotificationで通知(画像かメモ付きのみ)","自動リロード+新着レスをNotificationで通知(全て)"].map((c, i) => " " + c + (i == GF.reloadAndNotifyNewArrival ? " ←\n" : "\n")).join("")}`, 9, "min-width:31em;")
-
- if (GF.reloadAndNotifyNewArrival && ld("2chan.net")) {
- $(`<span id="notiApiOn" class="ignoreMe" title="${mess}" style="all:initial; cursor:pointer; position: fixed; right:60em; bottom:0.5em; z-index:100; opacity:0.55; font-size:15px; margin:0px 1px; text-decoration:none !important; padding:1px 6px 1px 6px; word-break: break-all !important; border-radius:12px; border:solid 1px #888; background-color:${["#fff","#dfe","#dfe","#dfe"][GF.reloadAndNotifyNewArrival-1]}; color:#888; ">${["オフ","更新","メモ","画像","全て"][GF.reloadAndNotifyNewArrival]}</span>`).click(e => keyFuncDispatch("n")).appendTo('body');
- }
- },
- }, {
- key: 'a', // a::
- func: () => {
- GF.stopmoq = 1
- let isftchan = /^https?:\/\/kuzure\.but\.jp\/f\/b\//.test(location.href);
- let isanigeaki = /\/\/anige\.horigiri\.net\/\?p/.test(location.href);
- if (isanigeaki || isftchan) $(elegeta('.thre .rtd').filter(e => !e.closest("#pickbox,.ftbpu"))[0]).closest("table").before($('<div id="thre0"></div>'))
- $('.reloadline').remove();
- GF.sort = (GF?.sort || 0) % 4 + 1 //var sorttype = GF.sort||0//Number($('.yhmSortType')?.attr("id") || 0);
- let sorttype = GF.sort
- popup2("A:ソート\n" + (["画像", "そうだね", "引用", "古い順"].map((c, i) => " " + c + (i + 1 == sorttype ? " ←\n" : "\n")).join("")), 6, "min-width:6em;")
- sorttype == 1 && sortdom(elegeta('table:not([data-reszero]) .rtd:not(#pickbox .rtd,.ftbpu .rtd)').map(v => v?.closest('table')), (v) => { return (((v.querySelector('table:not([data-reszero]) .sod') || v).innerText?.match0(/そうだねx(\d+)/) || 0) * 1) + (v.querySelectorAll("table:not([data-reszero]) .revQuote").length * 1) + (((v.textContent.match(/\.(gif|webm|mp4).*\d\d\d\sB\)|youtube\.|youtu\.be|nicovideo|(?<!>)fu?\d+\.(gif|webm|mp4)/gmi) ? 1 : 0) * 1000000000) || ((v.textContent.match(/\d\d\d\sB\)|(?<!>)fu?\d+\.(jpg|jpeg|png|bmp|webp)/gmi) ? 1 : 0) * 1000000) || ((v.textContent.match(/ttps?\:\/\//gmi) ? 1 : 0) * 1000)) }, 1) // リンクも加点
- //sorttype == 1 && sortdom(elegeta('table:not([data-reszero]) .rtd:not(#pickbox .rtd,.ftbpu .rtd)').map(v => v?.closest('table')), (v) => { return (((v.querySelector('table:not([data-reszero]) .sod') || v).innerText?.match0(/そうだねx(\d+)/) || 0) * 1) + (v.querySelectorAll("table:not([data-reszero]) .revQuote").length * 1) + (((v.textContent.match(/\d\d\d\sB\)|youtube\.|youtu\.be|nicovideo|(?<!>)fu?\d+\.(jpg|jpeg|png|gif|bmp|webp|webm|mp4)/gmi) ? 1 : 0) * 1000000) || ((v.textContent.match(/ttps?\:\/\//gmi) ? 1 : 0) * 1000)) }, 1) // リンクも加点
- sorttype == 2 && sortdom(elegeta('table:not([data-reszero]) .rtd:not(#pickbox .rtd,.ftbpu .rtd)').map(v => v?.closest('table')), (v) => { return (((v.querySelector('table:not([data-reszero]) .sod') || v).innerText?.match0(/そうだねx(\d+)/) || 0) * 1000000000) + (v.querySelectorAll("table:not([data-reszero]) .revQuote").length * 1000000) + (((v.textContent.match(/\d\d\d\sB\)|youtube\.|youtu\.be|nicovideo|(?<!>)fu?\d+\.(jpg|jpeg|png|gif|bmp|webp|webm|mp4)/gmi) || []).length * 1000) || ((v.textContent.match(/ttps?\:\/\//gmi) || []).length * 1)) }, 1) // リンクも加点
- sorttype == 3 && sortdom(elegeta('table:not([data-reszero]) .rtd:not(#pickbox .rtd,.ftbpu .rtd)').map(v => v?.closest('table')), (v) => { return (((v.querySelector('table:not([data-reszero]) .sod') || v).innerText?.match0(/そうだねx(\d+)/) || 0) * 1000000) + (v.querySelectorAll("table:not([data-reszero]) .revQuote").length * 1000000000) + (((v.textContent.match(/\d\d\d\sB\)|youtube\.|youtu\.be|nicovideo|(?<!>)fu?\d+\.(jpg|jpeg|png|gif|bmp|webp|webm|mp4)/gmi) || []).length * 1000) || ((v.textContent.match(/ttps?\:\/\//gmi) || []).length * 1)) }, 1) // リンクも加点
- sorttype == 4 && sortdom(elegeta('table:not([data-reszero]) .rtd:not(#pickbox .rtd,.ftbpu .rtd)').map(v => v?.closest('table')), v => v.getAttribute("rsc")) //,
- setTimeout(() => { GF.stopmoq = 0 }, 500)
- },
- }],
- funcOnlyFirst: () => {
- hoverHelp(e => e.closest('table[border="0"]') ? "Q:非表示 W:アンドゥ 1,5:○メモ 2,6:×メモ" : "")
- GF.latestReload = Date.now() - 3000
- GF.newarticle = 1000
- GF.latestInterval = FUTABA_AUTO_RELOAD_INTERVAL * 60 * 1000
-
- //GF.alertWord = pref("alertWord")?.replace(/^<string>([\s\S]*)<\/string>$/, "$1") || ""; // m::
- document.addEventListener("focus", () => GF.alertWord = pref("alertWord")?.replace(/^<string>([\s\S]*)<\/string>$/, "$1") || "")
- keyFuncAdd([{
- key: 'm',
- func: () => {
- const tips = "Tips:\n「ABCやDEFを含まず、GHIかJKLを含み、かつMNOとPQRも含む」\n!ABC|DEF GHI|JKL MNO PQR\n";
- let a = prompt(`m:\n監視ワードを正規表現+独自構文で設定できます\nこれにヒットしたレスはNotificationで通知されます\n\n${tips}\n\n現在の設定値:\n${GF?.alertWord||"なし"}`, GF?.alertWord || "")
- if (a === null) return;
- try {
- GF.alertWordRE = new RegExp(a.replace(/^S$/, "??").replace(/^S([\s \||])/, "??$1").replace(/([\s \||!!])S([\s \||])/, "$1??$2").replace(/([\s \||!!])S$/, "$1??").replace(/|/gm, "|").replace(/^[\!|!](\S*)/, "^(?!.*($1)).*").replace(/(\S*)[ ](\S*)/gm, "^(?=.*($1))(?=.*\($2\))").replace(/\s| /gm, ".*"), "mi"); //alert(searRE); // 独自構文を正規表現に変換
- } catch (e) {
- alert(`${a}\n\nは正規表現としてエラーが出てしまうため取り消します\n\n参考:\nhttps://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_expressions\n`);
- a = "";
- }
- GF.alertWord = a;
- pref("alertWord", a ? `<string>${a}</string>` || "" : "")
- }
- }])
-
- let is2chan = /^https?:\/\/[^.]+\.2chan\.net\//.test(location.href);
- let isftb = /^https?:\/\/[^\.]+\.ftbucket\.info\//.test(location.href); // let isftb = /^https?:\/\/www\.ftbucket\.info\//.test(location.href);
- let istsumanne = ld("tsumanne.net");
- if (is2chan && !location.href.match0(/\.2chan\..+\/res\//)) return;
- let iskurokako = /\/\/kako\.futakuro\.com\/futa\//.test(location.href);
- let isftchan = /^https?:\/\/kuzure\.but\.jp\/f\/b\//.test(location.href);
- let isanigeaki = /\/\/anige\.horigiri\.net\/\?p/.test(location.href);
- let isfvw = eleget0('#fvw_menu') // futakuro
- if (isanigeaki) GM_addStyle('table, th, td{border:0;}');
- if (isftchan || isanigeaki) { document.body.innerHTML = "<div class='thre'>" + document.body.innerHTML + "</div>" }
- if (isftchan) { GM_addStyle("body{min-width:95%} .thre table{margin-right:0} #v0z{display:none;}") }
- if (is2chan || isftchan) GM_addStyle(".rtd{vertical-align:top} #pdm{z-index:2000000021}")
- //GM_addStyle("#pickbox .yhmMyMemo{white-space: nowrap;} .quo{vertical-align:top} a:visited{color:#800080;}")
- GM_addStyle("#pickbox .yhmMyMemo{font-size:85%; white-space: nowrap;} .quo{vertical-align:top} a:visited{color:#800080;} .ftbpu .quo{max-width:25vw;}")
- //let fivechthumbnailetc = (!lh(/\.2chan\.net\//) || eleget0('#fivechthumbnailetc')) && 1
- GM_addStyle(".quoteSpeechBalloon{padding:0 0.68em; margin-left:0.68em; font-size:14px; position:relative; bottom:1px; color:#484; background-color:#ffffee;border-radius:1em; user-select:none; cursor:pointer;}") // qsb::
- //GM_addStyle(".quoteSpeechBalloon{font-size:14px; position:relative; bottom:1px; color:#484; background-color:#ffffee;border-radius:1em; user-select:none; cursor:pointer;}") // qsb::
- GM_addStyle(".quoteSpeechBalloonImg{float:right; clear:right; max-height:2.8em !important; padding:4px; user-select:none; background-color:#ffffee; border-radius:6px; cursor:pointer;")
- GM_addStyle(".revQuote{cursor:pointer;color:#789922; margin:0.19em; }")
- addstyle.add('.waiting{ display: inline-block; vertical-align: middle; font-size:85%; color: #666; line-height: 1; width: 1em; height: 1em; border: 0.12em solid currentColor; border-top-color: rgba(102, 102, 102, 0.3); border-radius: 50%; box-sizing: border-box; -webkit-animation: rotate 1s linear infinite; animation: rotate 1s linear infinite; } @-webkit-keyframes rotate { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } } @keyframes rotate { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }</style>')
- //addstyle.add('.relallArea{user-select:none; text-align:center; display:inline-block; line-height:1.5em; color:#789922c0; min-width:1.5em; height:1.5em; margin:1px 0 1px 3px; margin-top:0.3em; } .memo:empty+.backlink:empty+.relallArea{margin-top:3px; } .backlink:empty+.relallArea{margin-top:7px; } ') //background-color:#eed;
- addstyle.add('.relallArea{user-select:none; text-align:center; display:inline-block; line-height:1.5em; color:#789922c0; min-width:1.5em; height:1.5em; margin:1px 0 1px 3px; margin-top:0.3em; } .memo:empty+.backlink:empty+.relallArea{margin-top:3px; } .backlink:empty+.relallArea{margin-top:7px; } .backlink{word-break:break-word;}') //background-color:#eed;
- addstyle.add('.relallAreaon{outline:2px dotted #789922f0; cursor:pointer;}') //background-color:#eed;
- addstyle.add('.sodmypush{color:#f00;}')
- if (location.href.match0("anige.horigiri")) GM_addStyle(`blockquote{color:#800000;line-height:1.2em;font-style:normal;`)
- addstyle.add('.GM_FRRS_Counter{display:none !important;}')
- //addstyle.add(`#pickbox .sod{ margin: 0 0px 0 8px;} `)
- addstyle.add('#pickbox blockquote { word-wrap: anywhere; }')
- addstyle.add(`#pickbox .rts {cursor:pointer;}`)
-
- GF.originalDocTitle = eleget0('//div[@class="thre"]/blockquote')?.textContent || document.title;
- GF.originalDocTitle0 = document.title;
- GF.anchor = new Array(1000).fill("")
-
- //let favi=eleget0('.thre>a>img')?.src; if(favi)end(document.head,`<link rel="icon" href="${favi}">`) // ファビコンを最初の画像にする
-
- // フォーカスが戻った時に0を表示
- //$(document).on("click","div.thre",e=>{e.preventDefault();if(e?.target?.matches("div.thre"))leadFocus();})
- let Rimg = eleget0('//div[@class="thre"]/a/img')?.cloneNode(true)
- let Rdesc = elegeta('//div[@class="thre"]/span[1]|//div[@class="thre"]/span[2]|//div[@class="thre"]/span[3]|//div[@class="thre"]/span[4]|//div[@class="thre"]/span[5]|//div[@class="thre"]/a[@class="sod"]')?.map(e => e.cloneNode(true))
- let Rhonbun = eleget0('//div[@class="thre"]/blockquote')?.cloneNode(true)
- // if (!img || !honbun) return;
- if (Rimg && Rhonbun) {
- document.addEventListener("focus", e => { if (!elegeta('.thre img:not(img.quoteSpeechBalloonImg):inscreen:visible').length) leadFocus() })
- document.addEventListener("blur", e => { $(".leadFocus").remove() })
- Rhonbun.style.minWidth = "800px"
-
- function leadFocus(e) {
- if (!lh("/res/") || eleget0('//div[@class="thre"]/a/img|//div[@class="thre"]/a[2]/img:inscreen:visible') || eleget0('//div[@class="thre"]/blockquote:inscreen:visible') || eleget0('#pickbox,.leadFocus,.yhmMyMemo')) return;
- let Rlead = end(document.body, `<div class="ignoreMe leadFocus" style="background-color:#ffffeef8; box-shadow:#00000070 0 0 1em ; border:solid 2px #800000b0; border-radius:1em; padding:1.2em; opacity:1; z-index:2000000020; position:fixed; top:0; right:0; transform:translate(0,-150%);"><table border="0"><tbody><tr><td class="rts">…</td><td class="rtd"></td></tr></tbody></table></div>`)
- Rdesc.forEach(e => eleget0(".rtd", Rlead)?.appendChild(e))
- eleget0(".rtd", Rlead)?.appendChild(Rimg)
- eleget0(".rtd", Rlead)?.appendChild(Rhonbun)
-
- $(Rlead).animate2({ "transform": "translate(0,0)" }, 333) //, (function(e) { return function() { setTimeout(() => { $(e).animate({"transform":"translate(0,-100%)"},333, () => $(e).remove()) }, 999) } })(lead))
- setTimeout(Rlead => {
- $(document).one("click wheel mousemove keydown", "body", (function(Rlead) {
- return function() {
- $(Rlead).animate2({ "transform": "translate(0,-150%)" }, 333);
- setTimeout(Rlead => Rlead.remove(), 333, Rlead);
- }
- }(Rlead)))
- }, 1333, Rlead)
- }
- }
-
- // res0:: レス本文をレス0かのように加工
- if (FUTABA_REPLACE_RES0 && ld(/\.2chan\./) && !isfvw) {
- let img = eleget0('div.thre a img')?.cloneNode(true)
- let imgfn = eleget0('div.thre a')?.cloneNode(true)
- let imgfn2 = eleget0('div.thre a')?.cloneNode(true)
- let desc = elegeta('div.thre>span.rsc,div.thre>span.csb,div.thre>span.cnm,div.thre>span.cnw,div.thre>span.cno')?.slice(0, 6)?.map(e => e.cloneNode(true))
- let honbun = eleget0('div.thre blockquote')?.cloneNode(true)
- if (imgfn && imgfn2 && img && honbun) {
- addstyle.add(`.thre table[data-reszero] blockquote:not(.ftbpu table blockquote,#pickbox table blockquote){min-width:800px;}`)
- let lead = before(eleget0(`table[border="0"]`), `<table border="0" data-reszero><tbody><tr><td class="rts">…</td><td class="rtd"><span class="rsc">0</span></td></tr></tbody></table>`)
- lead = !lead ? after(eleget0(`.maxres`), `<table border="0" data-reszero><tbody><tr><td class="rts">…</td><td class="rtd"><span class="rsc">0</span></td></tr></tbody></table>`) : lead
- //let lead = before(eleget0(`table[border="0"]`), `<table border="0" data-reszero><tbody><tr><td class="rts">…</td><td class="rtd"><span class="rsc">0</span></td></tr></tbody></table>`)
- desc.forEach(e => eleget0(".rtd", lead).appendChild(e))
- end(eleget0(".rtd", lead), `<br> `)
- eleget0(".rtd", lead).appendChild(imgfn)
- //end(imgfn, `B)<br>`)
- after(imgfn, `<br>`)
- imgfn2.innerText = ""
- eleget0(".rtd", lead).appendChild(imgfn2)
- imgfn2.appendChild(img)
- eleget0(".rtd", lead).appendChild(honbun)
- elegeta('div.thre>a>img,div.thre>blockquote').forEach(e => {
- e.dataset.hiddenzero = 1;
- e.style.display = "none"
- })
- elegeta('div.thre>span.rsc,div.thre>span.csb,div.thre>span.cnm,div.thre>span.cnw,div.thre>span.cno').forEach(e => {
- e.dataset.hiddenzero = 1;
- e.style.display = "none"
- })
- /*elegeta('div.thre>a>img,div.thre>blockquote').forEach(e => e.style.display = "none")
- elegeta('div.thre>span.rsc,div.thre>span.csb,div.thre>span.cnm,div.thre>span.cnw,div.thre>span.cno').forEach(e => e.style.display = "none")*/
- }
- $(document).on("keydown", e => { e.key == "c" && !e.shiftKey && !e.altKey && !e.ctrlKey && eleget0('div.thre>table[data-rsc="0"]:hover') && $(eleget0('div.thre>a.sod:not(.sodmypush)')).click().effect("highlight") })
- }
-
- // let isfvw = eleget0('#fvw_menu')
- let replaceMainPopup = (FUTABA_HOVER_POPUP_REPLACE) || !is2chan
- if (is2chan && replaceMainPopup) { GM_addStyle("#slp{z-index:1001} .qtd{display:none !important;} .fvw_respop,#respopup_area{display:none;opacity:0}"); }
- $("#contres>a,#fvw_loading").attr("title", ($("#contres>a,#fvw_loading").attr("title") || "新着レスを読み込みます") + "\nE:リロード\nD/右クリック:リロード+新着にスクロール").on("contextmenu", (e) => {
- SITE.funcD();
- return false;
- })
- if (FUTABA_FLOAT_RELOAD_BUTTON) {
- $('#contres').attr("floated", "");
- GM_addStyle(`#contres{z-index:999; position:fixed; right:18em; left:auto; bottom:3px; height:auto; padding:0.1em 0.2em; border:2px solid #dddddd; background-color:#ffffff;}`)
- }
- pick2title(1)
-
- GF.myRes = [];
- eleget0('input[value="返信する"]')?.addEventListener("click", e => {
- let ysend = window.scrollY; // スクロールを戻す
- GF.myRes.push(eleget0("#ftxa")?.value?.trim())
-
- function revscr(i) {
- if (window.scrollY != ysend) window.scrollTo(0, ysend);
- else if (i--) setTimeout(revscr, 17, i);
- }
- revscr(1000)
- }, true)
-
- $(document).on("click", ".relallAreaon", e => SITE?.keyFunc?.find(v => v.id === "z")?.func(e.ctrlKey ? "Shift+Z" : "z"))
-
- // 自動リロード::
- if (1 || FUTABA_AUTO_RELOAD_INTERVAL >= 1) {
- var musousa = {
- last: Date.now(),
- elapsed: () => { return Date.now() - this.last },
- init: () => {
- this.last = Date.now();
- $('body').on('keydown mousedown mousemove', () => this.last = Date.now());
- },
- }
- musousa.init()
- setInterval(() => {
- if (document.body.textContent.match("スレッドがありません|上限\d+レスに達しました") && !GF?.stopThre) {
- GF.stopThre = 1
- if (document.visibilityState == "hidden") document.title = `🐾${document.title}`
- }
- if (!GF?.reloadAndNotifyNewArrival) return;
- if ((musousa.elapsed() < 30000 && document.activeElement.tagName.match(/textarea|input/i)) || eleget0('//span[@id="thread_down"]') || GF?.stopThre) return;
- let r = eleget0('#contres>a,#fvw_loading')
- if (!r) return
- let inter = Math.max(60 * 1000, Math.min(Math.max(600000, (FUTABA_AUTO_RELOAD_INTERVAL * 60 * 1000)), (FUTABA_AUTO_RELOAD_INTERVAL * 60 * 1000) + (musousa.elapsed() >= 59000 && GF?.newarticle == 0 && GF.latestInterval / 1))) // 1分以上無操作の時リロードして新着がないと更新間隔を広げていく、最低1分最大10分
- if (!GF.latestReload || Date.now() - GF.latestReload >= inter) {
- if (FUTABA_DEBUG >= 1) end(document.body, `<div>update : ${gettime()} / 現在更新間隔:${~~(inter/1000)} / 新着:${GF?.newarticle} / リロード後経過秒:${~~((Date.now()-GF.latestReload)/1000)} / 無操作秒:${~~(musousa.elapsed()/1000)} / 前回:${GF.latestInterval/1000}</div>`)
- GF.latestReload = Date.now()
- GF.latestInterval = inter
- r?.click()
- }
- if (FUTABA_DEBUG >= 2) document.title = `${~~(inter/1000)}/${GF?.newarticle}/${~~((Date.now()-GF.latestReload)/1000)}/${~~(musousa.elapsed()/1000)} 現在更新間隔:${~~(inter/1000)} / 新着:${GF?.newarticle} / リロード後経過秒:${~~((Date.now()-GF.latestReload)/1000)} / 無操作秒:${~~(musousa.elapsed()/1000)} / 前回:${GF.latestInterval/1000}`
- }, 1000)
- }
-
- // 画面最下段で下ホイールでリロード
- window.addEventListener('wheel', (e) => {
- if (e.deltaY > 0 && document.body.clientHeight - window.innerHeight <= window.pageYOffset && Date.now() - GF.latestReload >= 5000) {
- $('#contres>a').click().effect("highlight");
- GF.latestReload = Date.now();
- }
- })
-
- // c::ホバー下にそうだね
- var xTarget = []
- var cnoPushed = []
- var sodTarget = []
- var lastc = 0
- document.addEventListener('keypress', e => {
- if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable || ((e.target.closest('#chat-messages,ytd-comments-header-renderer') || document.activeElement.closest('#chat-messages,ytd-comments-header-renderer')))) return;
- var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
- var ele = document.elementFromPoint(mousex, mousey);
- var cno = eleget0('table:not([data-reszero]) .cno', ele?.closest('table'))?.textContent?.replace(/\D/g, "")
- if (cno && key == "c") $(ele?.closest('td')).effect("highlight")
- if (cno && key == "c" && cno && !cnoPushed.includes(cno)) {
- cnoPushed.push(cno)
- xTarget.push({ key: key, cno: cno });
- xTarget = (Array.from(new Set(xTarget.map(v => JSON.stringify(v))))).map(v => JSON.parse(v)) // uniq:オブジェクトの配列→JSON文字列配列→uniq→オブジェクトの配列
- dosou()
- //end(eleget0('.sod', ele?.closest('td')), `<span class="waiting">?</span>`) // くるくるを表示
- //elegeta(`table .cno:text*=${cno}`).forEach(e => end(eleget0(".sod", e?.closest('table')), `<span class="waiting">?</span>`)) // くるくるを表示
- }
- })
-
- function dosou() {
- if (Date.now() - lastc < 3500) return
- var a = xTarget.shift()
- if (!a) return
- let [key, cno] = [a.key, a.cno]
- let t = eleget0(`table .cno:text*=${cno}`)?.closest('table')
- if (!t) return;
- if (key == "c" && !t?.dataset?.soddone) {
- //$('.waiting', t).remove()
- //elegeta(`table .cno:text*=${cno}`).forEach(e => eleget0(".waiting", e?.closest('table'))?.remove())
- $('.sod', t).click().effect("highlight") // eleget0('//div[@class="thre"]/a[@class="sod"]')
- lastc = Date.now()
- t.dataset.soddone = 1;
- }
- }
- setInterval(dosou, 500)
-
- // そうだねを改行しないようにする
- //document.body.addEventListener('copy', (event) => { $("#pickbox .sod:contains('x')").css({ "font-size": "125%", "float": "none" }); setTimeout(() => { $("#pickbox .sod:contains('x')").css({ "font-size": "125%", "float": "right" }) }, 1) });
-
- var sdset = () => { if (is2chan) elegeta('#pickbox .sod:not([onclick]),.ftbpu .sod:not([onclick])').forEach(e => { e.setAttribute("onclick", `sd(${e?.id.replace(/\D/g,"")});return(false);`) }) }
- // $(document).on("click", "a.sod", (e) => { e.target.style.color = "#f00" }) //$(document).on("click","a.sod",(e)=>{e.target.style.textDecoration="underline"})
- $(document).on("click", "a.sod", (e) => { e.target.classList.add("sodmypush") }) //$(document).on("click","a.sod",(e)=>{e.target.style.textDecoration="underline"})
-
- $("#contres>a,#fvw_loading").on("click", (e => {
- GF.newarticle = 0
- let latestEle = eleget0('//*[@class="thre"]/table[last()]');
- //setTimeout(() => { document.body.dispatchEvent(new Event('2chanReloaded')) }, 1500)
- document.body.dispatchEvent(new Event('2chanReloadedNodelay'))
- })); // リロード再実行
-
- //moq(eleget0('.thre:not(#pickbox .thre'), ".thre>table,.thre>div:not(#pickbox .thre>div,#pickbox,.qtd,.slp)", v => { // 新しいレスが追加されたら
- // moq(eleget0('.thre:not(#pickbox .thre'), "table", v => {
- moq(eleget0('.thre:not(#pickbox .thre'), "table,div:not(#pickbox,.qtd)", v => { // ,divはfutakuro共存用
- //moq(eleget0('.thre:not(#pickbox .thre'), "table,div", v => { // ,divはfutakuro共存用
- if (!GF.stopmoq) {
- //let newarticle = elegeta('.thre table .rtd .rsc:not([data-basec]),.thre table .res_no:not([data-basec])')
- let newarticle = elegeta('.thre table .rsc:not([data-basec]),.thre table .res_no:not([data-basec])')
- GF.newarticle = newarticle.length || 0
- setTimeout(() => { document.body.dispatchEvent(new Event('2chanReloaded')) }, 1)
- }
- })
- // document.addEventListener("focus", () => { // firefox
- window.addEventListener("focus", () => { // firefox/chrome
- document.title = document.title.replace(/^🐾/g, "");
- if (GF?.arrival) {
- document.title = document.title.replace(/^[🐾🔴🔵⚠️■]+/g, "");
- //document.title = document.title.replace(/^[🐾🔴🔵■]+/g, "");
- GF.arrival = 0
- }
- })
-
- function moq(observeNode, targetCSSSelector, cb) {
- new MutationObserver((m) => {
- let eles = [...m.filter(v => v.addedNodes).map(v => [...v.addedNodes]).filter(v => v.length)].flat().find(v => v.nodeType === 1 && v?.matches(targetCSSSelector));
- if (eles) cb(eles)
- })?.observe(observeNode || document.body, { attributes: false, childList: true, subtree: false });
- }
-
- document.body.addEventListener('2chanReloadedNodelay', function() {
- $(`<hr class="reloadline" style="color:#aaa;">`).fadeIn("slow", function() { $(this).hide(0).fadeIn("slow") }).insertAfter($(elegeta('.thre table:not(#pickbox table,.ftbpu table,#respopup_area table,[floated] table)').pop()))
- }, false);
- $(document).on("scroll", () => {
- if (elegeta('.reloadline:not([found])').filter(e => isinscreen(e)).length) {
- $(elegeta('.reloadline')).attr("found", 1).delay(2000).hide("slow").delay(3000, function() { $(this).remove(); })
- }
- })
-
- /* $(elegeta('//table[@class="deleted"]|//tr/td[@class="rtd"]/blockquote[contains(text(),"del")]/../../../..')).attr("title", "クリックで復帰").attr("floated", "1").animate2({ "opacity": "0.3", "transform": "scale(0.8)", "transform-origin": "right", "float": "right" }, 500).one("click", function() {
- $(elegeta('//table[@class="deleted"]|//tr/td[@class="rtd"]/blockquote[contains(text(),"del")]/../../../..')).attr("title", "").animate2({ "opacity": "0.7", "transform": "scale(1)", "transform-origin": "right", "float": "none" }, 500);
- */
- $(elegeta('//table[@class="deleted"]')).attr("title", "クリックで復帰").attr("floated", "1").animate2({ "opacity": "0.3", "transform": "scale(0.8)", "transform-origin": "right", "float": "right" }, 500).one("click", function() {
- $(elegeta('//table[@class="deleted"]')).attr("title", "").animate2({ "opacity": "0.7", "transform": "scale(1)", "transform-origin": "right", "float": "none" }, 500);
- $(this)[0].scrollIntoView({ block: "nearest", behavior: "smooth" })
- }) // 隔離を薄くして右に
-
- $(document.body).append(`<script type="text/javascript">function scrRsc(n){let e=[...document.querySelectorAll('.rsc')].find(c=>c.textContent==n);if(e){e.closest(".rtd").style.outline="4px solid #0f0";setTimeout(()=>e.closest(".rtd").style.outline=null,1000)}e?.closest("table")?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center'})}</script>`)
-
- addstyle.add(`.embedyt{margin-bottom:0; max-width:43vw; margin-top:-0.5em; min-width: unset !important; width:fit-content; display: grid; grid-template-columns: repeat(auto-fit, minmax(321px, 1fr)); gap: 0px;}`)
- // ニコ動埋め込み(PrivacyBadger等は要Disable)
- var embednv = () => {
- var elea = elegeta('a[href*="nicovideo"]:not([nde]),a[href*="//nico.ms/sm"]:not([nde])').filter(e => !e.closest('font[color="#789922"]'))
- for (let ele of elea.filter(e => eleget0('.yhmMyMemo', e.closest("table"))).concat(elea.filter(e => isinscreen(e)))) { // リロード回避のためpickされるものは先に読み込む
- let url = ele.href; //innerText.replace(/^ttp/i, "http");
- ele.setAttribute("nde", "nde");
- var nico = url.match(/h?ttps?:\/\/(?:www\.|sp\.)?nicovideo.jp\/watch(?:_tmp)?\/(.*)/i);
- //var nico = url.match(/h?ttps?:\/\/(?:www\.|sp\.)?nicovideo.jp\/watch\/(.*)/i);
- if (!nico) var nico = url.match(/h?https:\/\/nico\.ms\/(.*)/i);
- if (!nico) continue;
-
- let bq = ele?.closest("td,div.thre>blockquote:not([yte])")
- let vbq = eleget0('.embedyt', ele?.closest("td,div.thre>blockquote:not([yte])"))
- if (!vbq) $(bq).append('<blockquote class="embedyt"></blockquote>');
- $(eleget0('.embedyt', bq)).append(`<p class="ignoreMe" style="display:inline-block; margin:0 1em 1em 0;"><iframe sandbox="allow-scripts allow-same-origin" class="ignoreMe" referrerpolicy="no-referrer" rel="nofollow external noopener noreferrer" allowfullscreen="allowfullscreen" allow="autoplay" src="https://embed.nicovideo.jp/watch/${nico[1]}${nico[1].match0(/\?/)?"&":"?"}persistence=1&oldScript=1&allowProgrammaticFullScreen=1" style="max-width: 100%;" height="181" frameborder="0"></iframe></p>`);
- //$(ele?.closest("td,div.thre>blockquote:not([nde])")).append(`<blockquote><p class="ignoreMe" style="margin:0 0 0px;"></p></blockquote>`) // 埋め込み外部プレイヤー版
- break; // 一度に1つずつしかやらない
- }
- if (elea.length) setTimeout(() => embednv(), 2000 + elea.length * 10);
- }
- autoPagerized(() => { embednv() })
-
- // youtube埋め込み
- var embedyt = () => {
- var elea = elegeta('a[href*="youtube.com"]:not(#pickbox a,[yte]),a[href*="youtu.be"]:not(#pickbox a,[yte])').filter(e => !e.closest('font[color="#789922"]'))
- for (let ele of elea.filter(e => eleget0('.yhmMyMemo', e.closest("table"))).concat(elea.filter(e => isinscreen(e)))) { // リロード回避のためpickされるものは先に読み込む
- let url = ele.href //innerText;
- ele.setAttribute("yte", "yte");
- var sm = (url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11}).*[\?\&]t=(\d*).*$/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/(?:live\/|watch\?v=)([a-zA-Z0-9_\-]{11}).*&t=(\d*).*$/i)) || url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/shorts\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/(?:live\/|watch\?v=)([a-zA-Z0-9_\-]{11})/i);
- var videoList = url.match0(/https:\/\/www\.youtube\.com\/watch_videos\?video_ids=([a-zA-Z0-9_\-\,]+)/)?.split(",")?.filter(v => v.match(/^[a-zA-Z0-9_\-]{11}$/));
- if (!sm && !videoList) continue;
- var pl = (url.match0(/[\&\?]list=([a-zA-Z0-9_\-]+)/));
- if (1) { // 2列詰め込む
- let bq = ele?.closest("td,div.thre>blockquote:not([yte])")
- let vbq = eleget0('.embedyt', ele?.closest("td,div.thre>blockquote:not([yte])"))
- if (!vbq) $(bq).append('<blockquote class="embedyt"></blockquote>');
- let src = sm ? 'https://www.youtube.com/embed/' + sm[1] + (pl ? `?list=${pl}` : "") + (sm[2] ? `${pl?"&":"?"}start=` + sm[2] : "") :
- videoList ? `https://www.youtube.com/embed/${videoList[0]}?playlist=${videoList?.join(',')}` :
- ""
- if (src) $(eleget0('.embedyt', bq)).append(`<p class="ignoreMe" style="display:inline-block; margin:0 1em 1em 0;"><iframe sandbox="allow-scripts allow-same-origin" class="ignoreMe" referrerpolicy="no-referrer" src="${src}" id="ytplayer" type="text/html" height=181 frameborder=0 allowfullscreen allow="picture-in-picture"></iframe></p>`);
- /*if (!sm) continue
- var pl = (url.match0(/[\&\?]list=([a-zA-Z0-9_\-]+)/));
-
- if (1) { // 2列詰め込む
- let bq = ele?.closest("td,div.thre>blockquote:not([yte])")
- let vbq = eleget0('.embedyt', ele?.closest("td,div.thre>blockquote:not([yte])"))
- if (!vbq) $(bq).append('<blockquote class="embedyt"></blockquote>');
- $(eleget0('.embedyt', bq)).append('<p class="ignoreMe" style="display:inline-block; margin:0 1em 1em 0;"><iframe sandbox="allow-scripts allow-same-origin" class="ignoreMe" referrerpolicy="no-referrer" src="https://www.youtube.com/embed/' + sm[1] + (pl ? `?list=${pl}` : "") + (sm[2] ? `${pl?"&":"?"}start=` + sm[2] : "") + `" id="ytplayer" type="text/html" height=181 frameborder=0 allowfullscreen allow="picture-in-picture"></p>`);
- */
- } else { // 1列モード
- if (sm) $(ele?.closest("td,div.thre>blockquote:not([yte])")).append('<blockquote><p class="ignoreMe" style="margin:0 0 0px;"><iframe sandbox="allow-scripts allow-same-origin" class="ignoreMe" referrerpolicy="no-referrer" src="https://www.youtube.com/embed/' + sm[1] + (pl ? `?list=${pl}` : "") + (sm[2] ? `${pl?"&":"?"}start=` + sm[2] : "") + `" id="ytplayer" type="text/html" height=181 frameborder=0 allowfullscreen allow="picture-in-picture"></p></blockquote>`); //width=${pl?401:321}
- }
- break; // 一度に1つずつしかやらない
- };
- if (elea.length) setTimeout(() => embedyt(), 2000 + elea.length * 10);
- }
- autoPagerized(() => { embedyt() })
- /* // ニコ動埋め込み(PrivacyBadger等は要Disable)
- var embednv = () => {
- var elea = elegeta('a[href*="nicovideo"]:not([nde]),a[href*="//nico.ms/sm"]:not([nde])').filter(e => !e.closest('font[color="#789922"]'))
- for (let ele of elea.filter(e => eleget0('.yhmMyMemo', e.closest("table"))).concat(elea.filter(e => isinscreen(e)))) { // リロード回避のためpickされるものは先に読み込む
- let url = ele.href; //innerText.replace(/^ttp/i, "http");
- ele.setAttribute("nde", "nde");
- var nico = url.match(/h?ttps?:\/\/(?:www\.|sp\.)?nicovideo.jp\/watch\/(.*)/i);
- //var nico = url.match(/h?ttps?:\/\/(?:www\.)?nicovideo.jp\/watch\/(.*)/i);
- //var nico = url.match(/h?ttps?:\/\/www.nicovideo.jp\/watch\/(.*)/i);
- if (!nico) var nico = url.match(/h?https:\/\/nico\.ms\/(.*)/i);
- if (!nico) continue
- $(ele?.closest("td,div.thre>blockquote:not([nde])")).append(`<blockquote><p class="ignoreMe" style="margin:0 0 0px;"><iframe class="ignoreMe" referrerpolicy="no-referrer" rel="nofollow external noopener noreferrer" allowfullscreen="allowfullscreen" allow="autoplay" src="https://embed.nicovideo.jp/watch/${nico[1]}${nico[1].match0(/\?/)?"&":"?"}persistence=1&oldScript=1&allowProgrammaticFullScreen=1" style="max-width: 100%;" width="312" height="176" frameborder="0"></iframe></p></blockquote>`) // 埋め込み外部プレイヤー版
- break; // 一度に1つずつしかやらない
- }
- if (elea.length) setTimeout(() => embednv(), 2000 + elea.length * 10);
- }
- autoPagerized(() => { embednv() })
-
- // youtube埋め込み
- var embedyt = () => {
- var elea = elegeta('a[href*="youtube.com"]:not(#pickbox a,[yte]),a[href*="youtu.be"]:not(#pickbox a,[yte])').filter(e => !e.closest('font[color="#789922"]'))
- for (let ele of elea.filter(e => eleget0('.yhmMyMemo', e.closest("table"))).concat(elea.filter(e => isinscreen(e)))) { // リロード回避のためpickされるものは先に読み込む
- let url = ele.href //innerText;
- ele.setAttribute("yte", "yte");
- // var sm = (url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11}).*[\?\&]t=(\d*).*$/i) || url.match(/h?ttps?:\/\/(?:www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_\-]{11}).*&t=(\d*).*$/i)) || url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.)?youtube\.com\/shorts\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_\-]{11})/i);
- // var sm = (url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11}).*[\?\&]t=(\d*).*$/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_\-]{11}).*&t=(\d*).*$/i)) || url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/shorts\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_\-]{11})/i);
- var sm = (url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11}).*[\?\&]t=(\d*).*$/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/(?:live\/|watch\?v=)([a-zA-Z0-9_\-]{11}).*&t=(\d*).*$/i)) || url.match(/h?ttps?:\/\/youtu\.be\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/shorts\/([a-zA-Z0-9_\-]{11})/i) || url.match(/h?ttps?:\/\/(?:www\.|m\.)?youtube\.com\/(?:live\/|watch\?v=)([a-zA-Z0-9_\-]{11})/i);
- if (!sm) continue
- var pl = (url.match0(/[\&\?]list=([a-zA-Z0-9_\-]+)/));
- // $(ele?.closest("td,div.thre>blockquote:not([yte])")).append('<blockquote><p class="ignoreMe" style="margin:0 0 0px;"><iframe class="ignoreMe" referrerpolicy="no-referrer" src="https://www.youtube.com/embed/' + sm[1] + (pl ? `?list=${pl}` : "") + (sm[2] ? `${pl?"&":"?"}start=` + sm[2] : "") + '" id="ytplayer" type="text/html" width=321 height=181 frameborder=0 allowfullscreen allow="picture-in-picture"></p></blockquote>');
-
- if (1) { // 2列詰め込む
- let bq = ele?.closest("td,div.thre>blockquote:not([yte])")
- let vbq = eleget0('.embedyt', ele?.closest("td,div.thre>blockquote:not([yte])"))
- if (!vbq) $(bq).append('<blockquote class="embedyt" style="margin-bottom:0; max-width:40vw;"></blockquote>');
- let index = +(eleget0('.embedyt', bq)?.dataset?.videos || 0) % 2
- $(eleget0('.embedyt', bq)).append('<p class="ignoreMe" style="display:inline-block; margin:0 1em 1em 0;"><iframe class="ignoreMe" referrerpolicy="no-referrer" src="https://www.youtube.com/embed/' + sm[1] + (pl ? `?list=${pl}` : "") + (sm[2] ? `${pl?"&":"?"}start=` + sm[2] : "") + `" id="ytplayer" type="text/html" height=181 frameborder=0 allowfullscreen allow="picture-in-picture"></p>`);
- eleget0('.embedyt', bq).dataset.videos = index + 1;
- //if (index == 1) $(eleget0('.embedyt', bq)).append('<br>')
- } else { // 1列モード
- $(ele?.closest("td,div.thre>blockquote:not([yte])")).append('<blockquote><p class="ignoreMe" style="margin:0 0 0px;"><iframe class="ignoreMe" referrerpolicy="no-referrer" src="https://www.youtube.com/embed/' + sm[1] + (pl ? `?list=${pl}` : "") + (sm[2] ? `${pl?"&":"?"}start=` + sm[2] : "") + `" id="ytplayer" type="text/html" height=181 frameborder=0 allowfullscreen allow="picture-in-picture"></p></blockquote>`); //width=${pl?401:321}
- }
- break; // 一度に1つずつしかやらない
- };
- if (elea.length) setTimeout(() => embedyt(), 2000 + elea.length * 10);
- }
- autoPagerized(() => { embedyt() })
- */
-
- // fu画像埋め込み
- var embedimg = () => {
- if (ld("tsumanne")) {
- elegeta('table blockquote a:not([ime])').filter(v => v?.href?.match(/fu?\d+\.(jpg|jpeg|png|gif|bmp|webp)/gmi)).forEach(e => {
- e.setAttribute("ime", "ime");
- $(e?.closest("td,div.thre>blockquote")).append(`<blockquote style="margin-top:0;"><p class="ignoreMe" style="margin:0 0 0px;"><img class="ignoreMe" referrerpolicy="no-referrer" style="max-height:250px;" src="${e.href}"></p></blockquote>`)
- })
- elegeta('table blockquote a:not([ime])').filter(v => v?.href?.match(/fu?\d+\.(mp4|webm|mp3|aac|flac|m4a)/gmi)).forEach(e => {
- e.setAttribute("ime", "ime");
- $(e?.closest("td,div.thre>blockquote")).append(`<blockquote style="margin-top:0;"><p class="ignoreMe" style="margin:0 0 0px;"><video controls="" name="media" src="${e.href}" style="max-height:250px;" class="ignoreMe"></video></p></blockquote>`)
- })
- } else {
- var elea = elegeta('.rtd blockquote:not([ime]),div.thre>blockquote:not([ime])')
- for (let ele of elea) { // 画面内にあるものだけが基本だけどリロード回避のためpickされるものは優先的に読み込む
- let txt = ele.innerText;
- ele.setAttribute("ime", "ime");
- var sm = txt.match(/^fu?\d+\.(jpg|jpeg|png|gif|bmp|webp)/gmi);
- if (sm?.length) {
- sm.forEach(v => $(ele?.closest("td,div.thre>blockquote")).append(`<blockquote style="margin-top:0;"><p class="ignoreMe" style="margin:0 0 0px;"><img class="ignoreMe" referrerpolicy="no-referrer" style="max-height:250px;" src="https://${/^fu\d+\./.test(v)?"dec.2chan.net/up2/src/":"dec.2chan.net/up/src/"}${v}"></p></blockquote>`))
- }
- var sm = txt.match(/^fu?\d+\.(mp4|webm|mp3|aac|flac|m4a)/gmi);
- if (sm?.length) {
- sm.forEach(v => $(ele?.closest("td,div.thre>blockquote")).append(`<blockquote style="margin-top:0;"><p class="ignoreMe" style="margin:0 0 0px;"><video controls="" name="media" src="https://${/^fu\d+\./.test(v)?"dec.2chan.net/up2/src/":"dec.2chan.net/up/src/"}${v}"" style="max-height:250px;" class="ignoreMe"></video></p></blockquote>`)) // preload="none"
- }
- //break; // 一度に1つずつしかやらない
- };
- //if (elea.length) setTimeout(() => embedimg(), 2000 + elea.length * 10);
- }
- }
- autoPagerized(() => { embedimg() })
-
- FUTABA_PLAY_GIF_INLINE && autoPagerized(() => embedGif())
-
- function embedGif() {
- elegeta('.thre>a>img[href*=".gif"]:not([data-gifloaded]),td.rtd>a[href*=".gif"]>img:not([data-gifloaded])').forEach(e => {
- let a = e.closest("a")
- if (a) {
- e.dataset.gifloaded = 1
- e.src = a.href;
- }
- })
- }
-
- var popped = []
- //$(eleget0('//td/input[@value="返信する"]')).on("click", () => { setTimeout(() => shikomi(), 999) })
- // 引用ポップアップ仕込み
- var cited = [];
- var resEnum = [];
-
- if (eleget0('//b[contains(text(),"このスレの書き込みはIPアドレスが表示されます。")]')) addstyle.add('#ftxa{background-color:#fee !important;}') // IPスレ警告
- addstyle.add('.idw{color:#f00; font-weight:800;}')
-
- function shikomi() {
- if (FUTABA_REMOVE_REDIRECT_PAGE) elegeta('td.rtd blockquote a[href*="/bin/jump.php?"] , div.thre blockquote a[href*="/bin/jump.php?"]').forEach(e => {
- e.rel = "noopener nofollow noreferrer"
- e.href = e.href.replace(/^.*\/bin\/\jump\.php\?/, "")
- }); // リダイレクトページを省略
-
- GF.alertWord = pref("alertWord")?.replace(/^<string>([\s\S]*)<\/string>$/, "$1") || ""; // m::
- let idw = elegeta('.cnw:not(.idw)')
- if (idw.every(v => /ID\:/.test(v.innerText))) {
- GF.idw = 1;
- addstyle.add('#ftxa{background-color:#fee;}') // addstyle.add('#ftxa{background-color:#ffd;}')
- } else if (GF?.idw) addstyle.add('#ftxa{background-color:#fff;}')
- idw.filter(v => /ID\:|IP\:/.test(v.innerText)).forEach(e => e.classList.add("idw")) // IDスレ警告
-
- elegeta('.thre table tr:not([data-quospan])').forEach(e => {
- e.dataset.quospan = "1";
- e.insertAdjacentHTML("beforeend", `<td class="ignoreMe quo" style="position:relative;"><div class="ignoreMe memo"></div><div class="ignoreMe backlink"></div><div class="ignoreMe relallArea"> </div></td>`)
- })
-
- let notifyDelay = 0;
- let awNotify = 0;
-
- elegeta('.thre table .rtd .rsc:not([data-basec]),.thre table .res_no:not([data-basec])').forEach(e => {
- e.dataset.basec = "1"
- e.style.cursor = "pointer"
- e.setAttribute("onclick", `scrRsc(${Number(e.textContent)})`); //クリックで中心にスクロール
- let resno = e?.textContent
- e.closest('table').setAttribute("rsc", resno)
- e.closest('.rtd').dataset.rsc = resno
- e.closest('table').dataset.rsc = resno
- // })
-
- // elegeta('.thre table .rtd .rsc:not([data-basec]),.thre table .res_no:not([data-basec])').forEach(e => {
- e.dataset.basec = "1"
-
- var text = eleget0('blockquote', e.closest('table'))?.innerText?.trim()
- let isMyres = (text && GF?.myRes?.includes(text))
-
- if (FUTABA_SET_56MEMO_TO_ANCHORED >= 1 && isMyres) { // 送信したレスに5メモを付ける
- // let text = eleget0('blockquote', e.closest('table'))?.innerText?.trim()
- // if (text && GF?.myRes?.includes(text)) {
- memoElement(e, document.body, COLOR5, getDefault56memo());
- GF.myRes = GF.myRes.filter(v => !GF?.myRes?.includes(text))
-
- /*if (isMyres) {
- setTimeout((function(e) {
- return function() {
- //var dateStr = getDefault56memo();
- memoElement(e, document.body, COLOR5, getDefault56memo());
- }
- })(e), 1)
- GF.myRes = GF.myRes.filter(v => !GF?.myRes?.includes(text))
- }*/
- }
-
- setTimeout(() => { // 非表示等を反映させるため遅らせる
-
- var tomemo = GF?.anchor[e?.closest("table")?.dataset?.rsc] || ""
- let hasAnyMemo = eleget0('.yhmMyMemo', e?.closest("table")) ? 1 : 0
-
- if (GF?.fromSecond) {
- // if (FUTABA_SET_56MEMO_TO_ANCHORED >= 3 && !isMyres) { // 遠くても5メモと連鎖していれば通知する
- if (FUTABA_SET_56MEMO_TO_ANCHORED >= 3 && !isMyres && !hasAnyMemo) { // 遠くても5メモと連鎖していれば通知する
- //var relatedMemoO = getRelatedRsca(e?.closest("table")?.dataset?.rsc)?.find(rsc => (eleget0('.yhmMyMemoO', eleget0(`table[data-rsc="${rsc}"]`))))
- var [relatedMemoO, ] = getRelatedRsca(e?.closest("table")?.dataset?.rsc)
- relatedMemoO = relatedMemoO?.find(rsc => (eleget0(`.yhmMyMemoO[data-yhmc="${COLOR1}"]`, eleget0(`table[data-rsc="${rsc}"]`))))
- if (relatedMemoO && !tomemo.match("🔵")) {
- let res = eleget0(`blockquote`, eleget0(`table[data-rsc="${relatedMemoO}"]`))?.innerText
- res = res?.replace(/^\s*\>.*\s*$/gm, "")?.replace(/キタ━+\(゚\∀゚\)━+\!+/gm, "")?.trim() || res;
- tomemo = tomemo || text?.match0(/^\>[^\n]*/m) || "";
- tomemo += (tomemo ? "\n" : "");
- tomemo = (`>🔵distant:${res.split("\n")?.[0]}\n`) + tomemo;
- }
- }
-
- if (FUTABA_SET_56MEMO_TO_ANCHORED >= 4 && !isMyres) { // 遠くても6メモと連鎖していれば通知する
- var [relatedMemoO, ] = getRelatedRsca(e?.closest("table")?.dataset?.rsc)
- relatedMemoO = relatedMemoO?.find(rsc => (eleget0('.yhmMyMemoX', eleget0(`table[data-rsc="${rsc}"]`))))
- if (relatedMemoO && !tomemo.match("🔴")) {
- let res = eleget0(`blockquote`, eleget0(`table[data-rsc="${relatedMemoO}"]`))?.innerText
- res = res?.replace(/^\s*\>.*\s*$/gm, "")?.replace(/キタ━+\(゚\∀゚\)━+\!+/gm, "")?.trim() || res;
- tomemo = tomemo || text?.match0(/^\>[^\n]*/m) || "";
- tomemo += (tomemo ? "\n" : "");
- tomemo = (`>🔴distant:${res.split("\n")?.[0]}\n`) + tomemo;
- }
- }
- }
-
- let table = e.closest('table');
- var text = table?.textContent;
-
- let awMatch = GF?.alertWord > "" && text?.match0(GF?.alertWord) || text?.match0(new RegExp(GF?.alertWord.replace(/^S$/, "??").replace(/^S([\s \||])/, "??$1").replace(/([\s \||!!])S([\s \||])/, "$1??$2").replace(/([\s \||!!])S$/, "$1??").replace(/|/gm, "|").replace(/^[\!|!](\S*)/, "^(?!.*($1)).*").replace(/(\S*)[ ](\S*)/gm, "^(?=.*($1))(?=.*\($2\))").replace(/\s| /gm, ".*"), "i")); //alert(searRE); // 独自構文を正規表現に変換
- if (!isMyres && GF?.alertWord > "" && (e.offsetHeight && awMatch) && !eleget0('.yhmMyMemo', table)) {
- var path = eleget0('img', table)?.src
- if (FUTABA_SET_56MEMO_TO_ANCHORED) memoElement(e, document.body, COLOR_ALERT_WORD, getDefault56memo());
- if (awNotify++ < 3) notifyMe(eleget0("blockquote", table)?.textContent + "\n", `⚠️${awMatch}⚠️ ${GF?.originalDocTitle||document.title}`, () => setTimeout(() => scrRsc(e?.closest('table')?.dataset?.rsc), 150), path || null, true)
- if (FUTABA_NOTIFY_NEWRES_SOUND_MEMO_QUOTED.split(" ").includes("m")) sound("sawtooth", 0.025, 440)
- document.title = "⚠️" + document.title.replace(/^[■🔴🔵⚠️]+/g, "");
- } //else
-
- if (GF?.fromSecond) {
- // nキーのモードと条件にマッチすれば通知する
- if (!isMyres && (((GF?.reloadAndNotifyNewArrival >= 2 && tomemo) || (GF?.reloadAndNotifyNewArrival >= 3 && (tomemo || (e.offsetHeight && eleget0("img:not(.quoteSpeechBalloonImg),blockquote a,blockquote video", e.closest('table'))))) || (GF?.reloadAndNotifyNewArrival >= 4 && e.offsetHeight)) && (document.visibilityState !== "visible" || tomemo))) {
- var path = eleget0('img', e.closest('table'))?.src
- notifyMe(tomemo + eleget0('blockquote', e.closest('table'))?.innerText?.replace(/^>.*$/gm, "")?.trim(), tomemo.replace(/[^🔴🔵]/gm, "") + GF.originalDocTitle, () => setTimeout(() => scrRsc(e?.closest('table')?.dataset?.rsc), 150), path || null)
- if (tomemo.match("🔵")) {
- if (FUTABA_NOTIFY_NEWRES_SOUND_MEMO_QUOTED.split(" ").includes("5")) sound("square", 0.025, 880); // type:sine, square, sawtooth, triangleがある
- if (!document.hasFocus()) {
- GF.arrival = 1;
- document.title = "🔵" + document.title.replace(/^[■🔴🔵]+/g, "");
- }
- }
- if (tomemo.match("🔴")) {
- if (FUTABA_NOTIFY_NEWRES_SOUND_MEMO_QUOTED.split(" ").includes("6")) sound("square", 0.025, 220); // type:sine, square, sawtooth, triangleがある
- if (!document.title.match(/^[■🔴]*🔵/) && !document.hasFocus()) {
- GF.arrival = 1;
- document.title = "🔴" + document.title.replace(/^[■🔴]+/g, "");
- }
- }
- }
-
- if ((!GF?.arrival && document.visibilityState !== "visible") && (!GF?.reloadAndNotifyNewArrival || (GF?.reloadAndNotifyNewArrival && e.offsetHeight))) {
- GF.arrival = 1;
- document.title = `■${document.title}` //document.title = `■${GF.originalDocTitle}`
- }
- }
- /* if (FUTABA_SET_56MEMO_TO_ANCHORED >= 3 && !isMyres&&tomemo.match("🔵")) memoElement(e, document.body, COLOR6, getDefault56memo()); // 5メモへアンカーしたレスに6メモを付ける
- if (FUTABA_SET_56MEMO_TO_ANCHORED >= 4 && !isMyres&&tomemo.match("🔴")) memoElement(e, document.body, COLOR6, getDefault56memo()); // 6メモへアンカーしたレスに6メモを付ける
- */
- if (GF?.fromSecond) {
- if (FUTABA_SET_56MEMO_TO_ANCHORED >= 3 && !isMyres) { // 5メモへアンカーしたレスに6メモを付ける
- if (tomemo.match("🔵")) {
- memoElement(e, document.body, COLOR6, getDefault56memo());
- }
- }
- if (FUTABA_SET_56MEMO_TO_ANCHORED >= 4 && !isMyres) { // 6メモへアンカーしたレスに6メモを付ける
- if (tomemo.match("🔴")) {
- memoElement(e, document.body, COLOR6, getDefault56memo());
- }
- }
- }
-
- // }, 1 + (notifyDelay++) * 17, e)
- // setTimeout(()=>document.body.dispatchEvent(new CustomEvent('plzGKSI')),555)
- }, 1, e)
- })
- // GF.fromSecond = 1; // 初回は新着ではないのでやらない
-
- /* elegeta('.thre table tr:not([data-quospan])').forEach(e => {
- e.dataset.quospan = "1";
- e.insertAdjacentHTML("beforeend", `<td class="ignoreMe quo" style="position:relative;"><div class="ignoreMe memo"></div><div class="ignoreMe backlink"></div><div class="ignoreMe relallArea"> </div></td>`)
- })
- */
- // 逆引用を追加
- var issorted = eleget0('#sortType2') || eleget0('#sortType1')
- resEnum = [];
- cited = [];
- GF.anchor = new Array(1000).fill("")
-
- var resa = elegeta('.thre table .rtd:not(#pickbox .rtd,.ftbpu .rtd,#respopup_area .rtd)').sort((a, b) => { return (Number(a.dataset.rsc) - Number(b.dataset.rsc)) })
- elegeta(".revQuote:not(#pickbox .revQuote,.ftbpu .revQuote)").forEach(e => e?.remove())
-
- //test: 5578ms - タイマー終了 test: 5327ms - タイマー終了
- //elegeta('.thre table .rtd blockquote font:not(#pickbox font,.ftbpu font,#respopup_area font),.thre table .rtd blockquote p font:not(#pickbox font,.ftbpu font,#respopup_area font)').forEach((h, i) => { //緑文字の引用行文字列
- resa.map(v => elegeta('blockquote :is(font,p font)', v)).flat().forEach((h, i) => { //緑文字の引用行文字列
- var eWord = h.textContent.match(/^\>+(.+)$/)?.[1]; // >***の***部分 // oこれだと>>No.*への逆引用がつくのは「>No.*」と「No.*」の両方に逆引用がつく x本当にレスしている対象より前の初出のレスだけに逆引用がついてしまう
- //var eWord = h.textContent.match(/^\>(.+)$/)?.[1]; // >***の***部分 // xこれだと>>No.*への逆引用がつくのは「>No.*」だけになり「No.*」にはつかない o本当にレスしている対象より前のものだけに逆引用がついてしまう
- if (eWord) {
- //h.style.cursor="pointer" //これをやるとちょっとうるさい
- var greenResNo = h.closest('table').dataset.rsc; //緑文字列があるレスのレス番
- resa.filter(e => e.textContent.indexOf(eWord) !== -1).forEach((c, i) => { // c=***が含まれるレス
- let n = c.dataset.rsc; // ***が含まれるレスのレス番
- if (i === 0 && !(!resEnum[n] && n === greenResNo)) { // i==0つまりスレの初出のそれにしかヒットしない
- let r = eleget0(".relallArea", h.closest('table'))?.classList.add("relallAreaon") // >>100があったらrelallOn
- eleget0(".relallArea", c.closest('table'))?.classList.add("relallAreaon") // >あいう の対象レスが本当に存在したらrelallOn
- if (!resEnum[n]) resEnum[n] = []
- if (!resEnum[n].includes(greenResNo)) {
- resEnum[n].push(greenResNo)
- // end(c.parentNode.querySelector(".backlink"), `<font class="revQuote" data-resenum="${resEnum[n]}" data-rsc="${n}" onclick="scrRsc(${greenResNo})">>>${greenResNo}</font>`) //クリックで中心にスクロール
- end(c.parentNode.querySelector(".backlink"), `<font class="revQuote" data-resenum="${resEnum[n]}" data-rsc="${n}" onclick="scrRsc(${greenResNo})">>>${greenResNo}</font>`) //クリックで中心にスクロール
- // let memo = (eleget0('.yhmMyMemoO', c.closest('table'))) ? `>🔵${eWord}\n` : (eleget0('.yhmMyMemoX', c.closest('table'))) ? `>🔴${eWord}\n` : null;
- let memo = (eleget0(`.yhmMyMemoO[data-yhmc="${COLOR1}"]`, c.closest('table'))) ? `>🔵${eWord}\n` : (eleget0('.yhmMyMemoX', c.closest('table'))) ? `>🔴${eWord}\n` : null;
- if (memo) GF.anchor[h?.closest("table")?.dataset?.rsc] += memo
- }
- }
- })
- }
- })
-
- let fivechthumbnailetc = (!lh(/\.2chan\.net\//) || eleget0('#fivechthumbnailetc')) && 1
- // >No.○に本文の引用を追加 qsb::
- // if (FUTABA_QUOTE_LEAD_FOR_NUMBER_ONLY && fivechthumbnailetc) { //} || lh("ftbucket|kuzure")) {
- if (FUTABA_QUOTE_LEAD_FOR_NUMBER_ONLY) { //} || lh("ftbucket|kuzure")) {
- var quos = elegeta('.thre table .rtd blockquote font:not([data-quoted],#pickbox font,.ftbpu font,#respopup_area font),.thre table .rtd blockquote p font:not([data-quoted],#pickbox font,.ftbpu font,#respopup_area font)').filter(v => v.innerText.match(/>+No\.|>+\d|>+fu/))
- quos.filter(e => /^\>+No\.\d+$/m.test(e?.textContent)).forEach((e, i) => { //緑文字の引用行文字列
- e.dataset.quoted = 1
- let ecno = e?.textContent?.replace(/\D/g, "")
- var srcTable = elegeta("table .cno").find(v => v?.textContent?.replace(/\D/g, "") == ecno)?.closest("table[rsc]")
- if (srcTable && srcTable != e?.closest("table[rsc]")) {
- var origno = e?.textContent
- var lead = eleget0('blockquote', srcTable)?.innerText?.replace(/^\s*>+.*$/gm, "")?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.trim()
- if (!lead) lead = eleget0('blockquote', srcTable)?.innerText?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.trim()
- if (lead?.slice(33)?.length) lead = lead?.slice(0, 33)?.trim() + "…"
- lead = lead?.replace(/\n/gm, " ")
- if (lead) {
- // adja(e, "afterend", ` <span class="quoteSpeechBalloon" data-quoteno="${origno}"> >${lead} </span>`)
- fivechthumbnailetc && adja(e, "afterend", `<span class="quoteSpeechBalloon" data-quoteno="${origno}">>${lead}</span>`)
- }
- var srcImg = eleget0("img", srcTable)?.cloneNode()
- if (srcImg) {
- srcImg.removeAttribute("width")
- srcImg.removeAttribute("height")
- srcImg.dataset.quoteno = origno
- srcImg.className = "quoteSpeechBalloonImg"
- srcImg.removeAttribute("hspace")
- srcImg.removeAttribute("align")
- srcImg.dataset.zoomonhover = "disable"
- srcTable && e.appendChild(srcImg)
- }
- }
- })
- // >>○.jpgに本文の引用を追加 qsb::
- quos.filter(e => /^\>+\d+\.(jpg|jpeg|png|gif|bmp|webp|webm|mp4)$/m.test(e?.textContent)).forEach((e, i) => { //緑文字の引用行文字列
- e.dataset.quoted = 1
- let ertd = e?.textContent?.replace(/\>+/, "")
- var srcTable = elegeta("table .rtd").find(v => { return v?.textContent?.match(/\d+\.(jpg|jpeg|png|gif|bmp|webp|webm|mp4)/)?.[0] == ertd })?.closest("table[rsc]")
- if (srcTable && srcTable != e?.closest("table[rsc]")) {
- var origno = e?.textContent
- var lead = eleget0('blockquote', srcTable)?.innerText?.replace(/^\s*>+.*$/gm, "")?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.trim()
- if (!lead) lead = eleget0('blockquote', srcTable)?.innerText?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.trim()
- if (lead?.slice(33)?.length) lead = lead?.slice(0, 33)?.trim() + "…"
- lead = lead?.replace(/\n/gm, " ")
- var srcImg = eleget0("img", srcTable)?.cloneNode()
- if (lead) {
- // adja(e, "afterend", ` <span class="quoteSpeechBalloon" data-quoteno="${origno}"> >${lead} </span>`)
- fivechthumbnailetc && adja(e, "afterend", `<span class="quoteSpeechBalloon" data-quoteno="${origno}">>${lead}</span>`)
- }
- if (srcImg) {
- srcImg.removeAttribute("width")
- srcImg.removeAttribute("height")
- srcImg.dataset.quoteno = origno
- srcImg.className = "quoteSpeechBalloonImg"
- srcImg.removeAttribute("hspace")
- srcImg.removeAttribute("align")
- srcImg.dataset.zoomonhover = "disable"
- srcTable && e.appendChild(srcImg)
- }
- }
- })
- // >fu○.jpgに本文の引用を追加 qsb::
- quos.filter(e => /^\>+fu\d+\.(jpg|jpeg|png|gif|bmp|webp)$/m.test(e?.textContent)).forEach((e, i) => { //緑文字の引用行文字列 fu*
- e.dataset.quoted = 1
- let ertd = e?.textContent?.replace(/\>+/, "")
- var srcTable = elegeta("table .rtd").find(v => elegeta('img', v).find(w => w?.src?.indexOf(ertd) !== -1))?.closest("table[rsc]")
- if (srcTable && srcTable != e?.closest("table[rsc]")) {
- var origno = e?.textContent
- var lead = eleget0('blockquote', srcTable)?.innerText?.replace(/^\s*>*fu\S+\s*/gm, "")?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.trim()
- //if (!lead) lead = eleget0('blockquote', srcTable)?.innerText?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.trim()
- if (lead?.slice(33)?.length) lead = lead?.slice(0, 33)?.trim() + "…"
- lead = lead?.replace(/\n/gm, " ")
- var srcImg = elegeta('img', srcTable).find(w => w?.src?.indexOf(e?.textContent?.replace(/\>+/, "")) !== -1)?.cloneNode()
- if (lead) {
- // adja(e, "afterend", ` <span class="quoteSpeechBalloon" data-quoteno="${origno}"> >${lead} </span>`)
- fivechthumbnailetc && adja(e, "afterend", ` <span class="quoteSpeechBalloon" data-quoteno="${origno}">>${lead}</span>`)
- }
- if (srcImg) {
- srcImg.dataset.quoteno = origno
- srcImg.className = "quoteSpeechBalloonImg"
- srcImg.dataset.zoomonhover = "disable"
- srcTable && e.appendChild(srcImg)
- }
- }
- })
- }
-
- elegeta('.cnw a:not([data-popped]),.cnm a:not([data-popped])').forEach(e => {
- e.dataset.popped = 1;
- after(e, ` <span class="mailtoPopped">${sani(decodeURI(e?.href))}</span>`)
- }) // メール欄の中身を外に出す
- }
- autoPagerized(() => shikomi())
-
- // .relAllAreaon枠に連鎖レス数を書き入れていく
- if (FUTABA_EXPERIMENTAL_DISPLAY_CHAINED) {
- GF.resChained = []
- if (!GF.hasmemo) GF.hasmemo = new Set();
- clearTimeout(GF?.resChainTO);
- GF.resChainTO = setTimeout(() => reschain(), 4000)
- if (lh(".2chan.")) {
- // GF.resChainTO = document.body.addEventListener('2chanReloaded', () => setTimeout(reschain, 2000), false)
- document.body.addEventListener('2chanReloaded', () => {
- clearTimeout(GF?.resChainTO)
- GF.resChainTO = setTimeout(reschain, 2000)
- }, false)
- }
-
- function reschain(dash = null) {
- let stime = Date.now()
- let org
- if (!GF.resChained || !GF.resChained?.length) {
- GF.resChained = [...elegeta('.thre table:has(.yhmMyMemo) .relallAreaon:not([data-filled])').map(e => { GF.hasmemo.add(e); return e }), ...elegeta('.thre .relallAreaon:not([data-filled],.ftbpu .relallAreaon,#pickbox .relallAreaon)')]; // 最初はピックアップにあるものだけ最速でやる
- GF.resTotal = elegeta('.thre .rtd').length
- }
- do {
- stime = Date.now();
- do {
- org = GF.resChained.shift()
- } while (org && org?.dataset?.filled)
- if (org) {
- let rsc = org.closest('[data-rsc]')?.dataset?.rsc
- let [lists, overflow] = getRelatedRsca(rsc)
- lists?.forEach(v => {
- elegeta('table[data-rsc="' + v + '"] .relallAreaon').forEach(w => {
- w.innerText = `${lists?.length}${overflow?"+":""}`;
- w.dataset.filled = "1"
- if (debug) $(w).effect("highlight"); //org.areaonEle.scrollIntoView()
- })
- })
- }
- } while (org && GF.hasmemo.has(org))
- clearTimeout(GF?.resChainTO)
- //GF.resChainTO = setTimeout(reschain, (org || dash) ? ((GF?.resTotal || 9) * 1 + 100) : 60000)
- //document.title=`${Date.now()-st}`
- let next = (org || dash) ? 50 + (Date.now() - stime) * 3 : 60000;
- //console.log(next)
- GF.resChainTO = setTimeout(reschain, next)
- }
- }
-
- autoPagerized(() => {
- GF.stoppick = 1;
- memofast = 1;
- run(document.body, "observed");
- GF.stoppick = 0;
- memofast = false;
- plzGKSI()
- }, "not1st")
- // autoPagerized(() => shikomi())
- //GF.fromSecond = 1; // 初回は新着ではないのでやらない
-
- function plzGKSI() {
- clearTimeout(GF?.gksiAfterMemo);
- GF.gksiAfterMemo = setTimeout(() => document.dispatchEvent(new CustomEvent('plzGKSI')), 444)
- }
-
- GF.FUTABA_RELOAD_AND_NOTIFY_NEWRES_DEFAULT = pref("FUTABA_RELOAD_AND_NOTIFY_NEWRES_DEFAULT") || 0;
- // setTimeout(() => { for (let i = 0; i < GF.FUTABA_RELOAD_AND_NOTIFY_NEWRES_DEFAULT; i++) { keyFuncDispatch("n", "automation") } }, 444);
- SITE.keyFunc.find(v => v.key == "n")?.func("n", "automation", GF.FUTABA_RELOAD_AND_NOTIFY_NEWRES_DEFAULT)
- // setTimeout(() => { GF.FUTABA_RELOAD_AND_NOTIFY_NEWRES_DEFAULT; i++) { keyFuncDispatch("n", "automation") } }, 444);
-
- // autoPagerized((node) => {run()},"not1sttime")
-
- // onclick,html埋め込み,レス番,不安
- autoPagerized((node) => {
- // elegeta('blockquote font,.quoteSpeechBalloon,.quoteSpeechBalloonImg', node).filter(v => !v.onclick && (v?.dataset?.quoteno || /^>+/gm.test(v.textContent))).forEach(e => {//test: 1017ms - タイマー終了
- elegeta('blockquote font:not([onclick]),.quoteSpeechBalloon:not([onclick]),.quoteSpeechBalloonImg:not([onclick])', node).filter(v => /^>./gm.test(v.textContent?.trim())).forEach(e => { //test: 832ms - タイマー終了
- let etext = e?.dataset?.quoteno?.match(/^>(.+)$/)?.[1].trim() || e.textContent.replace(/^>/gm, "").trim()
- let r = [...document.querySelectorAll(".thre table")].find(v => v.textContent.indexOf(etext) !== -1) || null
- e.setAttribute("onclick", `scrRsc(${eleget0('.rsc', r)?.textContent})`) //クリックで中心にスクロール
- })
- })
-
- // レス番rscに引用・非引用が連鎖するレスのレス番rscを全て配列で返す rsc => [rsc,rsc,rsc,...]
- function getRelatedRsca(rsc) {
- let stime = Date.now()
- let tableRsc = elegeta('table[data-rsc]').sort((a, b) => a.dataset.rsc === b.dataset.rsc ? 0 : Number(a.dataset.rsc) > Number(b.dataset.rsc) ? 1 : -1) // レステーブル[登場順]
- let tableRscOrder = [] // レステーブル[rsc]
- tableRsc.forEach(v => tableRscOrder[v.dataset.rsc] = v) // 速度のためにキャッシュする
- let ress = getRelCno([rsc], tableRsc, tableRscOrder)
- let abort = 0;
- for (let i = 200; i--;) { //while (1) {
- let r = getRelCno(ress, tableRsc, tableRscOrder)
- // if (r.length >= 100 || r.length <= ress.length) { ress = r; break }
- if (r.length >= 100 || r.length <= ress.length) { ress = r; break; }
- if ((document.visibilityState == "visible" && Date.now() - stime > 2000)) {
- ress = r;
- abort = 1;
- }
- ress = r
- }
- if (ress?.length < 2) return [null, null];
- return [ress, abort];
- }
-
- function getRelCno(resa, tableRsc, tableRscOrder) {
- let a = resa || []
- resa.forEach(res => {
- a = a.concat(elegeta(`.quo .revQuote`, tableRscOrder[res]).map(v => v.innerText.replace(/^>>/, ""))) // test: 6137ms - タイマー終了
- let rscText = elegeta(`blockquote font[color="#789922"]`, tableRscOrder[res]).map(e => e?.innerText?.replace(/^>/, "")?.trim())
- rscText.forEach(v => a.push(tableRsc.find(w => w.innerText.indexOf(v) !== -1)?.dataset.rsc)) // 最初の1つめの>abcだけにヒット
- })
- return [...new Set(a?.flat())].filter(v => v !== undefined && v !== null).sort()
- }
-
- // 引用ホバー hover::
- GM_addStyle(".rtdAttract{background-color:#fed;}")
- if (location.href.match0(/ftbucket/) && !eleget0(`.csb`)) GM_addStyle(".rsc,.cnw,.cno{padding:0 0.5em 0 0;}")
- var latestHover;
- var latestlevel = 0
- var latestPU
-
- if (FUTABA_HOVER_POPUP_DELAY == -1) { document.addEventListener("mousemove", function(e) { hover() }, false); } else { hover_enter() }
-
- function hover_enter() {
- hover();
- setTimeout(hover_enter, 1 * 17);
- }
-
- function hover() {
-
- if (!replaceMainPopup) return;
- let ele = document.elementFromPoint(mousex, mousey);
- hovertimer++;
- if (ele !== latestHover) latestPU = 0
- if (ele && (FUTABA_HOVER_POPUP_DELAY || (ele && latestHover != ele))) {
- var quoteDesEle = ele.matches('table FONT,table .quoteSpeechBalloon,table .quoteSpeechBalloonImg,.relallArea') ? ele : null; //ホバーしている黄土色文字の要素群
- var hoverEle = quoteDesEle; //ele.tagName === "FONT" && ele.closest("table") ? [ele] : []; //ホバーしている黄土色文字の要素群
-
- let level = Number(ele.closest(".ftbpu")?.dataset.level || 0);
- var lists = []
- //if (debug) V&&dc("quoteDesEle:" + quoteDesEle?.tagName)
- if ((quoteDesEle && latestPU !== ele) && ((FUTABA_HOVER_POPUP_DELAY == 0 && latestHover != quoteDesEle) || (FUTABA_HOVER_POPUP_DELAY && hovertimer >= (Math.max(hoverEle?.closest('#pickbox,.ftbpu') && FUTABA_HOVER_POPUP_DELAY != -1 ? 6 : 0, FUTABA_HOVER_POPUP_DELAY))))) { // ピックアップの中では遅延を少なくとも6にする
- var eWord = quoteDesEle?.dataset?.quoteno?.match0(/^\>+(.+)$/)?.trim() || quoteDesEle?.textContent?.match0(/^\>+(.+)$/)?.trim(); // 引用文 // >の入れ子数を無視してすべて遡る
- //var eWord = quoteDesEle?.dataset?.quoteno?.match0(/^\>(.+)$/)?.trim() || quoteDesEle?.textContent?.match0(/^\>(.+)$/)?.trim(); // 引用文 // >の入れ子数を忠実に遡る
- var resa = elegeta('.rtd').filter(e => !e.closest("#pickbox,.ftbpu,#respopup_area"))
- var hit0no = (replaceMainPopup && resa.find(a => a.textContent && a.textContent.indexOf(eWord) != -1))?.dataset?.rsc; //ヒットした最初のレス番号
- if (hit0no < 0) return;
- var motoNumber = hoverEle.closest('table').getAttribute("rsc"); // ホバーしているレスのレス番号
-
- var hitResNo = hoverEle.dataset.rsc; // rscがある=レスの右側に追加した>>100型逆引用である、そのレス番号
- var relAll = ele.matches(".relallArea:not(.ftbpu .relallArea)") && ele?.closest("table")?.dataset?.rsc // …:全関連レス
-
- if (relAll) { // relall::…:全関連レスモード
- $(".ftbpu").remove();
- [lists, ] = getRelatedRsca(relAll)
- } else
-
- if (hitResNo) { // >>100:逆引用モード
- var lists = []
- resa?.forEach(c => { if (c.dataset.rsc == hitResNo) lists.push(c.closest("table").dataset.rsc) })
- resEnum[hitResNo]?.forEach(e => resa.forEach(c => { if (c.dataset.rsc == e) lists.push(c.closest("table").dataset.rsc) })); // rscがある=レスの右側に追加した逆引用である、そのレス番号
- } else {
- // レス本文内の引用
- if (motoNumber) {
- var quoteStr = eWord; //quoteDesEle?.textContent?.match0(/^\>+(.+)$/)?.trim(); // 文字列
- if (quoteStr) {
- var hitEles = resa.filter(e => e.textContent.indexOf(quoteStr) !== -1)
- if (hitEles.length) {
- var hoverResNo = (replaceMainPopup && hoverEle.getAttribute("rsc")) //ホバーしているレス番号
- //hits[0].classList.add("rtdAttract")
- var lists = hitEles.map(e => e.closest("table").dataset.rsc)
- }
- }
- }
- }
-
- // 表示
- if (hitResNo || lists) {
- latestPU = ele
- lists = lists.sort((a, b) => a - b)
- var hit0no = lists[0] //tables[0][0].getAttribute("rsc") //ヒットした最初のレス番号
- var restable = elegeta('.rtd:not(#pickbox .rtd,.ftbpu .rtd,#respopup_area .rtd)').map(e => e.closest("table"))
- var tables = lists.map(c => ($(restable.find(e => e.dataset.rsc == c)).clone(true, true))?.[0])
- var lists2 = (hit0no == motoNumber) ? lists.slice(1) : lists
- debug && dc(`list : ${lists}\nlist2 : ${lists2}`, 0)
- debug && dc("既存:" + elegeta('.ftbpu').find(e => lists == e.dataset.list || lists2 == e.dataset.list2 || lists == e.dataset.list2)?.dataset.list)
- if (
- !(elegeta('.ftbpu').find(e => lists == e.dataset.list || lists2 == e.dataset.list2 || lists == e.dataset.list2))
- ) { // まだ重複するポップアップがなければ
- debug && dc(`list-sorted : ${lists}`, 0)
- let pupad = (Math.min(window.screen.availWidth, window.screen.availHeight) || 1080) / FUTABA_POPUP_PADDING_RATE;
- var pu = $(`<span data-anchor="${hit0no}" class="ftbpu ${relAll?"relAll ":""}ignoreFilter entry-content" data-list="${lists}" data-list2="${lists2}" data-level="${1+Number(level)}" style="z-index:2000000020; padding:${pupad}px; box-shadow:2px 2px 15px #000a; border-radius:2px; background-color:${FUTABA_BGC}; margin:0 0em 0px 0px; outline:1px solid #999; position:absolute; top:${quoteDesEle.getBoundingClientRect().top + window.scrollY + quoteDesEle.getBoundingClientRect().height-1}px; left:0;" ondblclick="this.remove();"><table style="table-layout:auto;"></table></span>`); //ヒットした全部をポップアップする版
-
-
- if (!relAll && hit0no == motoNumber) { tables.shift() } // 1個目の引用が自分自身なら削除
- if (tables.length) {
- let frag = new DocumentFragment();
- tables.forEach(e => { frag.append(e) });
- [...frag.querySelectorAll('span[data-mbt]')].forEach(e => {
- $(e).css({ "display": "inline-block", "width": "fit-content" })
- $(e).after("<br>")
- })
- $(pu).append(frag)
-
- $(".thre:first()").append(pu)
- if (!relAll) $(pu).find(".quoteSpeechBalloon").remove()
- $(elegeta('.ftbpu table').filter(e => !gmDataList_includesPartial(e, "gmHideByyhm"))).fadeIn(300)
-
- domsort(pu[0], elegeta('table', pu[0]), v => -v.getAttribute("rsc"))
- sdset()
-
- $(".ftbpu .relallArea").remove()
- let xr = ((mousex - 18) >= (clientWidth() - $(pu).outerWidth() - 1))
- //$(pu).css({ "left": minmax(mousex - 18, 0, clientWidth() - $(pu).width() - 11) + "px" })
- $(pu).css({ "left": minmax(mousex - 18, 0, clientWidth() - $(pu).outerWidth() - 1) + "px" })
-
- // 少し縮小するか?
- let eleBottomY = $(quoteDesEle).offset().top - $(window).scrollTop() + $(quoteDesEle).outerHeight() + 1;
- let eleTopY = quoteDesEle.getBoundingClientRect().top // +window.scrollY;//gbcr $(quoteDesEle).offset().top - $(window).scrollTop() // + $(quoteDesEle).outerHeight() + 1;
- let puHeight = pu[0].getBoundingClientRect().height // offsetHeight //$(pu).outerHeight() // + 15;
- let bottomMargin = Math.min(window.innerHeight, document.documentElement.clientHeight) - eleBottomY
- let upMargin = (quoteDesEle.getBoundingClientRect().top)
- let originx = window.innerWidth - mousex
- // 画面の下のほうより上のほうが大きくあいていれば上に表示
- if (puHeight > bottomMargin && upMargin > puHeight) {
- $(pu).css({ "top": `${window.scrollY + eleTopY - puHeight}px` })
- } else {
- // 少し縮小する
- if (bottomMargin / puHeight < 1) $(pu).css({ "transform-origin": xr ? `${$(pu).outerWidth()-(window.innerWidth-mousex)+30}px -1px` : `0px -1px` }).delay(100).animate2({ "transform": `scale(${Math.max(futabapopupscale/100,bottomMargin/(puHeight))})`, "opacity": "1" }, 100) // 右が足りなければ縮小しない transform-originがtopleft=JQのdraggableが不具合起こさない
- }
-
- elegeta('.relpost').forEach(e => e.classList.remove("relpost"))
- elegeta(`table[data-rsc="${motoNumber}"] .rts`).forEach(e => e.classList.add("relpost"))
- clearTimeout(GF?.relpostID);
- GF.relpostID = setTimeout(() => elegeta('.relpost').forEach(e => e.classList.remove("relpost")), 2000)
- addstyle.add(`.relpost{ background-color:#dfc !important;}`)
- //addstyle.add(".relpost{animation: pulse1 1s infinite; } @keyframes pulse1 { 0% { background-color:#ffff0060; } 50% { background-color:#ffff0000; } 100% { background-color:#ffff0060; } }")
-
- // z使用モード
- GF?.zFunc && GF?.zFunc()
- dragElement(pu[0], "*", ".rtd,.yhmMyMemo,.revQuote")
- }
- }
- }
- } else {
- // if (!hoverEle && eleget0('.ftbpu') && !(ele.closest(".ftbpu") || ele.closest("#slp") || ele.closest(".fvw_respop") || eleget0("#pdm"))) {
- if (!hoverEle && eleget0('.ftbpu') && !(ele.closest(".ftbpu") || ele.closest("#slp") || ele.closest(".fvw_respop") || eleget0("#pdm") || ele.closest("#hzPv,.hzP"))) {
- $(".ftbpu").remove();
- $(".rtdAttract").removeClass("rtdAttract")
- elegeta('.relpost').forEach(e => e.classList.remove("relpost"))
- }
- if (latestHover != ele && ele.closest(".ftbpu,#slp,.fvw_respop")) { // levelが低い要素に降りたら上のは消す
- elegeta(".ftbpu").forEach(e => { if (e?.dataset?.level > level) { e.remove() } })
- }
- }
- }
- latestlevel = ele?.closest(".ftbpu")?.dataset?.level || 0
- latestHover = ele; //V&&dc("latest:"+latestHover?.tagName)
- }
-
- // pick::メモの付いたレスを右上に列挙
- var pick_overflow;
- GF.pickOFMaxH = 250;
- if (is2chan || isftb || isftchan || iskurokako || istsumanne) {
- var pick = (force = 0) => {
- if (GF.stoppick) return;
-
- if (eleget0('.thre table:has( :is(a[href*="youtube.com"],a[href*="youtu.be"],a[href*="nicovideo"],a[href*="//nico.ms/sm"]):not(#pickbox a,[yte],[nde],font[color="#789922"] a)):has( .yhmMyMemo)')) { // まだyt埋め込みしてないytリンクがあるならpickしない
- clearTimeout(GF.pickID);
- GF.pickID = setTimeout(() => pick(force), 999);
- return;
- }
- if (window.getSelection() == "" && $("#pickbox:hover").length == 0 && $('#pickbox:hidden').length == 0) {
- var res = [...new Set($.makeArray($('.thre table:has(span.yhmMyMemo):not([data-hidden="1"])')))].filter(e => !e.closest("#pickbox,.ftbpu")); // 埋め込み動画はロードが発生するので無視
- if (res.some(v => { let e = eleget0('.relallAreaon', v); return e && !e?.dataset?.filled })) {
- clearTimeout(GF.pickID);
- GF.pickID = setTimeout(() => pick(force), 999);
- return;
- } // まだ関連レス数が書き込まれていない.relallAreaonがあるなら待つ
- GF.presentPick = res
- let update = (GF.res !== JSON.stringify(res.map(e => e.innerText).sort()))
- if (update || force) {
- GF.res = JSON.stringify(res.map(e => e.innerText).sort())
- if (debug) popup2("更新:" + GF.res.slice(0, 200))
- if (!pick_overflow) {
- var p = eleget0('#pickbox:not(:hover)');
- if (p && p?.scrollHeight > p?.offsetHeight) {
- pick_overflow = 1;
- // GF.pickOFMaxH--;
- }
- }
- $("#pickbox").remove();
- $('#5chVerticalThreadTitle').remove()
- let threR = $('#rightadfloat:visible')[0] ? document.documentElement.clientWidth - ($(".thre").offset().left + $('.thre').outerWidth()) : 3
- if (res.length) {
- // let threR = $('#rightadfloat:visible')[0] ? document.documentElement.clientWidth - ($(".thre").offset().left + $('.thre').outerWidth()) : 3
- if (1 || document.documentElement.clientWidth - threR > 1300) {
- $.makeArray($(".thre")).filter(e => !e.closest("#pickbox,.ftbpu"))[0].insertAdjacentHTML("beforeend", `<div id='pickbox' class='ignoreFilter' floated="" style='z-index:1; max-height:calc(${(100)*(100/futabapicksize)}vh - ${8*(100/futabapicksize)}em) ; scrollbar-gutter: stable; scrollbar-width: thin; overflow-y:auto; max-width:${55}%; opacity:0.9; outline:2px #8888 solid; position:fixed; top:6px; right:${threR+2}px; background-color:#ffffeecc; transform:scale(${futabapicksize/100}); transform-origin:top right;'></div>`)
- let pickbox = eleget0("#pickbox")
-
- let frag = new DocumentFragment();
- res.forEach(e => { frag.append($(e).clone(true, true).css({ "display": "revert", "margin-left": "auto", "margin-right": "0" })[0]) })
- pickbox.append(frag)
-
- //res.forEach(e => { pickbox.appendChild($(e).clone(true, true).css({ "display": "revert", "margin-left": "auto", "margin-right": "0" })[0]) })
- //elegeta('.quoteSpeechBalloon', pickbox).forEach(e => { if (e?.textContent?.length > 18) { e.textContent = e.textContent.slice(0, 18) + "…" } })
- elegeta('.quoteSpeechBalloon', pickbox).forEach(e => { if (e?.textContent?.length > 16) { e.textContent = e.textContent.slice(0, 16) + "…" } })
- //$("#pickbox .sod:contains('x')").css({ "font-size": "125%", "float": "right" })
- $("#pickbox .sod:contains('x')").css({ "float": "right" })
- if (pick_overflow) {
- $("#pickbox img").css({ "width": "auto", "max-height": Math.max(50, GF.pickOFMaxH) + "px" });
- $("#pickbox blockquote").css({ "margin": "5px 40px" })
- }
- //$("#pickbox .relallAreaon").css({ "right": "1px", "position": "absolute", "bottom": "0" }) //,"z-index":"-1"})
- //$("#pickbox .relallAreaon").css({ "right": "1px", "position": "absolute" }) //,"z-index":"-1"})
- elegeta("#pickbox .relallAreaon").forEach(e => e.previousElementSibling.insertAdjacentElement('beforebegin', e))
- $("#pickbox .relallAreaon").css({ "float": "right", "margin": "4px 4px 0 0" }) //,"z-index":"-1"})
- elegeta("#pickbox .rts").forEach(e => { let no = e?.closest("table")?.dataset?.rsc; if (no) e.setAttribute("onclick", `scrRsc(${no})`); })
-
- $("#pickbox .revQuote").after("<br>"); //css({ "display": "inline-block" })
- $("#pickbox .yhmMyMemo,.revQuote").css({ "user-select": "none" })
- if (update) { $("#pickbox").css({ "outline": "#f00 5px solid" }).delay(100).queue(() => { $("#pickbox").css({ "outline": "2px #8888 solid" }) }) }
- domsort(pickbox, elegeta('table', pickbox).filter(e => e.closest("#pickbox")), v => -v.getAttribute("rsc"))
- sdset()
- GF?.zFunc && GF?.zFunc()
- dragElement(pickbox, "*", ".rts,.rtd,.yhmMyMemo,.relallArea,.revQuote")
- checkOF(1)
- }
- } else {
-
- //let threR = $('#rightadfloat:visible')[0] ? document.documentElement.clientWidth - ($(".thre").offset().left + $('.thre').outerWidth()) : 3
- $(document.body).append(`<div id="5chVerticalThreadTitle" style="writing-mode: vertical-rl; top:2em; bottom:3em; right:${threR+16}px; position:fixed;z-index:-111; font-size:2.5em; opacity:0.5; color:#800;">${GF.originalDocTitle?.substr(0,63)}</div>`);
- // $(eleget0('//ul/li[@class="menubottomnav"]/a[@class="menuitem" and text()="全部"]/../../..')).before(`<span id="bottomDocTitle" style=" margin:0 0 0 0.2em;font-size:1.5em; opacity:0.9; color:${serverColor};">${document.title}</span>`);
- }
- pick2title(20)
- }
- }
- setTimeout(() => pick(), 2000)
- }
- setTimeout(pick, 2000)
-
- function checkOF(force = 0) {
- if (Date.now() - GF?.resized < 100) return; // リサイズ直後はしない(resizeイベントが複数回起こってガクガクするため)
- if (futabapicksize == futabapicksizeL && GF.pickOFMaxH <= 50 && !force) return;
- var p = eleget0('#pickbox:not(:hover)')
- if (p) {
- var lr = elegeta('.rtd')?.filter(e => isinscreen(e, 1) && !e?.closest("#pickbox,.ftbpu,#respopup_area,[floated]"))?.map(e => { let r = e.getBoundingClientRect().right; return e?.closest('table')?.querySelector('.revQuote,.relallArea')?.getBoundingClientRect()?.right + 4 || r + 2 }).reduce((a, b) => a > b ? a : b, 0) || 0 //test 175 / 1sec
- var big = p.getBoundingClientRect().left - lr
- var bigabs = Math.abs(big)
- if (p.scrollHeight > p.offsetHeight) {
- $("#pickbox blockquote").css({ "margin": "5px 40px" })
- GF.pickOFMaxH = GF.pickOFMaxH - ~~(p.scrollHeight - p.offsetHeight) / 8;
- $("#pickbox img").css({ "width": "auto", "max-height": Math.max(50, GF.pickOFMaxH) + "px" });
- futabapicksize = Math.max(futabapicksizeL, futabapicksize - (p.scrollHeight - p.offsetHeight) / 62);
- if (pick_overflow != 1) {
- pick_overflow = 1
- pick(1);
- } else {
- pick_overflow = 1;
- p.style.transform = `scale(${futabapicksize/100})`
- p.style.maxHeight = `calc(${(100)*(100/futabapicksize)}vh - ${8*(100/futabapicksize)}em)`;
- debug && dc("picksize:" + futabapicksize, 1)
- }
- } else if (big < 0) {
- futabapicksize = Math.max(futabapicksizeL, futabapicksize - bigabs / 62);
- p.style.transform = `scale(${futabapicksize/100})`
- debug && dc("picksize:" + futabapicksize, 1)
- }
- }
- }
- setInterval(checkOF, 52)
- //}, 60)
-
- window.addEventListener('resize', () => {
- GF.resized = Date.now()
- futabapicksize = 100;
- if (!eleget0('#pickbox iframe')) {
- GF.pickOFMaxH = 250;
- pick_overflow = 0;
- $("#pickbox").remove();
- pick(1);
- //checkOF();
- return;
- }
- var p = eleget0('#pickbox:not(:hover)')
- if (p) {
- p.style.transform = `scale(${futabapicksize/100})`
- p.style.maxHeight = `calc(${(100)*(100/futabapicksize)}vh - ${8*(100/futabapicksize)}em)`;
- GF.pickOFMaxH = 250;
- $("#pickbox img").css({ "width": "auto", "max-height": Math.max(50, GF.pickOFMaxH) + "px" });
- //checkOF();
- }
- // pick(1)
- })
-
- //window.addEventListener('focus', () => { futabapicksize = 100; pick(1) }) // ややうるさい
-
- setTimeout(() => {
- let slider = eleget0('#pickbox') ? [eleget0('/HTML/BODY/HR[2]'), "style=' position:fixed; right:8em; bottom:0.5em; font-size:11px; transform:scale(0.9); display:block;'", "style=' position:fixed; right:20em; bottom:0.5em; font-size:11px; transform:scale(0.9); display:block;'"] : [eleget0(`//span[@id="hml"]/..`), "style='float:left; font-size:13px; transform:scale(0.9);'", "style='float:left; font-size:13px; transform:scale(0.9);'"]
-
- setSlider(slider[0], 30, 100, futabapicksizeDefault, "ピックアップの最小スケール:***%", "FUTABA_pickupSize", (val) => {
- futabapicksizeL = val;
- futabapicksize = Math.min(100, ++futabapicksize);
- pick(1);
- }, 0, slider[1])
-
- setSlider(slider[0], 50, 100, 95, "ポップアップの最小スケール:***%", "FUTABA_popupScale", (val) => { futabapopupscale = val; }, 1, slider[2]);
- }, 2100)
- }
-
- function pick2title(len) {
- var suff = document.title.match0(/(\s-\s.*)/) || ""
- let intro = [...new Set(elegeta('.thre>blockquote,table[data-reszero] blockquote,#pickbox blockquote')?.slice(0, len)?.map(e => e?.innerText))]?.map(e => e?.replaceAll("キタ━━━(゚∀゚)━━━!!", "")?.replace(/\n/gm, " "))
- intro = intro?.join(" ")?.replace(/[ \s\u200B-\u200D\uFEFF\u2028\u2029\u200eㅤ]{1,99}/g, " ")
- // if ((isftb || isftchan || is2chan) && intro && suff) { // 0とpickのレス100文字までページタイトルにする
- if ((isftb || isftchan || is2chan) && intro) { // 0とpickのレス100文字までページタイトルにする
- let threno = location?.href?.match0(/(\d{3,})/) || ""
- if (intro && !GF?.arrival) {
- document.title = `${(GF.originalDocTitle0+" "+threno+" - "+intro)?.slice(0, 94)}`
- }
- }
- }
- },
- },
- {
- id: 'www.uniqlo.com',
- urlRE: '//www.uniqlo.com/',
- listTitleXP: '//a/div[2]/h3',
- listTitleSearchXP: '//a/div[2]/h3[+++]/../../..',
- listTitleMemoSearchXP: '//a/div[2]/h3[+++]|//h1[@data-test="product-name"][+++]',
- listGen: 6,
- redoWhenReturned: 1,
- delay: 500,
- observe: 500,
- detailURLRE: /\/www.uniqlo.com\/jp\/ja\/products\//,
- detailTitleXP: '//h1[@data-test="product-name"]',
- detailTitleSearchXP: '//h1[@data-test="product-name"][+++]/../../..',
- urlHasChangedCommonFunc: () => {
- setTimeout(() => {
- isDetail = (SITE.detailURLRE && location.href.match(SITE.detailURLRE)) ? 1 : 0;
- run(document.body)
- }, 2000);
- },
- },
- {
- id: 'workman',
- urlRE: '//workman.jp/shop/',
- listTitleXP: '//div[@class="block-thumbnail-t--goods-name"]/a|.//div[@class="_wrap"]/div[@class="_title"]/a',
- listTitleSearchXP: '//div[@class="block-thumbnail-t--goods-name"]/a[+++]/../../..|.//div[@class="_wrap"]/div[@class="_title"]/a[+++]/../../..',
- listTitleMemoSearchXP: '//div[@class="block-thumbnail-t--goods-name"]/a[+++]|//h1[@class="h1 block-goods-name--text js-enhanced-ecommerce-goods-name"][+++]|.//div[@class="_wrap"]/div[@class="_title"]/a[+++]',
- listGen: 4,
- observe: 500,
- detailURLRE: /shop\/g\//,
- detailTitleXP: '//h1[@class="h1 block-goods-name--text js-enhanced-ecommerce-goods-name"]',
- detailTitleSearchXP: '//h1[@class="h1 block-goods-name--text js-enhanced-ecommerce-goods-name"][+++]/../../../..',
- },
- {
- id: 'free.arinco.org',
- urlRE: 'http://free.arinco.org/mail/index1.html',
- listTitleXP: '//a',
- redoWhenRefocused: 1,
- useURL: 1,
- listTitleMemoSearchXPSameGen: 1,
- listGen: 4,
- listTitleSearchXP: '//a[++url++]/..',
- listTitleMemoSearchXP: '//a[++url++]',
- },
- {
- id: 'free.arinco.org',
- urlRE: '//free.arinco.org/',
- useURL: 1,
- redoWhenRefocused: 1,
- listTitleMemoSearchXPSameGen: 1,
- listGen: 4,
- listTitleXP: '//a|//h1/span[@itemprop="name"]',
- listTitleSearchXP: '//a[**url**]/..|//h1/span[@itemprop="name"][**url**]',
- listTitleMemoSearchXP: '//a[**url**]|//h1/span[@itemprop="name"][**url**]',
- detailURLRE: /\/mail\//,
- detailTitleXP: '//h1/span[@itemprop="name"]',
- detailTitleSearchXP: '//h1/span[@itemprop="name"][**url**]',
- funcOnlyFirst: function() {
- GM_addStyle('.itemlist li{height:auto; margin:0.5em;}');
- var e = location.href.replace(/^https?:\/\/free.arinco.org\/mail\/([^/]+\/)$/, "$1");
- var t = eleget0('//h1/span[@itemprop="name"]')
- if (document.body.innerText.match(/ホーム » Free Mail » /) && e && t) t.setAttribute("href", e)
- },
- automemoURLRE: /^https?:\/\/free.arinco.org\/mail\/[^/]+\/$/, // メールサービス名にホバーしないと作られない
- automemoSearchFunc: function() { return eletext(['//article[@role="main"]/section[@id="detail"]', '//div[@id="main"]/article/section[1]']); },
- automemoFunc: function() {
- // [/(imap)/im, /(pop3)/mi, /(Tor)/m, /(e2ee)/m, /(openpgp)|(gnupgp)|(pgp)/mi].forEach(m => autoMemo(m));
- [/(imap)/im, /(pop3)/mi, /(Tor)/m, /(e2ee)/m, /(openpgp)|(gnupgp)|(gpg)|(pgp)/mi].forEach(m => autoMemo(m));
- },
- automemoForceFunc: function() { return 1; },
- /* autoTranslucentURLRE: /^https?:\/\/free.arinco.org\/mail\/[^/]+\/$/, // urlだけでは詳細概要画面を特定できない
- detailURLRE: /^https?:\/\/free.arinco.org\/mail\/.+/,
- detailTitleXP: '//h1/span[@itemprop="name"]',
- detailTitleSearchXP: '//h1/span[@itemprop="name"][**url**]/../../../..',
- automemoURLRE: /^https?:\/\/free.arinco.org\/mail\/[^/]+\/$/,
- automemoSearchFunc: () => { return eletext(['//article[@role="main"]/section[@id="detail"]']); },
- automemoFunc: () => {
- [/(imap)/im,/(pop3)/mi,/(openpgp)|(gnupgp)|(pgp)/mi].forEach(m => autoMemo(m));
- },
- */
- },
- {
- id: 'twiman.net',
- urlRE: '//twiman.net/',
- listTitleXP: '//div[@class="v-list-item__content"]/div[2]',
- listTitleSearchXP: '//div[@class="v-list-item__content"]/div[2][***]/../../../..',
- listTitleMemoSearchXP: '//div[@class="v-list-item__content"]/div[2][***]/../..',
- listGen: 7,
- observe: 500,
- trim: 1,
- },
- {
- id: 'twicomi.com',
- urlRE: '//twicomi.com',
- trim: 1,
- title: 'div.screen-name,div.fixed-tweet>div:nth-child(3),span.screen-name,div.tweet-text',
- box: 'div.author-profile,.fixed-area,div.manga-item',
- forceTranslucentFunc: e => e.closest('div.author-profile,.fixed-area'),
- autoTranslucentURLRE: /\/\/twicomi\.com\/manga\//,
- XP2name: 'ユーザー名 ',
- listTitleXP2: 'div.screen-name,span.screen-name',
- listGen: 8,
- observe: 500,
- redoWhenReturned: 1,
- func: () => { $('.list').css({ "min-height": "0px" }) }, // AP継ぎ足し時の空白を詰める
- funcOnlyFirst: () => {
- var observeUrlHasChangedhref = location.href;
- var observeUrlHasChanged = new MutationObserver(mutations => {
- if (observeUrlHasChangedhref !== location.href) {
- pauseAll = 1;
- prefCacheClear()
- observeUrlHasChangedhref = location.href;
- elegeta('//span[contains(@class,"yhmMyMemo")]/..').forEach(e => e.remove());
- setTimeout(() => {
- pauseAll = 0;
- $(".phov2").remove();
- $('span.phov').remove();
- // elegeta('//div[@class="fixed-area"]/div[@class="fixed-tweet"]/div[@class="text"]/..').forEach(e => e.style.opacity = "1")
- elegeta('div.author-profile,.fixed-area', ).forEach(e => e.style.opacity = "1")
- disableHide = (SITE.autoTranslucentURLRE && location.href.match(SITE.autoTranslucentURLRE)) || (pref("translucent") == "on");
- run(document.body, "returned")
- }, 100);
- }
- });
- observeUrlHasChanged.observe(document, { childList: true, subtree: true });
- },
- },
- {
- id: 'chrome.google.com/webstore/search/',
- urlRE: '//chrome.google.com/webstore/search/|//chrome.google.com/webstore/detail/',
- listTitleXP: '//div[@class="a-na-d-w" and @role="heading"]',
- listTitleSearchXP: '//div[@class="a-na-d-w" and @role="heading"][+++]/../../../../../..',
- listTitleMemoSearchXP: '//div[@class="a-na-d-w" and @role="heading"][+++]|.//div[@class="e-f-n-Va"]/div[@class="e-f-w-Va"]/h1[@class="e-f-w"][+++]',
- listGen: 7,
- delay: 2500,
- observe: 500,
- redoWhenReturned: 1,
- detailURLRE: /https:\/\/chrome.google.com\/webstore\/detail\//,
- detailTitleXP: '//div[@class="e-f-n-Va"]/div[@class="e-f-w-Va"]/h1[@class="e-f-w"]',
- detailTitleSearchXP: '//div[@class="e-f-n-Va"]/div[@class="e-f-w-Va"]/h1[@class="e-f-w"][+++]/../../../..',
- listTitleMemoSearchXPSameGen: 1,
- },
- {
- id: 'sakura-checker.jp',
- urlRE: '//sakura-checker.jp/category/',
- listTitleXP: '//div[1]/figure/a',
- listTitleSearchXP: '//div[1]/figure/a[++url++]/../../..',
- listTitleMemoSearchXP: '//div[1]/figure/a[++url++]',
- listGen: 5,
- listHelpXP: '//div[1]/figure/a/../../..',
- useURL: 1,
- },
- {
- id: 'BOOTH.PM', // 作者名でQ/1/2 出品者名でQ
- urlRE: 'https:\/\/booth\.pm\/ja\/browse/|https:\/\/booth\.pm\/ja\/items|https:\/\/booth.pm\/ja$|https:\/\/booth\.pm\/ja\/events\/|https:\/\/booth\.pm\/ja\/search\/',
- listHelpXP: '//a[@class="item-card__title-anchor nav"]/../../../..|.//a[@class="item-card__title-anchor--multiline nav"]/../../../..',
- listTitleXP: '//a[@class="item-card__title-anchor nav"]|.//a[@class="item-card__title-anchor--multiline nav"]',
- listTitleXP2: '//div[@class="item-card__shop-name"]|//div[@class="u-text-ellipsis"]|//a[@class="nav u-tpg-title2"]',
- XP2memo: 1,
- XP2name: '出品者名 ',
- listTitleSearchXP: '//a[@class="item-card__title-anchor nav"][+++]/../../../..|//div[@class="item-card__shop-name"][+++]/../../../../../..|.//a[@class="item-card__title-anchor--multiline nav"][+++]/../../../..',
- listTitleMemoSearchXP: '//a[@class="item-card__title-anchor nav"][+++]|//header/h2[@class="u-text-wrap u-tpg-title1 u-mt-0 u-mb-400"][+++]|.//a[@class="item-card__title-anchor--multiline nav"][+++]|.//div[@class="item-card__shop-name"][+++]|.//div[@class="u-text-ellipsis"][+++]|//a[@class="nav u-tpg-title2"][+++]',
- listGen: 7,
- detailURLRE: /https:\/\/booth\.pm\/ja\/items\//,
- detailTitleXP: '//header/h2[@class="u-text-wrap u-tpg-title1 u-mt-0 u-mb-400"]',
- detailTitleSearchXP: '//header/h2[@class="u-text-wrap u-tpg-title1 u-mt-0 u-mb-400"][+++]/../../../../../../../..|//div[@class="u-text-ellipsis"][+++]/../../../../../../../..',
- redoWhenReturned: 1,
- hideListEvenDetail: 1,
- },
- {
- id: 'TOODORAN',
- urlRE: '//todo-ran.com/t/soukan/',
- listTitleXP: '//td/a[1]',
- listTitleSearchXP: '//td/a[1][+++]/../..',
- listTitleMemoSearchXP: '//td/a[1][+++]',
- listGen: 3,
- listTitleMemoSearchXPSameGen: 1,
- },
- {
- id: '2CHTHREADLIST',
- urlRE: /\/\/ff5ch\.syoboi\.jp\/\?q=/,
- title: 'a.thread,a.col-brd',
- titleSubstr: true,
- box: 'li.bdr-b',
- listTitleXP2: 'a.col-brd',
- XP2name: `板名 `,
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- var sorttype = GF.yhmSortType || 0
- let menu = [
- { t: "タイトル", f: () => { sortdom(elegeta('li.bdr-b'), v => eleget0('a.thread', v)?.textContent) } },
- { t: "板名", f: () => { sortdom(elegeta('li.bdr-b'), v => eleget0('a.col-brd', v)?.textContent + eleget0('.board_title span', v)?.textContent) } },
- { t: "レス数", f: () => { sortdom(elegeta('li.bdr-b'), v => eleget0('span.fnt-small.col-sec', v)?.textContent, 1) } },
- { t: "新しい", f: () => { sortdom(elegeta('li.bdr-b'), v => eleget0('//div[@class="fnt-small col-sec m-tb-4"]/span', v)?.textContent, 1) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- }, {
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- }],
- },
- {
- id: 'MSDMANUAL', // 検索結果と詳細ページでは項目名に表記ゆれがあるので合致しない
- urlRE: '//www.msdmanuals.com/',
- listTitleXP: '//div/a[@class="search__result--title"]',
- listTitleSearchXP: '//div/a[@class="search__result--title"][+++]/../../..',
- listTitleMemoSearchXP: '//div/a[@class="search__result--title"][+++]|//h1[@class="topic__header__headermodify--title topic__header__headermodify--title--animate"][+++]',
- listGen: 3,
- delay: 2000,
- observe: 500,
- detailURLRE: /^(?!.*(SearchResults)).*/,
- detailTitleXP: '//h1[@class="topic__header__headermodify--title topic__header__headermodify--title--animate"]',
- detailTitleSearchXP: '//h1[@class="topic__header__headermodify--title topic__header__headermodify--title--animate"][+++]/../../../../../..',
- },
- {
- id: 'CHIEBUKURO',
- urlRE: '//chiebukuro.yahoo.co.jp/',
- // urlRE: /\/\/chiebukuro.yahoo.co.jp\/|\/\/detail.chiebukuro.yahoo.co.jp\//,
- listTitleXP: '//div/a/div/div/div/div/h2/../../../../..',
- listTitleSearchXP: '//article/div/a/div/div/div/div/h2/../../../../..[++url++]/../..',
- listTitleMemoSearchXP: '//article/div/a[++url++]/div/div/div/div/h2',
- listGen: 9,
- useURL: 1,
- redoWhenReturned: 1,
- },
- {
- urlRE: 'https://refind2ch.org/search',
- id: '2CHTHREADLIST',
- title: 'p.list-group-item-heading.thread_title,p.board_title span',
- box: '#search_results a.thread_url.list-group-item.entry.board_border',
- /* listTitleXP: '//p[contains(@class,"thread_title")]',
- listTitleXP2: '//p/span[@class="board_clr_font_shitaraba"]|.//p/span[@class="board_clr_font_2chnet"]', // おーぷん板名は重複'|//p/span[@class="board_clr_font_open2chnet"]',
- XP2name: '板 ',
- listTitleSearchXP: '//p[contains(@class,"thread_title")][***]/../..|.//p/span[@class="board_clr_font_shitaraba"][***]/../../..|.//p/span[@class="board_clr_font_2chnet"][***]/../../..', //'|//p/span[@class="board_clr_font_open2chnet"][+++]/../../..',
- listTitleMemoSearchXP: '//p[contains(@class,"thread_title")][***]',
- listGen: 4,
- */
- observe: 500,
- redoWhenReturned: 1,
- XP2name: '板名 ',
- listHelpXP2: '.board_title span',
- trim: 1,
- //titleProcessFunc: (title) => { return title.replace(/\s\(したらば\)/gmi, "") },
- WhateverFirstAndEveryAPFunc: () => {
- $(".side_box").css({ "height": "100vh" });
- popup3("Shift+F:re.Find2ch検索", 8, 5000)
- },
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- var sorttype = GF.yhmSortType || 0
- let menu = [
- { t: "タイトル", f: () => { sortdom(elegeta('#search_results a.thread_url.list-group-item.entry.board_border'), v => eleget0('p.list-group-item-heading.thread_title', v)?.textContent) } },
- { t: "板名", f: () => { sortdom(elegeta('#search_results a.thread_url.list-group-item.entry.board_border'), v => eleget0('p:last-child span small', v)?.textContent + eleget0('.board_title span', v)?.textContent) } },
- { t: "新しい", f: () => { sortdom(elegeta('#search_results a.thread_url.list-group-item.entry.board_border'), v => eleget0('.date_raw,.date', v)?.textContent, 1) } },
- { t: "勢い", f: () => { sortdom(elegeta('#search_results a.thread_url.list-group-item.entry.board_border'), v => eleget0('.rate_cnt', v)?.textContent, 1) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- }, {
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- }],
- func: (node = document) => { // 高密度化&https化
- elegeta('//div/div[@class="container-fluid"]').forEach(e => {
- e.style.width = "95%";
- e.style.maxWidth = "100%";
- })
- elegeta('//div[@id="content_main"]').forEach(e => {
- e.style.width = "calc(95vw - 400px)";
- e.style.maxWidth = "100%";
- })
- elegeta('//div[@class="progress rate pull-right"]').forEach((e) => { e.style.width = "5%" });
- for (let element of elegeta('//div[@class="clearfix"]|//a[contains(@class,"thread_url list-group-item entry clearfix board_border board_clr_border_2chnet") and @target="_blank" and @rel="nofollow noreferrer"]/p')) {
- element.parentNode.href = element.parentNode.href.replace(/http:\/\//, "https://");
- element.style = "display:inline;float:left; margin:0px 0.0em; padding:0px 0.5em 0px 0.5em;";
- }
- for (let element of elegeta('//a[@rel="nofollow noreferrer"]')) { element.style = "padding:0px;"; }
- elegeta('//div[@id="content_main"]/div[@id="search_results"]/a', node).forEach(e => { e.setAttribute("onclick", "") })
- elegeta('div>small.pull-right', node).forEach(e => {
- e.style = "float:none !important";
- e.parentNode.parentNode.appendChild(e);
- });
- },
- },
- {
- id: 'KAKAKUBB',
- urlRE: '//kakaku.com/bb/',
- listTitleXP: '//a[@class="planName"]',
- listTitleSearchXP: '//a[@class="planName"][+++]/../../../../..',
- listTitleMemoSearchXP: '//a[@class="planName"][+++]',
- listGen: 3,
- },
- {
- id: 'MINSOKU',
- urlRE: '//minsoku.net/',
- listTitleXP: '//div/div[@class="text-bold mt-xxs"]/a|.//div/div[@class="mt-10 text-bold"]/a|.//div[@class="mt-10 mb--xxxs text-bold"]/a',
- listTitleSearchXP: '//div/div[@class="text-bold mt-xxs"]/a[+++]/../../..|.//div/div[@class="mt-10 text-bold"]/a[+++]/../../..|.//div[@class="mt-10 mb--xxxs text-bold"]/a[+++]/../../..',
- listTitleMemoSearchXP: '//div/div[@class="text-bold mt-xxs"]/a[+++]|.//div/div[@class="mt-10 text-bold"]/a[+++]|.//div[@class="mt-10 mb--xxxs text-bold"]/a[+++]',
- listGen: 4,
- },
- {
- id: 'OMOCORO',
- urlRE: '//omocoro.jp/',
- listTitleXP: '//div[@class="details"]/div[@class="title"]/a',
- listTitleSearchXP: '//div[@class="details"]/div[@class="title"]/a[+++]/../../..',
- listTitleMemoSearchXP: '//div[@class="details"]/div[@class="title"]/a[+++]',
- listGen: 4,
- },
- {
- id: '360life.shinyusha.co.jp',
- urlRE: '//360life.shinyusha.co.jp/',
- listTitleXP: '//article/div[@class="m-article-item__info"]/h3[@class="m-article-item__title"]',
- listTitleSearchXP: '//article/div[@class="m-article-item__info"]/h3[@class="m-article-item__title"][***]/../../../..',
- listTitleMemoSearchXP: '//article/div[@class="m-article-item__info"]/h3[@class="m-article-item__title"][***]|//div[@class="article-header"]/h1[@class="article-header__title"][***]',
- listGen: 4,
- detailURLRE: /\/\/360life\.shinyusha\.co\.jp\/articles\//,
- detailTitleXP: '//div[@class="article-header"]/h1[@class="article-header__title"]',
- detailTitleSearchXP: '//div[@class="article-header"]/h1[@class="article-header__title"][***]/../../../../..',
- redoWhenReturned: 1,
- trim: 1,
- },
- {
- id: 'SHOPPING_YAHOO',
- urlRE: '//shopping.yahoo.co.jp/search',
- listTitleXP: '//div[2]/p/a[@target="_blank" and @data-rapid_p="1"]/span',
- listTitleSearchXP: '//div[2]/p/a[@target="_blank" and @data-rapid_p="1"]/span[+++]/../../../../..',
- listTitleMemoSearchXP: '//li[@class="LoopList__item"]/div/div[2]/p/a[@target="_blank" and @data-rapid_p="1"]/span[+++]',
- listGen: 6,
- func: () => { // 商品名を省略しなくする
- elegeta('//div[2]/p/a[@target="_blank" and @data-rapid_p="1"]/span/..').forEach(e => {
- e.style.display = "block";
- e.style.maxHeight = "none";
- });
- },
- observe: 1000,
- },
- {
- id: 'FREEM',
- urlRE: '//www.freem.ne.jp/',
- listTitleXP: '//a/h3[@class="pc"]',
- listTitleSearchXP: '//ul[contains(@class,"game-list game-list-wrap row")]/li/a/h3[@class="pc"][+++]/../..',
- listTitleMemoSearchXP: '//ul[contains(@class,"game-list game-list-wrap row")]/li/a/h3[@class="pc"][+++]',
- listGen: 3,
- },
- {
- id: 'ONSEN',
- urlRE: '//www.onsen.ag/',
- listTitleXP: '//h4[@class="title"]',
- listTitleSearchXP: '//h4[@class="title"][+++]/../..',
- listTitleMemoSearchXP: '//h4[@class="title"][+++]',
- listGen: 4,
- observe: 500,
- },
- {
- id: 'HIBIKI',
- urlRE: '//hibiki-radio.jp',
- listTitleXP: '//div[@class="title program-title-animate ng-binding"]',
- listTitleSearchXP: '//div[@class="title program-title-animate ng-binding"][+++]/../../..',
- listTitleMemoSearchXP: '//div[@class="title program-title-animate ng-binding"][+++]',
- listGen: 3,
- observe: 500,
- },
- {
- id: 'GOOGLE_SCHOLAR',
- urlRE: '//scholar\.google\..*/',
- listTitleXP: '//h3[@class="gs_rt"]/a',
- listTitleSearchXP: '//h3[@class="gs_rt"]/a[++url++]/../../..',
- listTitleMemoSearchXP: '//h3[@class="gs_rt"]/a[++url++]',
- listGen: 3,
- useURL: 1,
- disableKeyB: 1,
- },
- {
- id: 'NICODOUGA',
- urlRE: '//commons.nicovideo.jp/',
- listTitleXP: '//a[@class="title_link"]',
- listTitleSearchXP: '//a[@class="title_link"][+++]/..',
- listTitleMemoSearchXP: '//a[@class="title_link"][+++]', // ちゃんと動かない
- listGen: 2,
- observe: 500,
- },
- {
- id: 'RRWS',
- urlRE: '//rrws.info/',
- listTitleXP: '//h2[@class="entry-card-title card-title e-card-title"]',
- listTitleSearchXP: '//h2[@class="entry-card-title card-title e-card-title"][***]/../../..',
- listTitleMemoSearchXP: '//h2[@class="entry-card-title card-title e-card-title"][***]|//h1[@class="entry-title"][***]',
- listGen: 3,
- detailURLRE: /rrws.info\/archives\//,
- detailTitleXP: '//h1[@class="entry-title"]',
- detailTitleSearchXP: '//h1[@class="entry-title"][***]/../..',
- trim: 1,
- },
- {
- id: 'A-TIMESALE',
- urlRE: '//a-timesale.com/',
- listTitleXP: '//div[3]/div[@class="border-b pb-3 mb-4"]/a[@target="_blank"]',
- listTitleSearchXP: '//div[3]/div[@class="border-b pb-3 mb-4"]/a[@target="_blank"][+++]/../../../../..',
- listTitleMemoSearchXP: '//div[3]/div[@class="border-b pb-3 mb-4"]/a[@target="_blank"][+++]',
- listGen: 6,
- observe: 500,
- },
- {
- id: 'PUBMED',
- // urlRE: '//pubmed.ncbi.nlm.nih.gov/.term=',
- urlRE: '//pubmed.ncbi.nlm.nih.gov/.term=|//pubmed.ncbi.nlm.nih.gov/.linkname=|//pubmed.ncbi.nlm.nih.gov/',
- listTitleXP: '//span[@class="docsum-pmid" and text()]|.//span[@class="docsum-pmid"]/font[1]/font[1]',
- listHelpXP: '//span[@class="docsum-pmid" and text()]/../../../../..|.//span[@class="docsum-pmid"]/font/font/../../../../../../..',
- listTitleSearchXP: '//span[@class="docsum-pmid"][+++]/../../../../..|.//span[@class="docsum-pmid"]/font/font[+++]/../../../../../../..',
- listTitleMemoSearchXP: '//span[@class="docsum-pmid"][+++]|.//span[@class="docsum-pmid"]/font/font[+++]|//header[@id="heading"]/div[1]/ul/li/span/strong[@class="current-id"][+++]|//strong[@class="current-id"]/font/font[+++]/../..',
- observe: 500,
- listGen: 7,
- trim: 1,
- detailURLRE: /\/\/pubmed.ncbi.nlm.nih.gov\/\d*\//,
- detailTitleXP: '//header[@id="heading"]/div[1]/ul/li/span/strong[@class="current-id"][1]|//strong[@class="current-id"][1]/font[1]/font[1]',
- detailTitleSearchXP: '//header[@id="heading"]/div[1]/ul/li/span/strong[@class="current-id"][+++]/../../../../../..|//strong[@class="current-id"][1]/font[1]/font[1][+++]/../../../../../../../..',
- useText: 1,
- },
- {
- id: 'NICOCHART',
- urlRE: '//www.nicochart.jp/',
- listTitleXP: '//li[@class="title"]/a',
- listTitleSearchXP: '//li[@class="title"]/a[+++]/../../../../..',
- listTitleMemoSearchXP: '//li[@class="title"]/a[+++]',
- listGen: 5,
- redoWhenReturned: 1,
- },
- {
- id: 'NICOCHART',
- urlRE: '//www.nicovideo.me/',
- listTitleXP: '//h3[@class="fxs mtxs"]/a',
- listTitleSearchXP: '//h3[@class="fxs mtxs"]/a[+++]/../../..',
- listTitleMemoSearchXP: '//h3[@class="fxs mtxs"]/a[+++]',
- listGen: 3,
- redoWhenReturned: 1,
- },
- {
- id: 'TWITTER',
- urlRE: '//twitter.com/',
- title: 'a div[dir="ltr"] span',
- //listTitleXP: '//a/div[@dir="ltr"]/span',
- //listTitleSearchXP: '//a/div[@dir="ltr"]/span[+++]/../../../../../../../../../../../../../../..',
- box: 'div[data-testid="cellInnerDiv"]',
- //listTitleSearchXP: '//a/div[@dir="ltr"]/span[+++]/ancestor::div[@data-testid="cellInnerDiv"]',
- //listTitleMemoSearchXP: '//a/div[@dir="ltr"]/span[+++]',
- //listGen: 14,
- observe: 500,
- disableHelpForce: 1,
- },
- {
- id: 'SURUGAYA',
- urlRE: '//www.suruga-ya.jp/',
- listTitleXP: '//p[@class="title"]/a[1]',
- listTitleSearchXP: '//p[@class="title"]/a[1][+++]/../../..',
- listTitleMemoSearchXP: '//p[@class="title"]/a[1][+++]',
- listGen: 5,
- // titleProcessFunc: (title) => { return title.replace(/ランクB\)/gmi, "").replace(/(.*$|\(.*$/g, "").replace(/全??\d+巻セット.*$|全?\d+?~?\d+巻セット.*$/gmi, "").replace(/\s\/.*$/gmi, "").trim() },
- redoWhenReturned: 1,
- funcOnlyFirst: function() {
- if (location.href == "https://www.suruga-ya.jp/pcmypage/action_nyuka_search/list") {
- setupbutton("zaiko", "品切れの項目を非表示", () => {
- setInterval(() => { elegeta('//div[last()]/input[@value="再入荷通知する"]/../../../..').forEach(e => e.style.display = "none") }, 500);
- }, "もとに戻すにはリロード", "removeWhenClicked")
- }
- /* $(document).keypress(k=>{
- if(k.key=="1"){ setInterval(()=>{elegeta('//div[last()]/input[@value="再入荷通知する"]/../../../..').forEach(e=>e.style.display="none") },999);}
- if(k.key=="2"){ elegeta('//div[last()]/input[@value="再入荷通知する"]/../../../..').forEach(e=>e.style.display="block")}
- });
- */
- },
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- if (1 || lh(/\/\/www\.youtube\.com\/playlist\?list=/)) {
- addstyle.add('div.item_box{display: flex; flex-wrap: wrap;}')
- let menu = [
- { t: "安い", f: () => { sortdom(elegeta('div.item'), v => Number((eleget0('//div[contains(@class,"item_price")]/p[3]/span[1]/strong', v) || eleget0('//p[@class="price_teika"]/span[1]/strong', v) || eleget0('//div[@class="item_price"]/p/span[1]/strong', v))?.textContent?.replace(/[^0-9]/gmi, "") || 9999), 0) } },
- ]
- var sorttype = GF.yhmSortType % menu.length || 0
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- },
- }],
- },
- {
- id: 'YOUTUBE', // youtube::
- // helpOnDNI: 1,
- //listTitleMemoSearchXPSameGen: 1,
- //delayAutoWeighting: lh("www.youtube.com/playlist") ? 1 : 0,
- urlRE: /\/\/www\.youtube\.com\/(?:\?bp=.*)?$|\/\/www\.youtube\.com\/results|\/\/www\.youtube\.com\/channel\/|\/\/www\.youtube\.com\/playlist|\/\/www\.youtube\.com\/c\/|\/\/www\.youtube\.com\/user\/|\/\/www\.youtube\.com\/watch\?|\/\/www\.youtube\.com\/@/,
- disableUrlRE: /\/\/www\.youtube\.com\/watch\?/,
- redoWhenRefocused: 1,
- redoWhenReturned: 1,
- callGKSIafterMemo: 1,
- // redoWhenReturned: 1,
- listTitleXPIgnoreNotExist: 1,
- //nfd: 1,
- trim: 1,
- title: 'ytd-channel-name.ytd-c4-tabbed-header-renderer>.ytd-channel-name>div>yt-formatted-string,div.ytd-channel-name>yt-formatted-string#text>a,h1.title.ytd-video-primary-info-renderer>yt-formatted-string,h3.title-and-badge.ytd-video-renderer>a#video-title>yt-formatted-string.ytd-video-renderer,#items #dismissible a#video-title.yt-simple-endpoint,h4.ytd-playlist-panel-video-renderer span#video-title,h3.ytd-playlist-video-renderer a#video-title,#video-title.ytd-rich-grid-media,h1 yt-formatted-string.style-scope.ytd-watch-metadata,yt-formatted-string.style-scope.ytd-channel-name.complex-string a,span#video-title,.ytd-watch-next-secondary-results-renderer yt-formatted-string.ytd-channel-name,#byline', //,h1.ytd-watch-metadata yt-formatted-string.ytd-watch-metadata
- box: 'ytd-grid-video-renderer, ytd-video-renderer, div.ytd-playlist-video-list-renderer ytd-playlist-video-renderer, ytd-rich-item-renderer, div#title.style-scope.ytd-watch-metadata, div#channel-header .ytd-channel-name yt-formatted-string, ytd-watch-flexy h1.ytd-video-primary-info-renderer yt-formatted-string, ytd-video-owner-renderer #channel-name .ytd-channel-name div yt-formatted-string a,ytd-playlist-panel-video-renderer,ytd-compact-video-renderer,ytd-reel-item-renderer',
- forceTranslucentFunc: e => e.closest('#channel-container div ytd-channel-name div div yt-formatted-string.style-scope.ytd-channel-name,ytd-watch-metadata div#title.style-scope.ytd-watch-metadata,ytd-watch-metadata .ytd-channel-name a,div#channel-header .ytd-channel-name yt-formatted-string,ytd-watch-flexy h1.ytd-video-primary-info-renderer yt-formatted-string,ytd-video-owner-renderer #channel-name .ytd-channel-name div yt-formatted-string a,ytd-playlist-panel-video-renderer,#byline'),
- dniCancel: 1, // DNIがobserve(ms)以上連続して発火しても途切れるのを待ち続ける
- /*
- #channel-container div ytd-channel-name div div yt-formatted-string.style-scope.ytd-channel-name
- ↑チャンネルホームの投稿者名
- ytd-watch-metadata h1 yt-formatted-string.ytd-watch-metadata
- ↑新視聴画面タイトル
- ytd-watch-metadata .ytd-channel-name a
- ↑新視聴画面投稿者名
- div#channel-header .ytd-channel-name yt-formatted-string
- ↑旧チャンネルホーム投稿者名
- ytd-watch-flexy h1.ytd-video-primary-info-renderer yt-formatted-string
- ↑旧視聴タイトル
- ytd-video-owner-renderer #channel-name .ytd-channel-name div yt-formatted-string a
- ↑旧視聴投稿者名
- */
- listHelpXP: '//div[@id="dismissible"]|//div[@class="style-scope ytd-playlist-video-renderer"]/h3[@class="style-scope ytd-playlist-video-renderer"]/a/../../../../..',
- listTitleXP: '//a/yt-formatted-string[@class="style-scope ytd-video-renderer"]/..|.//a[@id="video-title"]|.//h3/span[@id="video-title"]|.//a[@id="video-title-link"]/yt-formatted-string[@id="video-title"]|.//yt-formatted-string[@id="video-title" and @class="style-scope ytd-rich-grid-media"]|//div[2]/ytd-video-primary-info-renderer[@has-date-text=""]/div/h1/yt-formatted-string[@force-default-style="" and contains(@class,"style-scope ytd-video-primary-info-renderer")]|//ytd-watch-metadata[@class="style-scope ytd-watch-flexy"]/div/div[@class="style-scope ytd-watch-metadata"]/h1[@class="style-scope ytd-watch-metadata"]/yt-formatted-string',
- listTitleSearchXP: '//ytd-grid-video-renderer[.//a[@id="video-title" and +++]]|//ytd-channel-name[@wrap-text=""]/div/div/yt-formatted-string[+++]/following::a|.//ytd-video-renderer[.//a[@id="video-title" and ++title++]]|.//ytd-video-renderer[.//a[contains(@class,"yt-simple-endpoint") and +++]]|.//ytd-rich-item-renderer[.//yt-formatted-string[@id="video-title" and +++]]|.//ytd-rich-item-renderer[.//a[contains(@class,"yt-simple-endpoint") and +++]]|.//ytd-playlist-video-renderer[.//a[@id="video-title" and ++title++]]',
- XP2name: '投稿者名 ',
- //XP2memo:1, // 投稿者にメモ可は重そう
- listTitleXP2: '//ytd-item-section-renderer[@class="style-scope ytd-section-list-renderer" and @use-height-hack=""]/div[3]/ytd-video-renderer[@class="style-scope ytd-item-section-renderer" and @use-prominent-thumbs=""]/div[@id="dismissible" and @class="style-scope ytd-video-renderer"]/div/div/ytd-channel-name[@id="channel-name" and @class="long-byline style-scope ytd-video-renderer" and @wrap-text="true"]/div[@id="container"]/div[@id="text-container" and @class="style-scope ytd-channel-name"]/yt-formatted-string[@id="text" and @class="style-scope ytd-channel-name"]/a|.//div[@class="byline style-scope ytd-rich-grid-media"]/ytd-video-meta-block[@rich-meta="" and @mini-mode=""]/div[@class="style-scope ytd-video-meta-block"]/div[@class="style-scope ytd-video-meta-block"]/ytd-channel-name/div[@class="style-scope ytd-channel-name"]/div[@class="style-scope ytd-channel-name"]/yt-formatted-string[@id="text" and @class="style-scope ytd-channel-name complex-string"]/a[@class="yt-simple-endpoint style-scope yt-formatted-string" and @spellcheck="false" and @dir="auto"]|//div[@id="meta" and @class="style-scope ytd-c4-tabbed-header-renderer"]/ytd-channel-name/div[@class="style-scope ytd-channel-name"]/div[@id="text-container" and @class="style-scope ytd-channel-name"]/yt-formatted-string[@id="text" and @class="style-scope ytd-channel-name"]|.//ytd-channel-name[@id="channel-name" and @class="style-scope ytd-video-meta-block"]/div[@id="container"]/div[@class="style-scope ytd-channel-name"]/yt-formatted-string[@class="style-scope ytd-channel-name complex-string" and @ellipsis-truncate=""]/a[@class="yt-simple-endpoint style-scope yt-formatted-string" and @dir="auto"]|.//ytd-channel-name[@id=\"channel-name\" and @wrap-text=\"true\"]/div[@class=\"style-scope ytd-channel-name\"]/div/yt-formatted-string/a|//div[@id="container"]/div[@class="style-scope ytd-channel-name"]/yt-formatted-string/a[@class="yt-simple-endpoint style-scope yt-formatted-string"]',
- listGen: 7,
- observe: 500,
- // ignoreDNI: e => e.nodeType !== 1 || !["YTD-PLAYLIST-VIDEO-RENDERER", "YTD-VIDEO-RENDERER", "YTD-RICH-ITEM-RENDERER", "YTD-PLAYLIST-PANEL-VIDEO-RENDERER"].includes(e.tagName), //ytd-playlist-panel-video-renderer
- ignoreDNI: e => e.nodeType !== 1 || !e?.matches(SITE.box), //!["YTD-PLAYLIST-VIDEO-RENDERER", "YTD-VIDEO-RENDERER", "YTD-RICH-ITEM-RENDERER", "YTD-PLAYLIST-PANEL-VIDEO-RENDERER"].includes(e.tagName), //ytd-playlist-panel-video-renderer
- //observeId: "dismissible",
- disableKeyB: 1,
- preventHelpFunc: () => 1,
- funcOnlyFirst: () => {
- hoverHelp(e => {
- if (e.closest('span#video-title , a#video-title , div#title.style-scope > h1.style-scope , yt-formatted-string#video-title.style-scope')) return "Q:非表示 W:アンドゥ 1,5:○メモ 2,6:×メモ<br>D:この投稿者の新しい/古い順の再生リストで再生<br>S:この動画を含む再生リストを検索"
- if (e.closest('ytd-channel-name > div#container.ytd-channel-name')) return "投稿者 Q:非表示 W:アンドゥ 1,5:○メモ 2,6:×メモ"
- if (e.closest('ytd-video-renderer , ytd-reel-item-renderer , ytd-rich-item-renderer')) return "Q:非表示 W:アンドゥ 1,5:○メモ 2,6:×メモ"
- if (e.closest('div.style-scope.ytd-channel-name > yt-formatted-string.complex-string > a , yt-formatted-string.ytd-channel-name > a')) return "投稿者 Q:非表示 W:アンドゥ 1,5:○メモ 2,6:×メモ<br>S:この投稿者の動画を入力ワードで検索"
- })
-
- addstyle.add('#channel-name.ytd-video-meta-block {--ytd-channel-name-text-complex-display: initial !important;}') // プレイリストの投稿者名のメモをなんとか見えるようにする
- addstyle.add('div#container.style-scope.ytd-playlist-panel-renderer {resize: both !important;}') // プレイリストをサイズ可変に
- document.body.addEventListener('mousedown', e => {
- var one = document.elementFromPoint(mousex, mousey) || e?.target
- //動画視聴ページで再生リストタイトルを右クリックでプレイリスト詳細を開く
- if (e.button == 2 && lh(/\&list=([0-9a-zA-Z-_]+)/) && one == eleget0('//yt-formatted-string[@class="title style-scope ytd-playlist-panel-renderer" and @ellipsis-truncate="" and @title="Untitled List" and text()="Untitled List"]|//div[@id="container"]/div/div[@id="header-contents" and @class="style-scope ytd-playlist-panel-renderer"]/div[1]/div[1]/h3[1]/yt-formatted-string/a')) {
- let u = location.href.match0(/\&list=([0-9a-zA-Z-_]+)/)
- if (u) window.open(`https://www.youtube.com/playlist?list=${u}`, "", "noreferrer")
- }
- //動画視聴ページで再生中タイトルを右クリックでその動画を含む再生リストを検索する
- if (e.button == 2 && lh(/\/watch/) && one?.matches('div#title>h1>yt-formatted-string')) {
- let u = encodeURIComponent(one?.innerText?.trim())
- if (u) {
- if (confirm(`https://www.youtube.com/results?search_query="${one?.innerText?.trim()}"&sp=EgIQAw%253D%253D\n\nを開きます。よろしいですか?`)) {
- elegeta('video').forEach(v => v.pause());
- window.open(`https://www.youtube.com/results?search_query=%22${u}%22&sp=EgIQAw%253D%253D`, "", "noreferrer")
- }
- }
- }
- }, false);
-
- var observeUrlHasChangedhref = location.href;
- var observeUrlHasChanged = new MutationObserver(mutations => {
- if (observeUrlHasChangedhref !== location.href) {
- pauseAll = 1;
- prefCacheClear();
- observeUrlHasChangedhref = location.href;
- // elegeta('//span[contains(@class,"yhmMyMemo")]/..').forEach(e => e.remove());
- elegeta('.yhmMyMemo').forEach(e => e?.parentNode?.remove());
- elegeta(SITE.box).forEach(e => e.style.opacity = "1");
- setTimeout(() => {
- pauseAll = 0;
- /*let watchTitle=eleget0('//div[@id="above-the-fold" and @class="style-scope ytd-watch-metadata"]/div/h1[@class="style-scope ytd-watch-metadata"]/yt-formatted-string'); if(watchTitle)watchTitle.innerText=watchTitle?.textContent?.normalize("NFC")*/
- run(document.body, "returned")
- }, 3500);
- }
- });
- observeUrlHasChanged.observe(document, { childList: true, subtree: true });
- GM_addStyle("#meta.ytd-playlist-panel-video-renderer{display:block}") // プレイリストがdisplay:flexで1行に詰め込めないので外す試用
- GM_addStyle('ytd-watch-flexy[rounded-player-large][default-layout] #ytd-player.ytd-watch-flexy{border-radius: 0 !important;} ytd-thumbnail[size="medium"] a.ytd-thumbnail, ytd-thumbnail[size="medium"]::before,ytd-thumbnail[size="large"] a.ytd-thumbnail, ytd-thumbnail[size="large"]::before { border-radius: 0 !important;}') // 動画の角丸を解除
- },
- func: function(node = document.body) {
- /*var watchtitle = eleget0('h1>yt-formatted-string.style-scope.ytd-video-primary-info-renderer');
- if (watchtitle) watchtitle.innerText = watchtitle.innerText.normalize("NFC"); //動画視聴画面のタイトルだけNFDでマッチしないので変換*/ //これやると動画遷移時タイトルが書き換わらなくなる
- // if (location.href.indexOf("https://www.youtube.com/playlist?list=") !== -1) { elegeta('a#video-title,span#video-title').forEach(e => { e.title = e.textContent.trim(); e.innerText = e.textContent.trim(); }); } // 再生リストだけテキストにゴミスペースがある
- //if (lh(/^https:\/\/www\.youtube\.com\/playlist\?list=|^https:\/\/www\.youtube\.com\/watch/)) { elegeta('a#video-title,span#video-title').forEach(e => { e.title = e.textContent.trim(); e.innerText = e.textContent.trim(); }); } // 再生リストだけテキストにゴミスペースがある
- if (REPLACE_LINK_IN_YOUTUBE) {
- // elegeta('//a', node).forEach(e => { if (/\/(channel|user|c)\/[^\/]+$/.test(e.href)) e.href = e.href + "/videos"; });
- elegeta('a', node).forEach(e => { if (/\/(channel|user|c)\/[^\/]+$|youtube\.com\/@[^\/]+$/.test(e?.href) && !/\/video/.test(e?.href)) { e.href = e.href + "/videos"; } })
- // elegeta('a', node).forEach(e => { if (/\/(channel|user|c)\/[^\/]+$|youtube\.com\/@[^\/]+$/.test(e.href)) e.href = e.href + "/videos"; });
- //elegeta('a[href*="&pp="]', node).forEach(e => e.href=e?.href?.replace(/&pp=[^&]+/,"") );
- }
- },
- // helpOnDNI:1,
- keyFunc: [{
- key: "d", // d::
- func: (e, evt) => {
- let targets = (elegeta(['//div[@id="title"]/h1/yt-formatted-string/span[1]', // watchのタグついてるタイトル
- '//h3[@class="title-and-badge style-scope ytd-video-renderer"]/a[@id="video-title" and @class="yt-simple-endpoint style-scope ytd-video-renderer"]/yt-formatted-string',
- '//div[@class="style-scope ytd-playlist-video-renderer"]/h3/a[@id="video-title"]',
- '//div[@id="title" and contains(@class,"style-scope ytd-watch-metadata")]/h1[@class="style-scope ytd-watch-metadata"]/yt-formatted-string',
- '//span[@id="video-title" and @class=" style-scope ytd-compact-video-renderer style-scope ytd-compact-video-renderer"]',
- '//a[@id="video-title-link"]/yt-formatted-string[@id="video-title" and @class="style-scope ytd-rich-grid-media"]',
- '//div[@class="style-scope ytd-playlist-panel-video-renderer"]/div[3]/h4/span[@id="video-title"]',
- '//ytd-rich-grid-slim-media[@lockup="true"]/div[@class="style-scope ytd-rich-grid-slim-media"]/div[@id="details"]/h3/a/span[@id="video-title"]',
- '//span[@class="style-scope ytd-reel-item-renderer"]', 'div#meta.style-scope.ytd-grid-video-renderer > h3.style-scope > a#video-title'
- ])) //
- targets.forEach(e => debugEle(e, "test autoRemove"))
- var one = document.elementFromPoint(mousex, mousey)
- if (targets.some(e => e.contains(one))) {
-
- let vid = (one?.closest('a[href*="watch?v="],a[href*="/shorts/"]')?.href || location.href).match(/watch\?v=([a-zA-Z0-9\-_]{11})|shorts\/([a-zA-Z0-9\-_]{11})/)?.slice(1)?.find(v => v)
-
- //チャンネル/videosページか視聴ページのみ 動画タイトル上でdキーでこの投稿者の「新しい順プレイリスト」でこの動画を再生するURL
- let chid = one.closest('[channel_id]')?.getAttribute("channel_id"); // 検索結果画面等のchID.youtubeフィルタを入れていると使える
- let plid = chid ? `${chid?.match0(/UC([a-zA-Z0-9\-_]+)/m)}` :
- !one.closest('div#items.style-scope.ytd-watch-next-secondary-results-renderer') ? (
- eleget0('#infocard-videos-button a[href*="/channel/UC"]')?.href?.match0(/\/channel\/UC([a-zA-Z0-9\-_]+)/m) ||
- elegeta('script').map(v => v?.innerHTML)?.join()?.match1(/"channelId":"UC([a-zA-Z0-9\-_]+)"|"externalId":"UC([a-zA-Z0-9\-_]+)"/m)
- ) : null
- if (plid && !one?.closest('ytd-playlist-panel-renderer#playlist.style-scope.ytd-watch-flexy')) {
- /*
- let vid = (one?.closest('a[href*="watch?v="],a[href*="/shorts/"]')?.href || location.href).match(/watch\?v=([a-zA-Z0-9\-_]{11})|shorts\/([a-zA-Z0-9\-_]{11})/)?.slice(1)?.find(v => v)
- //チャンネル/videosページか視聴ページのみ 動画タイトル上でdキーでこの投稿者の「新しい順プレイリスト」でこの動画を再生するURL
- let chid = one.closest('[channel_id]')?.getAttribute("channel_id"); // 検索結果画面等のchID.youtubeフィルタを入れていると使える
- let plid = chid ? `${chid?.match0(/UC([a-zA-Z0-9\-_]+)/m)}` :
- eleget0('#infocard-videos-button a[href*="/channel/UC"]')?.href?.match0(/\/channel\/UC([a-zA-Z0-9\-_]+)/m) || elegeta('script').map(v => v?.innerHTML)?.join()?.match1(/"channelId":"UC([a-zA-Z0-9\-_]+)"|"externalId":"UC([a-zA-Z0-9\-_]+)"/m)
- if (plid && !one?.closest('ytd-playlist-panel-renderer#playlist.style-scope.ytd-watch-flexy')) {
- */
- evt.preventDefault();
- evt.stopPropagation(); // 有効なdキーだったら本来の機能(10秒進む)をキャンセル
- if (plid && vid) {
- var url = `https://www.youtube.com/watch?v=${vid}&list=UU${plid}`
- if (confirm(`d:この投稿者の『新しい順のプレイリスト』でこの動画を再生するURL\n\n${url}\n\nを開きますか?`)) {
- //elegeta('video').forEach(v => v.pause()); // 停止する
- GM.openInTab(url, true)
- return false;
- }
- }
- }
-
- // /videosページ、視聴ページ、検索結果、どこでも この投稿者の『古い順プレイリスト』でこの動画を再生するURL
- var url = `https://www.youtube.com/watch?v=${vid}&list=${Math.random()>0.5?"ULcxqQ59vzyTk":"UL01234567890"}`;
- if (vid && confirm(`d:この投稿者の『古い順プレイリスト』でこの動画を再生するURL\n\n${url}\n\nを開きますか?`)) {
- //elegeta('video').forEach(v => v.pause()); // 停止する
- GM.openInTab(url, true)
- return false;
- }
- return false;
- }
- }
- }, {
- key: "s", // s::
- func: (e, evt) => {
- let targets = (elegeta('//h3[@class="title-and-badge style-scope ytd-video-renderer"]/a[@id="video-title" and @class="yt-simple-endpoint style-scope ytd-video-renderer"]/yt-formatted-string|//div[@class="style-scope ytd-playlist-video-renderer"]/h3/a[@id="video-title"]|//div[@id="title" and contains(@class,"style-scope ytd-watch-metadata")]/h1[@class="style-scope ytd-watch-metadata"]/yt-formatted-string|//span[@id="video-title" and @class=" style-scope ytd-compact-video-renderer style-scope ytd-compact-video-renderer"]|//a[@id="video-title-link"]/yt-formatted-string[@id="video-title" and @class="style-scope ytd-rich-grid-media"]|//div[@class="style-scope ytd-playlist-panel-video-renderer"]/div[3]/h4/span[@id="video-title"]'))
- var one = document.elementFromPoint(mousex, mousey)
- //let hover=(eleget0('yt-formatted-string:hover,a:hover'))
- one = targets.find(e => e.contains(one))
- if (targets.includes(one)) {
- //動画タイトル上でsキーでその動画を含む再生リストを検索する
- let title = one?.innerText?.trim()
- let u = encodeURIComponent(title)
- if (u) {
- evt.preventDefault();
- evt.stopPropagation(); // 有効なlキーだったら本来の機能(10秒進む)をキャンセル
- if (confirm(`s:指したタイトルを含む再生リストを検索する\n\nhttps://www.youtube.com/results?search_query="${one?.innerText?.trim()}"&sp=EgIQAw%253D%253D\n\nを開きます。よろしいですか?`)) {
- //elegeta('video').forEach(v => v.pause()); // 停止する
- GM.openInTab(`https://www.youtube.com/results?search_query=%22${u}%22&sp=EgIQAw%253D%253D`, "true")
- }
- }
- return false;
- }
- //投稿者名上でsキーでそのチャンネルの動画を入力したキーワードで検索する
- var one = document.elementFromPoint(mousex, mousey)
- if (lh(/\/watch|search_query|^https:\/\/www\.youtube\.com\/$/) && one?.matches('yt-formatted-string#text.style-scope.ytd-channel-name > a.yt-simple-endpoint[herf*="https://www.youtube.com/channel/"],div.ytd-channel-name yt-formatted-string a,yt-formatted-string#text.ytd-channel-name>a[href*="https://www.youtube.com/@"],ytd-channel-name div.ytd-channel-name div#text-container yt-formatted-string a[href*="https://www.youtube.com/@"]')) { //div#channel-header ytd-channel-name div div yt-formatted-string
- let u = one?.href?.match0(/(https:\/\/www\.youtube\.com\/@[^\/]+)\/videos/) || one?.href?.match0(/(https:\/\/www\.youtube\.com\/channel\/[^\/]+)/)
- if (u) {
- evt.preventDefault();
- evt.stopPropagation(); // 有効なlキーだったら本来の機能(10秒進む)をキャンセル
- u += '/search?query='
- let qu = prompt(`s:指した投稿者の動画をキーワードで検索する\n\n${one?.textContent}\nの動画を入力した検索キーワード(***)で検索します\n\n${u}***\n\n`)?.trim()
- if (qu) {
- GM.openInTab(u + encodeURIComponent(qu), "true")
- }
- }
- }
- return false;
- },
- }, {
- key: 'Shift+F', // Shift+F::YouTubeでキーワード検索
- func: () => { searchWithHistory("YouTube", "YouTube", 'https://www.youtube.com/results?search_query=***', "+OR+") },
- }, {
- key: 'u', // u::チャプターメモ
- func: (e) => {
- if (lh(/https:\/\/www\.youtube\.com\/results\?search_query\=/)) { // u::uniq
- let undup = []
- let dup = []
- elegeta('h3.title-and-badge.style-scope.ytd-video-renderer>a>yt-formatted-string:visible').forEach(e => {
- if (undup.includes(e.textContent)) {
- e.scrollIntoView({ behavior: "instant", block: "center", inline: "center" });
- $(e.closest("ytd-grid-video-renderer, ytd-video-renderer, div.ytd-playlist-video-list-renderer ytd-playlist-video-renderer, ytd-rich-item-renderer, h1 yt-formatted-string.ytd-watch-metadata, div#channel-header .ytd-channel-name yt-formatted-string, ytd-watch-flexy h1.ytd-video-primary-info-renderer yt-formatted-string, ytd-video-owner-renderer #channel-name .ytd-channel-name div yt-formatted-string a,ytd-playlist-panel-video-renderer,ytd-compact-video-renderer,ytd-reel-item-renderer")).hide(999, function() { $(this).remove() }); //e?.closest(".entry")?.remove()
- dup.push(e.textContent)
- } else { undup.push(e.textContent) }
- })
- popup2(`u:重複タイトルを隠す\n${dup.join("\n")}`, 6)
- return
- }
-
- chapterMemo(/watch/, () => eleget0('//div[2]/ytd-video-primary-info-renderer[@has-date-text=""]/div/h1/yt-formatted-string[@force-default-style="" and contains(@class,"style-scope ytd-video-primary-info-renderer")]|//ytd-watch-metadata[@class="style-scope ytd-watch-flexy"]/div/div[@class="style-scope ytd-watch-metadata"]/h1[@class="style-scope ytd-watch-metadata"]/yt-formatted-string')?.textContent, `https://www.youtube.com/watch?v=${location.href.match0(/v\=([^?&]*)/)}&t=**time**`)
- },
- }, {
- key: 'Shift+U', // Shift+U::チャプターメモをクリップボードにコピー
- func: (e) => {
- // watch視聴画面
- elegeta('a[href*="&pp="]').forEach(e => e.href = e?.href?.replace(/&pp=[^&]+/, ""))
- if (lh(/watch/) && kaisuuU % 4 < 2) chapterMemo(/watch/, () => eleget0('meta[name="title"]:visible')?.getAttribute("content") || eleget0('//div[@id="title" and @class="style-scope ytd-watch-metadata"]/h1/yt-formatted-string:visible')?.textContent?.trim(), `${(kaisuuU%3%2==1?"https://www.youtube.com/watch?v=**id**&t=**time**":"https://youtu.be/**id**?t=**time**").replace("**id**",location.href.match0(/v\=([a-zA-Z0-9_\-]{11})/))}`, 1) // 1-2回目:今見てる動画のついているチャプターメモを列挙
- if (lh(/watch/) && kaisuuU % 4 == 2) { // 3回目:プレイリスト中の○メモかチャプターメモがついた動画(Qで消されていたら除外)を列挙
- let chaMemoTU = [...new Set((elegeta('div#items ytd-playlist-panel-video-renderer#playlist-items').reduce((ac, v) => {
- if (eleget0('.yhmMyMemo:not(.yhmMyMemoX)', v) && v?.style?.opacity != 0.5) {
- //ac.push(`${eleget0('#video-title', v)?.innerText?.normalize("NFC")?.trim()}\n${eleget0('a', v)?.href?.replace(/\&list=.*/, "")}\n`)
- ac.push(`${eleget0('#video-title', v)?.innerText?.normalize("NFC")?.trim()} - YouTube\n${eleget0('a', v)?.href?.replace(/\&.*/, "")}\n`)
- }
- return ac
- }, [])))]
- GM.setClipboard(chaMemoTU.join(""))
- popup2(chaMemoTU.join(""), -1, "", "top")
- }
- if (lh(/watch/) && (kaisuuU % 5 == 3 || kaisuuU % 5 == 4)) { // 4/5回目:プレイリスト中の○メモかチャプターメモがついた動画(Qで消されていたら除外)を列挙、メモを掲載
- let chaMemoTU = [...new Set((elegeta('div#items ytd-playlist-panel-video-renderer#playlist-items').reduce((ac, v) => {
- let uploader = eleget0('span#byline.style-scope.ytd-playlist-panel-video-renderer', v)?.textContent?.trim();
- let videolen = eleget0('div.style-scope.ytd-thumbnail-overlay-time-status-renderer', v)?.textContent?.trim();
- let memoot = elegeta('.yhmMyMemo:not(.yhmMyMemoX)', v).filter(v => v?.style?.opacity != 0.5).map(v => v.textContent).join(" ")
- let memoxt = elegeta('.yhmMyMemoX', v).filter(v => v?.style?.opacity != 0.5).map(v => v.textContent).join(" ")
- let chapterurl = elegeta('.yhmMyMemo:not(.yhmMyMemoX)', v).find(v => v?.style?.opacity != 0.5 && v?.dataset?.url)?.dataset.url.match0(/&t=\d*/)
- if (kaisuuU % 5 == 4 || memoot) {
- // ac.push(`${eleget0('#video-title', v)?.innerText?.normalize("NFC")?.trim()} - YouTube${uploader?` - ${uploader}`:""}${(memoot||memoxt)?" - ":""}${memoot}${memoxt?" "+memoxt:""}\n${chapterurl?eleget0('a', v)?.href?.replace(/\&.*/, "")+chapterurl: eleget0('a',v)?.href?.replace(/\&.*/, "")}\n`)
- ac.push(`${eleget0('#video-title', v)?.innerText?.normalize("NFC")?.trim()} - YouTube${uploader?` - ${uploader}`:""}${videolen?` - [${videolen}]`:""}${(memoot||memoxt)?" - ":""}${memoot}${memoxt?" "+memoxt:""}\n${chapterurl?eleget0('a', v)?.href?.replace(/\&.*/, "")+chapterurl: eleget0('a',v)?.href?.replace(/\&.*/, "")}\n`)
- }
- return ac
- }, [])))]
- GM.setClipboard(chaMemoTU.join(""))
- popup2(`${kaisuuU % 5 ==3?"メモとチャプター反映/メモあり":"メモとチャプター反映/全て"}(${chaMemoTU?.length})\n` + chaMemoTU.join(""), -1, "background-color:#447;", "top")
- //popup2(`${chaMemoTU?.length})\n` + chaMemoTU.join(""), -1, "", "top")
- }
-
- // 検索、プレイリスト画面等
- if (!lh(/\/watch/) && lh(/\/results\?search_query=|\/videos|\/playlist|\/shorts|\/search/)) {
-
- let list
- if (kaisuuU % 4 == 3) { // 4回目:○メモかチャプターメモがついた動画(Qで消されていたら除外)を列挙、メモを掲載
- list = [...new Set((elegeta('ytd-grid-video-renderer,ytd-video-renderer,ytd-playlist-video-renderer,ytd-rich-item-renderer,ytd-reel-item-renderer.style-scope.yt-horizontal-list-renderer').reduce((ac, v) => {
- let memoot = elegeta('.yhmMyMemo:not(.yhmMyMemoX)', v).filter(v => v?.style?.opacity != 0.5).map(v => v.textContent).join(" ")
- let memoxt = elegeta('.yhmMyMemoX', v).filter(v => v?.style?.opacity != 0.5).map(v => v.textContent).join(" ")
- let chapterurl = elegeta('.yhmMyMemo:not(.yhmMyMemoX)', v).find(v => v?.style?.opacity != 0.5 && v?.dataset?.url)?.dataset.url.match0(/&t=\d*/)
- if (memoot) {
- ac.push(`${eleget0('#video-title', v)?.innerText?.normalize("NFC")?.trim()} - YouTube ${memoot}${memoxt?" "+memoxt:""}\n${chapterurl?eleget0('a', v)?.href?.replace(/\&.*/, "")+chapterurl: eleget0('a',v)?.href?.replace(/\&.*/, "")}\n`)
- }
- return ac;
- }, [])))];
- list = [...new Set(list)];
- } else {
-
- // 1-3回め:
- list = elegeta('.yhmMyMemo:not(.yhmMyMemoX):visible')
- .filter(e => e?.closest("ytd-grid-video-renderer,ytd-video-renderer,ytd-playlist-video-renderer,ytd-rich-item-renderer,ytd-reel-item-renderer.style-scope.yt-horizontal-list-renderer") && ((GF?.chaptermemotype || 0) % 3 != 1 || e?.dataset?.cm))
- .map(memoEle => {
- let vEle = eleget0("a[href*='/watch?v='],a[href*='/shorts/']", memoEle?.closest(SITE.box));
- // let vID = vEle?.href?.match0(/https:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9_\-]{11})/);
- let vID = vEle?.href?.match0(/(?:\/watch\?v=|\/shorts\/)([a-zA-Z0-9_\-]{11})/);
- let url = `https://www.youtube.com/watch?v=${ vID}`;
- let title = eleget0(SITE.title, memoEle?.closest(SITE.box))?.textContent?.trim();
- let stime = hms2sec(memoEle.textContent.match0(/^([\d:]+)\s/) || "");
- let memo = !stime ? memoEle.textContent?.replace(/^\d\d\d\d\.\d\d\.\d\d(?:\s\(.\))?$/, "") : "";
- let line = (GF?.chaptermemotype || 0) % 4 < 2 && stime ? `${title} - YouTube ▶ ${memoEle?.textContent?.trim()}\n${url}?t=${stime}\n` : `${title} - YouTube${memo?" "+memo:""}\n${url}\n`;
- return line;
- });
- list = [...new Set(list)];
- }
-
- GF.chaptermemotype = (GF?.chaptermemotype || 0) + 1; // 偶数回目に押した時はチャプターメモに絞る
- GM.setClipboard(list?.join("") || "")
- popup2((list?.join("") || ""), -1, "", "top") //popup2(`(${list?.length})\n` + (list?.join("") || ""), -1, "", "top")
- }
- kaisuuU++
- },
- }, {
- key: 'h', // a:: h::キューかプレイリストありでの視聴画面 (「YouTube検索結果「全てキューに入れて再生」ボタンを追加」用)
- func: () => {
- if (/\/\/www\.youtube\.com\/watch/.test(location.href)) {
- let menu = [
- { t: "時間長", f: () => { sortdom(elegeta('ytd-playlist-panel-video-renderer:visible'), v => Number(v?.querySelector('span.style-scope.ytd-thumbnail-overlay-time-status-renderer')?.innerText?.replace(/[^0-9]/gmi, "") || Number.MAX_SAFE_INTEGER), 1) } },
- { t: "時間短", f: () => { sortdom(elegeta('ytd-playlist-panel-video-renderer:visible'), v => Number(v?.querySelector('span.style-scope.ytd-thumbnail-overlay-time-status-renderer')?.innerText?.replace(/[^0-9]/gmi, "") || Number.MAX_SAFE_INTEGER)) } },
- //{ t: "メモ多", f: () => { sortdom(elegeta('ytd-playlist-panel-video-renderer:visible'), v => Number(elegeta('.yhmMyMemo', v).length), 1) } },
- { t: "メモ多", f: () => { sortdom(elegeta('ytd-playlist-panel-video-renderer:visible'), v => (elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- { t: "タイトル", f: () => { sortdom(elegeta('ytd-playlist-panel-video-renderer:visible'), v => v?.querySelector('span#video-title')?.textContent?.trim()) } },
- { t: "投稿者名", f: () => { sortdom(elegeta('ytd-playlist-panel-video-renderer:visible'), v => v?.querySelector('span#byline')?.textContent?.trim()) } },
- ]
- var sorttype = GF.yhmSortType % menu.length || 0
- popup2("h:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- }
- }
- }, {
- key: 'a', // a::
- func: () => {
- if (lh(/\/\/www\.youtube\.com\/playlist\?list=/)) {
- let menu = [
- { t: "時間長", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")), 1) } },
- { t: "時間短", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, ""))) } },
- //{ t: "メモ多", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => elegeta('.yhmMyMemo', v).length, 1) } },
- { t: "メモ多", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => (elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- { t: "タイトル", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('#video-title', v)?.textContent?.trim()) } },
- { t: "投稿者", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('div.style-scope.ytd-channel-name yt-formatted-string a', v)?.textContent?.trim() || "") } },
- { t: "再生多", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//yt-formatted-string[@id="video-info"]/span[@dir="auto" and @class="style-scope yt-formatted-string" and contains(text(),"回視聴")]', v)?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1) } },
- { t: "再生少", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//yt-formatted-string[@id="video-info"]/span[@dir="auto" and @class="style-scope yt-formatted-string" and contains(text(),"回視聴")]', v)?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 0) } },
- { t: "古い", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//div[@id="metadata"]/div/yt-formatted-string/span[contains(text(),"前")]', v)?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1) } },
- { t: "新しい", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//div[@id="metadata"]/div/yt-formatted-string/span[contains(text(),"前")]', v)?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 0) } },
- { t: "逆順", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('//yt-formatted-string[@id="index"]', v)?.textContent, 1) } },
- { t: "元順", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('//yt-formatted-string[@id="index"]', v)?.textContent, 0) } },
- ]
- var sorttype = GF.yhmSortType % menu.length || 0
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- if (lh(/\/\/www.youtube.com\/(?:channel\/|c\/|user\/|@)[^\/]+\/(?:search)/)) { // a::
- let menu = [
- { t: "メモ多", f: () => { sortdom(elegeta('ytd-item-section-renderer.style-scope.ytd-section-list-renderer'), v => (elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+、×メモは-評価
- { t: "時間短", f: () => { sortdom(elegeta('ytd-item-section-renderer.style-scope.ytd-section-list-renderer'), v => Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, ""))) } },
- { t: "タイトル", f: () => { sortdom(elegeta('ytd-item-section-renderer.style-scope.ytd-section-list-renderer:visible'), v => v?.querySelector('a#video-title.style-scope > yt-formatted-string')?.textContent?.trim()) } },
- { t: "古い", f: () => { sortdom(elegeta('ytd-item-section-renderer.style-scope.ytd-section-list-renderer'), (v) => { let n = v?.querySelector('div.ytd-video-meta-block span:nth-child(4).inline-metadata-item.style-scope.ytd-video-meta-block')?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1) } },
- { t: "新しい", f: () => { sortdom(elegeta('ytd-item-section-renderer.style-scope.ytd-section-list-renderer'), (v) => { let n = v?.querySelector('div.ytd-video-meta-block span:nth-child(4).inline-metadata-item.style-scope.ytd-video-meta-block')?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == GF.yhmSortType % menu.length ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF.yhmSortType % menu.length]?.f()
- GF.yhmSortType = (GF?.yhmSortType + 1) % menu.length
- }
- if (lh(/\/\/www.youtube.com\/(?:channel\/|c\/|user\/|@)[^\/]+\/(?:videos|shorts|streams)/)) { // a::
- $('ytd-rich-grid-row .style-scope.ytd-rich-grid-row').unwrap(); // 表示が乱れるのでよくわからない4列化行要素を消す
- var sorttype = GF.yhmSortType || 0
- let menu = [
- { t: "現状を反転", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v, i) => { return -i }) } },
- { t: "時間長", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { return Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")) }, 1) } },
- { t: "時間短", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { return Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")) }) } },
- { t: "メモ多", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { return (elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0) }, 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- { t: "タイトル", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => v?.querySelector('#video-title')?.textContent?.trim()) } },
- { t: "再生多", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(3)')?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1) } },
- { t: "再生少", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(3)')?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }) } },
- { t: "古い", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(4)')?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1) } },
- { t: "新しい", f: () => { sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(4)')?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }) } },
- // { t: "", f: () => { } },
- ]
- menu = menu.slice(0, lh(/\/\/www\.youtube\.com\/playlist\?list=/) ? 5 : 9)
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+4),0)}em;`);
- //popup2("A:ソート\n\n※YouTubeの仕様変更により現在「時間短」しかまともに動作しないようです\n\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+4),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return;
-
- /*var menumax = lh(/\/\/www\.youtube\.com\/playlist\?list=/) ? 5 : 9
- var sorttype = Number($('.yhmSortType')?.attr("id") || 0);
- $('.yhmSortType').remove();
- $(document.body).append(`<span class="yhmSortType" id="${++sorttype}"></span>`)
- popup2("A:ソート\n" + (["現状を反転", "時間長", "時間短", "メモ多", "タイトル", "再生多", "再生少", "古い", "新しい"].slice(0, menumax).map((c, i) => " " + c + (i + 1 == sorttype ? " ←\n" : "\n")).join("")), 6, "min-width:8em;")
- //popup2("A:ソート\n" + (["時間長", "時間短", "タイトル", "再生多", "再生少"].map((c, i) => " " + c + (i + 1 == sorttype ? " ←\n" : "\n")).join("")), 6, "min-width:6em;")
- let newUI = eleget0('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer') || eleget0('//div[@class="style-scope ytd-rich-grid-row"]')
- if (newUI) $('ytd-rich-grid-row .style-scope.ytd-rich-grid-row').unwrap(); // 表示が乱れるのでよくわからない4列化行要素を消す
- [() => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v, i) => { return -i }) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v, i) => { return -i }, 1);
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { return Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")) }, 1) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => { return -Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")) }, 1);
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { return Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")) }) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => { return Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")) }, 1);
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => (elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) // ○メモとチャプターメモは+1、×メモは-1評価
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => v?.querySelector('#video-title')?.textContent?.trim()) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => v?.querySelector('a#video-title')?.title?.trim(), 3);
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(3)')?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(1)')?.textContent; return -parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1);
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(3)')?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(1)')?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1);
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(4)')?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => { let n = eleget0('//div[1]/div[@id="metadata-line"]/span[2]', v)?.textContent; return -parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1)
- }, () => {
- if (newUI) sortdom(elegeta('ytd-rich-item-renderer.style-scope.ytd-rich-grid-row,ytd-grid-playlist-renderer.style-scope.ytd-grid-renderer,ytd-grid-video-renderer.style-scope.ytd-grid-renderer'), (v) => { let n = v?.querySelector('#metadata-line>span:nth-child(4)')?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }) // 20221029UI
- if (!newUI) domsort(elegeta('//div[@id="index-container"]/../..|//ytd-item-section-renderer/div[3]/ytd-grid-renderer[@class="style-scope ytd-item-section-renderer"]/div[@id="items"]:visible'), elegeta('//div[@id="index-container"]/..|//ytd-grid-video-renderer[@class="style-scope ytd-grid-renderer"]'), (v) => { let n = eleget0('//div[1]/div[@id="metadata-line"]/span[2]', v)?.textContent; return -parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 3)
- }][sorttype - 1]()
- if (sorttype == menumax) $('.yhmSortType').remove();
- return
- */
- }
- if (/\/\/www.youtube.com\/results\?search_query=/.test(location.href)) { // 検索結果 // a::
- let menu = [
- //{ t: "メモ多", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => elegeta('.yhmMyMemo', v).length, 1) } },
- // { t: "メモ多", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => Number(elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- { t: "メモ多", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => Number(elegeta('.yhmMyMemoO:visible', v)?.length || 0) - (elegeta('.yhmMyMemoX:visible', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価 // 投稿者名には見えない要素が1つあるのでメモが2倍ついているのでvisible指定するが本当はしたくない
- { t: "時間長", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => Number(eleget0('span#text.style-scope.ytd-thumbnail-overlay-time-status-renderer', v)?.textContent?.replace(/[^0-9]/gmi, "")), 1); } },
- { t: "時間短", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => Number(eleget0('span#text.style-scope.ytd-thumbnail-overlay-time-status-renderer', v)?.textContent?.replace(/[^0-9]/gmi, ""))); } },
- { t: "タイトル", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => eleget0('//yt-formatted-string[@class="style-scope ytd-video-renderer"]', v)?.textContent?.trim()); } }, // shortsを含めない
- //{ t: "タイトル", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => eleget0('//yt-formatted-string[@class="style-scope ytd-video-renderer"]', v)?.textContent?.replace(/[\s "”\[\]「」[]「」『』【】()\(\)\::・\-\//]/gmi,"")?.trim()); } }, // shortsを含めない // 空白と記号を無視する版
- { t: "投稿者", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => eleget0('//a[@class="yt-simple-endpoint style-scope yt-formatted-string"]', v)?.textContent); } },
- { t: "再生多", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => { let n = eleget0('//div[@id="metadata-line"]/span[1]', v)?.textContent || "0"; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1) } },
- { t: "再生少", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => { let n = eleget0('//div[@id="metadata-line"]/span[1]', v)?.textContent || "0"; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }) } },
- { t: "古い", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => { let n = eleget0('//div[@class="style-scope ytd-video-meta-block"]/div/span[2]', v)?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1) } },
- { t: "新しい", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer:visible'), v => { let n = eleget0('//div[@class="style-scope ytd-video-meta-block"]/div/span[2]', v)?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }) } },
- { t: "動画多", f: () => { sortdom(elegeta('ytd-video-renderer.style-scope.ytd-item-section-renderer,ytd-playlist-renderer:visible'), v => Number(eleget0('yt-formatted-string.style-scope.ytd-thumbnail-overlay-bottom-panel-renderer,.style-scope.ytd-thumbnail-overlay-side-panel-renderer', v)?.textContent?.replace(/[^0-9]/gmi, "") || 0) * 10000000 || Number(eleget0('span#text.style-scope.ytd-thumbnail-overlay-time-status-renderer', v)?.textContent?.replace(/[^0-9]/gmi, "")), 1) } },
- ]
- var sorttype = (GF.yhmSortType || 0) % menu.length
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- },
- }],
- //WhateverFirstAndEveryAPFunc: () => {if((/\/\/www.youtube.com\/results\?search_query=/.test(location.href)) || (/\/\/www.youtube.com\/channel\/[^\/]+\/videos/.test(location.href) || /\/\/www.youtube.com\/user\/[^\/]+\/videos/.test(location.href))) popup3(`A:ソート`,8,5000)},
- // wholeHelp: [() => (/\/\/www.youtube.com\/results\?search_query=/.test(location.href)) || (/\/\/www.youtube.com\/channel\/[^\/]+\/videos/.test(location.href) || /\/\/www.youtube.com\/user\/[^\/]+\/videos/.test(location.href)), " A:ソート"],
- wholeHelp: [() => (lh(/\/\/www\.youtube\.com\/playlist\?list=/) || /\/\/www.youtube.com\/results\?search_query=/.test(location.href) || lh(/\/\/www.youtube.com\/(?:channel\/|c\/|user\/|@)[^\/]+\/(?:videos|shorts|streams)/)), " A:ソート"],
- },
- {
- id: 'IHERB',
- urlRE: '//.*.iherb.com/',
- title: 'div.product-title,div div#name',
- box: 'div.product-cell-container,article.ga-product.product-grouping-refresh',
- redoWhenRefocused: 1,
- //listTitleXP: '//div[@class="absolute-link-wrapper"]/a',
- //listTitleSearchXP: '//div[@class="absolute-link-wrapper"]/a[++title++]/../../..',
- //listTitleMemoSearchXP: '//div[@class="absolute-link-wrapper"]/a[++title++]|.//div[@itemprop="name" and @id="name" and ***]|.//div/div[@id="name" and ***]|//section[3]/div[@id="product-summary-header"]/div[3][***]',
- //listGen: 3,
- observe: 1000,
- //runWhenUrlHasChanged:1,
- /*detailURLRE: /iherb.com\/pr\//,
- detailTitleXP: '//div[@itemprop="name" and @id="name"]',
- detailTitleSearchXP: '//div[@itemprop="name" and @id="name"][***]/../../../../..',*/
- forceTranslucentFunc: () => lh(/iherb.com\/pr\//),
- trim: 1,
- titleProcessFunc: (title) => { return title.replace(/<br>/gmi, "")?.trim() },
- func: () => {
- lh(/\/c\/|\/search\?/) && elegeta('div.rating > a.stars:not([data-starpop])').forEach(e => {
- before(e, `<span style="color:#444" data-estars="${parseFloat(e?.title.match0(/^([0-9\.]+)/)) }">${e?.title.match0(/^([0-9\.]+)/||"0")+" "||""}</span>`);
- e.dataset.starpop = 1;
- })
- elegeta('//div[@itemprop="name" and @id="name"]').forEach(e => e.textContent = e.textContent.replace(/\&/gmi, "&").replace(/\"/gmi, "”").trim()) // &はxpath/textで見逃す
- elegeta('//div[@class="absolute-link-wrapper"]/a').forEach(e => e.title = e.title.replace(/\&/gmi, "&").replace(/\"/gmi, "”").trim())
- GM_addStyle('.product-column .product { height: auto; min-height:395px; }');
- lh('https://jp.iherb.com/pr/') && [/(メチルコバラミン[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(Methylcobalamin[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(アデノシルコバラミン[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(Adenosylcobalamin[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(ヒドロキソコバラミン[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(Hydroxocobalamin[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(シアノコバラミン[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(Cyanocobalamin[^\n]*\d+\s*(?:mg|mcg|μg))/mi, /(Cyanocobalamin[^\n]*\d+\s*mg)/mi, /(ubiquinol|ubiquinon|ユビキノン|ユビキノール)/mi, /(iron[^\n]*\d+\s*mg)/im, /(鉄[^\n]*\d+\s*mg)/im].forEach(m => autoMemo2(eletext('section.content-wrapper'), m));
- //lh('https://jp.iherb.com/pr/') && [/(アデノシルコバラミン|Adenosylcobalamin|メチルコバラミン|cyanocobalamin|ヒドロキソコバラミン|Hydroxocobalamin|methylcobalamin|シアノコバラミン)/mi,/(ubiquinol|ubiquinon|ユビキノン|ユビキノール)/mi,/(iron[^\n]*\d+\s*mg)/im, /(鉄[^\n]*\d+\s*mg)/im].forEach(m => autoMemo2(eletext('section.content-wrapper'), m));
- }, // 商品ブロックの縦幅固定をやめる
- }, {
- id: 'YODOBASHI',
- urlRE: '//www.yodobashi.com/',
- //title:!lh(`/product`)?'div:last-of-type > ul > li:last-of-type > a , a > div.pName.fs14 > p:last-of-type , span.mr10':' h1[class*="pName js_variHeight"] > span , td#js_makerTD.maker',
- title: 'div.srcResultItem.spt_hznList.tileTypeList.js_productList.changeTile :is(div:last-of-type > ul > li:last-of-type > a , a > div.pName.fs14 > p:last-of-type , span.mr10) , div.pdTopContainer :is( h1[class*="pName js_variHeight"] > span , td#js_makerTD.maker )',
- box: `div.srcResultItem_block.pListBlock.hznBox.js_productBox.js_smpClickable.js_latestSalesOrderProduct.productListTile , div.pdTopContainer`,
- listHelpXP2: 'div.srcResultItem.spt_hznList.tileTypeList.js_productList.changeTile :is(div:last-of-type > ul > li:last-of-type > a , a > div.pName.fs14 > p:last-of-type , span.mr10) , div.pdTopContainer :is( h1[class*="pName js_variHeight"] > span , td#js_makerTD.maker )',
- forceTranslucentFunc: e => lh("https://www.yodobashi.com/product/1"),
- /* listTitleXP: '//div[@class="pName fs14"]/p[2]|.//div[@class="product js_productName"]',
- listTitleSearchXP: '//div[@class="pName fs14"]/p[2][+++]/../../..|.//div[@class="product js_productName" and +++]/../../..|.//div[@class="product js_productName" and +++]/../../../../..',
- listTitleMemoSearchXP: '//div[@class="pName fs14"]/p[2][+++]|.//div[3]/h1[@id="products_maintitle"]/span[1][+++]|.//div[@class="product js_productName" and +++]|.//div[@class="product js_productName"][+++]',
- listGen: 4,
- listHelpXP: '//div[@class="pName fs14"]/p[2]/../../..',
- detailURLRE: /\/www.yodobashi.com\/product\//,
- detailTitleXP: '//div[3]/h1[@id="products_maintitle"]/span[1]',
- detailTitleSearchXP: '//div[3]/h1[@id="products_maintitle"]/span[1][+++]/../../../../..',*/
- hideListEvenDetail: 1,
- observe: 500,
- automemoURLRE: /^https:\/\/www.yodobashi.com\/product\//,
- automemoSearchFunc: () => { return eletext(['//div[@id="pinfo_productSummury"]', '//div[@id="productSet1Box"]', '//div[@class="specBox"]', '//h1[@class="pName js_variHeight"]/span[1]']); },
- automemoFunc: () => {
- var cat = elegeta('//div[@class="txtnav clearfix"]');
- if ((cat.some(e => /ヘルス&ビューティー/.test(e.innerText)))) {
- [/(イソプロピルメチルフェノール)/m, /(IPMP)/m, /(塩化セチルピリジニウム|塩化セシルピリジニウム|セチルピリジニウム塩化物)/m, /(CPC)/m, /(塩化ベンザルコニウム)/m, /(BKC)/m, /(ラウロイルサルコシンナトリウム|ラウロイルサルコシンNa|ラウロイルサルコシンNa)/m, /(LSS)/m, /(塩化ベンゼトニウム)/m, /(BTC)/m, /(クロルヘキシジン)/m, /(CHG)/m, /(グリチルリチン酸アンモニウム)/m, /(イプシロン.アミノカプロン酸)/m, /(ε.ACA)/m, /(トラネキサム酸)/m, /(TXA)/m, /(グリチルリチン酸ジカリウム|グリチルリチン酸二カリウム|グリチルリチン酸2K|グリチルリチン酸2K|GK2)/mi, /(1\,?450\s?ppm)/m, /(高?濃?度?フッ化ナトリウム|高?濃?度?フッ素)/m, /(ハイドロオ?キシアパタイト)/m, /(リン酸化オリゴ糖カルシウム)/m, /(POs-Ca|POs-Ca)/mi, /(カゼインホスホペプチド.非結晶性リン酸カルシウム|リカルデント)/m, /(CPP-ACP)/m, /(チモール)/m, /(サリチル酸メ?チ?ル?)/m, /(1\,8-シネオール)/m, /(トリクロサン)/m, /(トリクロカルバン)/m, /(オクトピロックス|オクトロピックス|ピロクトン.?オラミン)/m, /(Znピリチオン|ジンクピリチオン)/m, /(硫黄|イオウ)/m, /(アラントイン)/m, /(グリチルリチン酸アンモニウム)/m, /(ミコナゾール硝?酸?塩?)/m, /(クロラムフェニコール)/m, /(フラジオマイシン硫?酸?塩?)/m, /(ナイスタチン)/m, /(塩化亜鉛)/m, /(ポビドン.?ヨード)/m, /(ラウリルジアミノエチルグリシンナトリウム)/m, /(カキタンニン)/m, /(チャエキス)/m, /(ローズマリー)/m, /(カンゾウ)/m, /(クマザサ)/m, /(セージ)/m, /(シソエキス)/m, /(β?-?グリチルレチン酸?)/m, /(メントール)/m, /(ポリリン酸ナトリウム|ポリリン酸Na)/m, /(ヒノキチオール)/m, /(ティーツリー油オ?イ?ル?)/m, /(ティートゥリー油オ?イ?ル?)/m].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /浄水器/.test(e.innerText)))) {
- // [/([0-90-9++].*?物質)/m, /(除?去?物質.{0,19}[0-90-9++]+)/m, /([0-90-9++]+?項目)/gm,/(交換.{1,19}[0-9.]+ヶ月)|(交換.{1,19}[0-9.]+年)|(取替.{1,19}[0-9.]+ヶ月)|(取替.{1,19}[0-9.]+年)/m].forEach(m => autoMemo(m)); //,/(除去物質数[\s\S]*\d+)/gm
- [/([0-90-9++].*?物質)/m, /([0-90-9++]+?項目)/gm, /(交換.{1,19}[0-9.]+ヶ月)|(交換.{1,19}[0-9.]+年)|(取替.{1,19}[0-9.]+ヶ月)|(取替.{1,19}[0-9.]+年)/m].forEach(m => autoMemo(m)); //,/(除去物質数[\s\S]*\d+)/gm
- }
- if ((cat.some(e => /電池/.test(e.innerText)))) {
- [/([\d\s\,]+mAh)/m, /([\d\s\,]+mAh)/m, /([\d\s\,]{2,9}回)/m].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /食器・グラス・カトラリー/.test(e.innerText)))) {
- [/(?:寸法|サイズ).*[::](.+)$/m, /容量[::](.+$)/m, /生産国[::](.+$)/m, /(深さ.*[::].+$)/m, /(\dつ穴)/m].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /シュレッダー/.test(e.innerText)))) {
- [/(細断サイズ[\s\S]{0,9}[0-9.]+×?[0-9.]*m?m?)/m, /ダストボックス(容量[\s\S]{0,9}[0-9.]+L)/m].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /食品/.test(e.innerText)))) {
- [/(食物繊維\D{0,9}[0-9.]+[gg])/m].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /圧力鍋/.test(e.innerText)))) {
- [/(低圧\D?\d+kpa)/mi, /(高圧\D?\d+kpa)/mi, /(圧力[\::]\d+kPa)/mi].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /ヘッドセット/.test(e.innerText)))) {
- [/(感度.{1,20}dB)/mi, /(\-\s*[0-90-9]+\s*dB)/mi].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /プランター/.test(e.innerText)))) {
- [/(容量[\s\S]{0,8}[0-9\.\,]+(?:L|L|リットル))/mi, /(容量\((?:L|L|リットル)\):[0-9\.\,]+)/mi].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /家電/.test(e.innerText)))) {
- [/(本体丸洗い[\s\S]{0,8}(?:可|不可))/mi, /(電源方式[\s\S]{0,8}充電・交流両式|充電式)/mi].forEach(m => autoMemo(m));
- }
- if ((cat.some(e => /入浴剤/.test(e.innerText))))[/\D(\d\dg)/m].forEach(m => autoMemo(m));
- if ((cat.some(e => /洗剤/.test(e.innerText))))[/(界面活性剤\s*[\((]+\s*\d+[\%%]+[^\))]*[\))]+)/m].forEach(m => autoMemo(m));
- },
- redoWhenReturned: 1,
- },
- {
- id: 'TSUGIMANGA',
- urlRE: '//tsugimanga.jp/',
- listTitleXP: '//div/div[@class="work__title"]',
- listTitleSearchXP: '//div/div[@class="work__title"][+++]/../..',
- listTitleMemoSearchXP: '//div/div[@class="work__title" and +++]',
- listGen: 5,
- },
- {
- id: 'NICOSEIGA_COMIC',
- urlRE: /\/\/seiga.nicovideo.jp\/(?:watch|comic|manga)\//,
- title: 'div.main_title>h1,div.description>div.title>a,div.inner_content>div>h1>span.episode_title,div.description_block>div>div>div.title>a,strong.mg_title>a',
- box: 'div.main_title,li.episode_item,li.mg_item.item,#mg_recent_inner li,div.inner.cfix div div.title h1', //'',
- forceTranslucentFunc: e => e.closest('div.main_title,div.inner.cfix div div.title h1'),
- trim: 1,
- listHelpJQS: 'div.main_title,li.episode_item,article#detail.vertical,li.mg_item.item,#mg_recent_inner li',
- redoWhenReturned: 1,
- disableHelpUrlRE: /\/watch\//,
- func: () => { if (lh('https://seiga.nicovideo.jp/comic/')) GM.addStyle(`.episode_item {float:none !important; display:inline-flex !important;}`) },
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- elegeta('li.episode_item:not([data-orgorder])').forEach((v, i) => v.dataset.orgorder = i)
- $(".yfokgk").remove()
- let menu = [
- //{ t: "メモ総長順", f: () => { sortdom(elegeta('.NC-MediaObject.NC-VideoMediaObject.VideoContainer-item'), v => (elegeta('.yhmMyMemoO', v)?.reduce((a, b) => b?.textContent?.length + a, 0) || 0) - (elegeta('.yhmMyMemoX', v).reduce((a, b) => b?.textContent?.length + a, 0) || 0), 1) } }, // ○メモとチャプターメモは+文字数、×メモは-文字数評価
- { t: "再生+コメント多", f: () => { sortdom(elegeta('li.episode_item'), v => Number(eleget0('div.counter', v)?.textContent?.match0(/再生\:(\d+)/) || 0) + Number(eleget0('div.counter', v)?.textContent?.match0(/コメント\:(\d+)/) || 0) * 100, 1) } },
- {
- t: "再生+コメント多2",
- f: () => {
- sortdom(elegeta('li.episode_item'), (v, i) => {
- v.dataset.giantkilling = Number(v.dataset.orgorder) - i;
- end(v, `<span class="yfokgk" style="color:#499">${v.dataset.giantkilling>0?"+":""}${v.dataset.giantkilling}</span>`);
- return Number(v.dataset.orgorder) - i
- }, 1)
- }
- }, // 再生数とコメント数は古い話ほど多いのが普通なのでその順からズレた順位=相対人気順で並べる
- { t: "メモ総長順", f: () => { sortdom(elegeta('li.episode_item'), v => (elegeta('.yhmMyMemoO', v)?.reduce((a, b) => b?.textContent?.length + a, 0) || 0) - (elegeta('.yhmMyMemoX', v).reduce((a, b) => b?.textContent?.length + a, 0) || 0), 1) } }, // ○メモとチャプターメモは+文字数、×メモは-文字数評価
- { t: "再生多", f: () => { sortdom(elegeta('li.episode_item'), v => Number(eleget0('div.counter', v)?.textContent?.match0(/再生\:(\d+)/) || 0), 1) } },
- { t: "再生少", f: () => { sortdom(elegeta('li.episode_item'), v => Number(eleget0('div.counter', v)?.textContent?.match0(/再生\:(\d+)/) || 0), 0) } },
- { t: "コメント多", f: () => { sortdom(elegeta('li.episode_item'), v => Number(eleget0('div.counter', v)?.textContent?.match0(/コメント\:(\d+)/) || 0), 1) } },
- { t: "コメント少", f: () => { sortdom(elegeta('li.episode_item'), v => Number(eleget0('div.counter', v)?.textContent?.match0(/コメント\:(\d+)/) || 0), 0) } },
- { t: "タイトル順", f: () => { sortdom(elegeta('li.episode_item'), v => (eleget0('.title', v)?.textContent), 0) } },
- { t: "url降順", f: () => { sortdom(elegeta('li.episode_item'), v => (eleget0('a', v)?.href), 1) } },
- { t: "url昇順", f: () => { sortdom(elegeta('li.episode_item'), v => (eleget0('a', v)?.href), 0) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == GF.yhmSortType ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF.yhmSortType].f()
- GF.yhmSortType = ((GF?.yhmSortType + 1) % menu.length)
- },
- }],
- },
- {
- id: 'NICOSEIGA',
- urlRE: '//seiga.nicovideo.jp/illust/ranking/point/',
- listGen: 5,
- // 項目名:投稿者名
- listTitleXP: '//span[@class="rank_txt_user"]/a',
- listTitleSearchXP: '//span[@class="rank_txt_user"]/a[+++]/../../../../../..',
- listTitleMemoSearchXP: '//span[@class="rank_txt_user"]/a[+++]',
- listHelpXP: '//tr/td[contains(@class,"rank_block_right rank_no_")]',
- },
- {
- id: 'NICOSEIGA',
- urlRE: '//seiga.nicovideo.jp/tag/|//seiga.nicovideo.jp/seiga/|//seiga.nicovideo.jp/user/illust/|//seiga.nicovideo.jp/illust/|//seiga.nicovideo.jp|//seiga.nicovideo.jp/my/personalize',
- listGen: 5,
- detailURLRE: /\/\/seiga.nicovideo.jp\/seiga\/|\/\/seiga.nicovideo.jp\/user\/illust\//,
- // 項目名:投稿者名
- listTitleXP: '//li[@class="user"]|.//span[@class="rank_txt_user"]/a|.//span[@class="popular_illust_block__item__info--nickname"]|.//p[@class="info_source"]/a[@class="user_name"]',
- listTitleSearchXP: '//li[@class="user" and +++]/../../..|.//span[@class="rank_txt_user"]/a[+++]/../../../..|.//span[@class="popular_illust_block__item__info--nickname" and +++]/../../..|.//p[@class="info_source"]/a[@class="user_name" and +++]/../../..',
- hideListEvenDetail: 1,
- listTitleMemoSearchXP: '//li[@class="user" and +++]/..|//ul/li[@class="user_name"]/strong[+++]/..|.//span[@class="nickname" and +++]/..|.//span[@class="rank_txt_user"]/a[+++]|.//span[@class="popular_illust_block__item__info--nickname" and +++]|.//p[@class="info_source"]/a[@class="user_name" and +++]',
- listHelpXP: '//li[contains(@class,"list_item list_no_trim2")]/a|.//tbody/tr/td[contains(@class,"rank_list_block rank_no_")]|.//div[@class="popular_illust_block__item"]|.//ul[@class="item_list"]/li[@class="list_item middle"]/a|.//div/ul[@class="item_list"]/li[@class="list_item middle"]/a|.//p[@class="info_source"]/a[@class="user_name"]/../../..',
- detailTitleXP: '//ul/li[@class="user_name"]/strong|//span[@class="nickname"]',
- detailTitleSearchXP: '//ul/li[@class="user_name"]/strong[+++]/../../../../../../../../../../../..|//span[@class="nickname" and +++]/../../../../../../..',
- },
- {
- id: 'KAKAKU',
- urlRE: '//kakaku.com/search_results/',
- listTitleXP: '//p[@class="p-item_name s-biggerlinkHover_underline"]',
- listTitleSearchXP: '//p[@class="p-item_name s-biggerlinkHover_underline"][+++]/../../../../..',
- listTitleMemoSearchXP: '//p[@class="p-item_name s-biggerlinkHover_underline"][+++]',
- listGen: 5,
- },
- {
- id: 'KAKAKU',
- urlRE: '//kakaku.com/specsearch|//kakaku.com/item/',
- listTitleXP: '//td[@class="textL"]/strong/a[1]',
- listTitleSearchXP: '//td[@class="textL"]/strong/a[1 and +++]/../../..',
- listTitleMemoSearchXP: '//td[@class="textL"]/strong/a[1 and +++]|//div[@class="boxL"]/h2[@itemprop="name" and +++]/..',
- listGen: 4,
- detailURLRE: /\/\/kakaku.com\/item\//,
- detailTitleXP: '//div[@class="boxL"]/h2[@itemprop="name"]',
- detailTitleSearchXP: '//div[@class="boxL"]/h2[@itemprop="name" and +++]/../../../..',
- },
- {
- id: 'HELLOWORK',
- urlRE: '//www.hellowork.mhlw.go.jp/kensaku/',
- listTitleXP: '//td[@class="fb in_width_9em" and text()="求人番号"]/following-sibling::td/div',
- listTitleSearchXP: '//td[@class="fb in_width_9em" and text()="求人番号"]/following-sibling::td/div[+++]/../../../../../../../../..|//div[@id="ID_kjNo"]',
- listTitleMemoSearchXP: '//td[@class="fb in_width_9em" and text()="求人番号"]/following-sibling::td/div[+++]/../../../..|//div[@id="ID_kjNo" and +++]/../../..',
- listHelpXP: '//td[@class="fb in_width_9em" and text()="求人番号"]/following-sibling::td/div/../../../../../../../../..',
- listGen: 8,
- detailURLRE: /Detail/i,
- detailTitleXP: '//div[@id="ID_kjNo"]',
- detailTitleSearchXP: '//div[@id="ID_kjNo" and +++]/../../../../..',
- func: () => { if (location.href.match(/detail/i)) { GM_addStyle('table.normal tr th, table.normal tr td { padding: 0.2em 1em;}') } else { GM_addStyle('table.kyujin th, table.kyujin td { padding: 0.5em 0.5em; } table.normal tr th, table.normal tr td { border-top: 1px solid #125939; padding: 0.5em 10px; text-align: left; } .mb03 { margin-bottom: 0em; }'); } },
- },
- {
- id: 'USERBENCHMARK',
- urlRE: '.*?.userbenchmark.com',
- listTitleXP: '//span/a[@class="nodec"]',
- listTitleSearchXP: '//span/a[@class="nodec" and +++]/../../../../..',
- listTitleMemoSearchXP: '//span/a[@class="nodec" and +++]|//h1[@class="pg-head-title"]/a[+++]',
- listGen: 5,
- observe: 1000,
- detailURLRE: /\/\/.*?.userbenchmark.com\/SpeedTest\/|\/\/.*?.userbenchmark.com\/.*?\/Rating\//i,
- detailTitleXP: '//h1[@class="pg-head-title"]/a',
- detailTitleSearchXP: '//h1[@class="pg-head-title"]/a[+++]/../../..',
- automemoURLRE: /\/\/.*?.userbenchmark.com\/SpeedTest\/|\/\/.*?.userbenchmark.com\/.*?\/Rating\//i,
- automemoSearchFunc: () => { return eletext('//h3[@class="pg-head-toption"]/span[@class="pg-head-toption-post"]') + "\n"; },
- automemoFunc: () => { autoMemo(/(.*)/); },
- },
- {
- urlRE: '//www.sukima.me/(?!bv|login)',
- id: 'SUKIMA',
- listTitleXP: '//div[@class="row ma-0 flex-nowrap align-center title-name-content"]/div',
- listTitleSearchXP: '//div[@class="row ma-0 flex-nowrap align-center title-name-content"]/div[***]/../../../..',
- listTitleMemoSearchXP: '//div[@class="row ma-0 flex-nowrap align-center title-name-content"]/div[***]',
- listHelpXP: '//div[@class="row ma-0 flex-nowrap align-center title-name-content"]/div/../../../..',
- listGen: 5,
- titleProcessFunc: title => { return title.replace(/\n\s*?\n\s*?|(?分冊版)?.*|【期間限定 無料お試し版】.*|[0-90-9]*?巻.*/g, "").trim() },
- observe: 1500,
- func: () => {
- document.title = document.title.replace(/(^\[.*\])(.*)/, "$2$1");
- } // ページタイトルの「[全話無料]」等の接頭辞を末尾に移動
- },
- {
- urlRE: '//www.mangaz.com/',
- // id: 'MANGAZ', // SUKIMAと登録内容を共通にしない
- id: 'SUKIMA', // SUKIMAと登録内容を共通にする
- title: 'div.listBoxDetail>h4>a,p.author,div.header h2,ul.seriesAuthor li a,span.sort-word' + `,ul.detailAuthor li span a`,
- box: '.itemList>li,div.seriesMain div.header,div.sort-inner' + `,ul.detailAuthor`,
- forceTranslucentFunc: e => e.closest('div.seriesMain div.header,div.sort-inner' + `,ul.detailAuthor`),
- observeFunc: e => e?.nodetype === 1 && e?.matches('.itemList>li,div.seriesMain div.header,div.sort-inner'),
- listHelpJPS: '.itemList>li,div.seriesMain div.header,div.sort-inner',
- listHelpXP2: 'p.author,ul.seriesAuthor li a',
- XP2name: '作者名 ',
- wholeHelp: [() => 1, " Shift+F:作品検索 A:ソート"],
- keyFunc: [{
- key: 'Shift+F', // Shift+F::キーワード検索
- func: () => { searchWithHistory("MANGAZ", "マンガ図書館Z", 'https://www.mangaz.com/title/index?category=&query=***&sort=&search=input', "") },
- }, {
- key: 'a', // a::ソート
- func: () => {
- var sorttype = GF.yhmSortType || 0;
- // $('.yhmSortType').remove(), $(document.body).append(`<span class="yhmSortType" id="${++sorttype%2}"></span>`)
- GF.yhmSortType = ++sorttype % 2
- popup2("A:ソート\n" + (["タイトル", "著者名"].map((c, i) => " " + c + (i + 1 == sorttype ? " ←\n" : "\n")).join("")), 6, "min-width:6em;")
- sorttype == 1 && sortdom(elegeta('.itemList>li'), v => eleget0('div.listBoxDetail>h4>a', v)?.textContent)
- sorttype == 2 && sortdom(elegeta('.itemList>li'), v => eleget0('.listBoxDetail>p', v)?.textContent)
- }
- }],
- titleProcessFunc: (title) => { return title.replace(/\s[0-90-9]+巻?$|【.*?】|全.*?巻|第\d*話/gmi, "").trim() },
- observe: 500,
- redoWhenRefocused: 1,
- func: () => {
- document.title = document.title.replace(/(^【.*】)(.*)/, "$2$1"); // ページタイトルの「[全話無料]」等の接頭辞を末尾に移動
- // 作品一覧の著者名をクリックで検索できるようにする
- elegeta('p.author:not([data-linked])').forEach((e, i, a) => {
- let author = e.textContent.trim().replace(/,/gm, " ").replace(/\s+/gm, " ")
- let url = 'https://www.mangaz.com/title/index?category=&query=***&sort=&search=input'.replace("***", encodeURI(author))
- e.dataset.linked = url
- e.style.cursor = "pointer"
- e.title = `クリックで「${author}」で作品検索をします\n${url}`
- e.addEventListener("click", v => window.open(v.target.dataset.linked, "", "noreferrer"))
- })
- }
- },
- {
- id: 'PICCOMA',
- urlRE: '//piccoma.com/',
- listTitleXP: '//div[@class="PCM-productCoverImage_title"]/span|.//div[@class="PCM-rankingProduct_title"]/p|.//p[@class="PCM-productCoverImage_title"]/span',
- listTitleSearchXP: '//div[@class="PCM-productCoverImage_title"]/span[+++]/ancestor::li[contains(@class,"PCM-slotProducts_list")]|.//div[@class="PCM-rankingProduct_tdata"]/div/p[+++]/ancestor::li[contains(@class,"PCM-slotProducts_list")]|.//p[@class="PCM-productCoverImage_title"]/span[+++]/ancestor::li[contains(@class,"PCM-slotProducts_list")]',
- listTitleMemoSearchXP: '//div[@class="PCM-productCoverImage_title"]/span[+++]', // 実質表示されない
- listGen: 7,
- observe: 3000,
- },
- {
- id: 'TAMESHIYOMI',
- urlRE: '//www.cmoa.jp/freecontents/',
- listTitleXP: '//p[@class="titile_name"]/a',
- listTitleSearchXP: '//p[@class="titile_name"]/a[+++]/../../../..',
- listTitleMemoSearchXP: '//p[@class="titile_name"]/a[+++]',
- listGen: 4,
- redoWhenReturned: 1,
- },
- {
- id: 'ja.aliexpress.com',
- urlRE: '//ja.aliexpress.com/',
- listTitleXP: '//h1[@class="_3eC3x"]/../../..',
- listTitleXP2: '//a[@class="ox0KZ"]',
- listHelpXP: '//h1[@class="_3eC3x"]/../../..',
- XP2name: 'セラー名 ',
- XP2memo: 1,
- listTitleSearchXP: '//a[**url**]/*/*/h1[@class="_3eC3x"]/../../..|//a[@class="ox0KZ"][+++]/../../..',
- listTitleMemoSearchXP: '//a[**url**]/*/*/h1[@class="_3eC3x"]|//a[@class="ox0KZ"][+++]',
- listGen: 3,
- useURL: 1,
- func: () => { // 商品名を全行表示する
- elegeta('//div[@class="product-container"]/div[2]/a/div[2]/div[1]/h1').forEach(e => {
- e.style.whiteSpace = "";
- e.style.height = "auto";
- e.style.whiteSpace = "normal";
- e.parentNode.style.display = "block"
- });
- },
- },
- {
- id: 'GREASYFORK',
- urlRE: '//gf.qytechs.cn/.*?/scripts',
- listTitleXP: `//a[@class="script-link"]|.//a[@class="script-link"]/font/font`, //'//article/h2/a',
- listTitleSearchXP: `//a[@class="script-link"][+++]/ancestor::li|.//a[@class="script-link"]/font/font[+++]/ancestor::li`, //'//article/h2/a[+++]/../../..|//article/h2/a/font/font[+++]/../../../../..',
- listTitleMemoSearchXP: `//a[@class="script-link"][+++]|.//a[@class="script-link"]/font/font[+++]/../..`, //'//article/h2/a[+++]|//article/h2/a/font/font[+++]/../..',
- listGen: 7,
- // func:(n)=>{elegeta('//h2/a[@class="script-link"]',n).forEach(e=>{$(e.parentNode.parentNode.parentNode).append(' <a style="float:right;margin:0 0 0 1em;" href="'+e.href+'/stats?period=all">統計</a>').append(' <a style="float:right;margin:0 0 0 1em;" href="'+e.href+'/feedback">フィードバック</a>')}) },
- },
- {
- id: 'JMTY',
- urlRE: '//jmty.jp/',
- listTitleXP: '//div[@class="p-item-title"]/a',
- listTitleSearchXP: '//div[@class="p-item-title"]/a[++url++]/../../..',
- listTitleMemoSearchXP: '//div[@class="p-item-title"]/a[++url++]',
- listGen: 5,
- useURL: 1,
- },
- {
- id: 'EBAY',
- urlRE: 'ebay.com/',
- listTitleXPIgnoreNotExist: 1,
- listTitleXP: '//div[@class="s-item__title"]/span[@role="heading"]/../..',
- listTitleSearchXP: '//div[@class="s-item__title"]/span[@role="heading"]/../..[**url**]/../../..',
- listTitleMemoSearchXP: '//div[@class="s-item__title"]/span[@role="heading"]/../..[**url**]|//h1[@class="x-item-title__mainTitle"]/span[1][**url**]/..',
- listGen: 5,
- detailTitleXP: '//h1[@class="x-item-title__mainTitle"]/span[1]',
- detailTitleSearchXP: '//h1[@class="x-item-title__mainTitle"]/span[1][**url**]/../../../../..',
- XP2memo: 1,
- XP2name: 'セラー名 ',
- listGen: 6,
- useURL: 1,
- funcOnlyFirst: () => {
- var e = eleget0('//link[@rel="canonical"]');
- var t = eleget0('//h1[@class="x-item-title__mainTitle"]/span[1]|//h1[@itemprop="name" and @id="itemTitle"]')
- if (e && t) t.setAttribute("href", e.href)
- },
- detailURLRE: /www.ebay.com\/itm\//,
- listHelpJQS: 'li.s-item',
- helpInBlock: 1,
- maxpriceXP: '//div/input[@aria-label="Maximum Value"]',
- }, {
- id: '2CHTHREADLIST',
- urlRE: /\/\/.*\.5ch\.net\/[^\/]*\/(\?v=pc)?$/,
- listTitleXP: '//td/a',
- listTitleSearchXP: '//table[@id="thread-list"]/tbody/tr/td/a[+++]/../..',
- listTitleMemoSearchXP: '//tr/td/a[+++]',
- listTitleMemoSearchXPSameGen: 1,
- listGen: 6,
- delay: 1000,
- observe: 500, // 並べ替え時に必要
- redoWhenReturned: 1,
- keyFunc: [{
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- // func: () => { searchWithHistory("REFIND2CH", "re.Find2ch", 'https://refind2ch.org/search?q=***&sort=rate', " OR ") },
- }],
- }, {
- urlRE: 'https://find.5ch.net/search',
- id: '2CHTHREADLIST',
- title: 'div.list_line_link_title,div.list_line_info_container.list_line_info_container-board>a',
- box: 'div.list_line',
- titleProcessFunc: v => v.replace(/\(\d+\)$/, "").trim(),
- titleSubstr: 1,
- redoWhenReturned: 1,
- XP2name: '板名 ',
- listHelpXP2: '//div[@class="list_line_info_container list_line_info_container-board"]/a',
- trim: 1,
- keyFunc: [{
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- }, {
- key: 'a', // a::
- func: () => {
- let menu = [
- { t: "勢い強", f: () => sortdom(elegeta('div.list_line'), v => { return (eleget0('//div/div[3]', v)?.textContent) }, 1) },
- { t: "メモ多", f: () => { sortdom(elegeta('div.list_line'), v => Number(elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- { t: "タイトル", f: () => sortdom(elegeta('div.list_line'), v => { return (eleget0('//a/div[@class="list_line_link_title"]', v)?.textContent) }, 0) },
- { t: "板名", f: () => sortdom(elegeta('div.list_line'), v => { return (eleget0('div.list_line_info_container-board>a', v)?.textContent?.trim()) }, 0) },
- { t: "新しい", f: () => sortdom(elegeta('div.list_line'), v => { return (eleget0('//div[@class="list_line_info_container"]', v)?.textContent) }, 1) },
- ]
- popup2("a:ソート\n" + (menu.map((c, i) => " " + c.t + (i == (GF?.yhmSortType % menu.length) ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF?.yhmSortType % menu.length].f()
- GF.yhmSortType = (GF?.yhmSortType || 0) + 1
- }
- }],
- wholeHelp: [() => 1, " A:ソート"], // Shift+F:スレッド検索
- }, { // 5chスレッド内 5ch::
- id: 'new5ch',
- urlRE: () => lh('.5ch.net/test/read.cgi/') && !lh("/c/"),
- title: 'details.post-header,.uid',
- listTitleXP2: '.uid',
- funcQ: e => e?.textContent?.match(/https:\/\/i\.imgur\.com\/[\w\.]+/gi)?.forEach(v => addNG(v)),
- XP2name: `ID `,
- box: 'article.post',
- memoStyle: "float:right;",
- memoOnRead: v => v?.concat((pref('5CH : SearchMyMemo') || [])?.map(v => { v.t = v.t.replace(/(\d\d\d\d\/\d\d\/\d\d\(.\))\s*(\d\d\:\d\d\:\d\d)/, "$1 $2").replace(/\>\>\d+/gm, ""); return v; })), // 旧5chで付けたメモも一方通行的に取り込む それらは旧5chでしか削除できない
- // delay: 5000+(Math.min(elegeta('article.post')?.length,1000)**2)/200,
- funcOnlyFirst: () => {
- if (eleget0('//span[@class="postid" and starts-with(text(),"0")]')) elegeta('.postid').forEach(e => e.textContent = Number(e.textContent))
- //if (IN5CH_REMOVE_AKABAN) elegeta('.post-header>summary>span:has( form)').filter(e => e?.textContent.indexOf("垢版") != -1).forEach(e => e?.remove())
- if (IN5CH_REMOVE_AKABAN) elegeta('.post-header>summary>span>form').filter(e => e?.textContent.indexOf("垢版") != -1).forEach(e => e?.remove())
- //if (IN5CH_REMOVE_AKABAN) elegeta('.post-header>summary>span').filter(e => e?.textContent == "垢版").forEach(e => e?.remove())
- }, // 0001みたいなゼロサプレスを削除
- redoWhenReturned: 1,
- redoWhenRefocused: 1,
- memoFunc: e => e?.parentNode?.querySelector(".post-content")?.previousElementSibling || e,
- hideSelectedWord: 1,
- delay: 333,
- selectedHelp: { help: [KEYHIDE + ":NGワードに追加"] }, //, multi: "複数行に渡る文字列は NG に入れられません" },
- listTitleSearchFunc: (title) => { // レス中キーワードNG
- let resHit = [];
- if (typeof title === "string" && /\D/m.test(title)) { // textContentでサーチする
- for (let res of elegeta('article.post')) { // レス本文
- if (res.textContent.indexOf(title) !== -1) resHit.push(res.closest("article.post"));
- }
- /* for (let res of elegeta('.uid')) { // ID
- if (res.textContent.indexOf(title) !== -1) resHit.push(res.closest("article.post"));
- }*/
- }
- return resHit;
- },
- keyFunc: [{
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- // func: () => { searchWithHistory("find5ch", "find5ch", ['https://find.5ch.net/search?q=***',`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`], " OR ") },
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- // func: () => { searchWithHistory("REFIND2CH", "re.Find2ch", 'https://refind2ch.org/search?q=***&sort=rate', " OR ") },
- }, {
- key: 'a', // a::
- func: () => {
- let menu = [
- { t: "引用", f: () => sortdom(elegeta('article'), v => { return -(v.querySelectorAll('.allpopup').length) }) },
- { t: "リンク", f: () => sortdom(elegeta('.post'), v => { return Number(v?.textContent?.match(/ttps?:\/\//gmi)?.length) * 10000 - (v.id) || 0 }, 1) },
- { t: "元", f: () => sortdom(elegeta('.post'), v => { return (v.id) }) },
- ]
- popup2("a:ソート\n" + (menu.map((c, i) => " " + c.t + (i == (GF?.yhmSortType % menu.length) ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF?.yhmSortType % menu.length].f()
- GF.yhmSortType = (GF?.yhmSortType || 0) + 1
- }
- }],
- wholeHelp: [() => 1, " A:ソート"], // Shift+F:スレッド検索
- }, {
- id: `${/shitaraba\.net/.test(location.href)?"SHITARABA":"5CH"}`, //'5CH',
- urlRE: '.5ch.net/test/read.cgi/|.shitaraba.net/bbs/read.cgi/|.shitaraba.net/bbs/read_archive.cgi/',
- // memoOnRead: v => v?.concat((pref('new5ch : SearchMyMemo') || [])?.map(v => { v.t = v.t.replace(/(\d\d\d\d\/\d\d\/\d\d\(.\))\s*(\d\d\:\d\d\:\d\d)/, "$1$2"); return v; })), // 新5chで付けたメモも一方通行的に取り込む それらは新5chでしか削除できない
- memoOnRead: v => v?.concat((pref('new5ch : SearchMyMemo') || [])?.map(v => { v.t = v.t.replace(/\s/g, ""); return v; })), // 新5chで付けたメモも一方通行的に取り込む それらは新5chでしか削除できない
- listTitleXP2: '//span[@class="uid"]',
- listTitleXPIgnoreNotExist: 1,
- memoStyle: 'float:right;', //' margin-bottom:1px;',
- forceRunIffunc: () => { return /\.shitaraba\.net\/bbs\/read\.cgi\//.test(location.href) || eleget0('.thread > dd:nth-child(2)') },
- hideSelectedWord: 1,
- selectedHelp: { help: [KEYHIDE + ":NGワードに追加"] }, //, multi: "複数行に渡る文字列は NG に入れられません" },
- titleProcessFunc: (title) => { return /^\d{1,4}.+\d\d\d\d\/\d\d\/\d\d\(.\)\s..\:/.test(title.replace(/\n/gm, "").trim()) ? title?.replace(/⋮/g, "").replace(/\>\>.*$|\[\d*\]$/, "").replace(/\n| |\s|:/g, "").trim() : title?.replace(/⋮/g, "").replace(/\n/gm, "").replace(/\>\>.*$|\[\d*\]$/, "").trim() },
- XP2name: 'ID ',
- listTitleXP: '//div[@class="meta"]', // 項目名はレス番~IDまでの一連のdiv.meta
- listTitleSearchXP: '//div[@class="meta"][**alt**]/..|//span[@class="escaped"][***]/../..',
- listTitleMemoSearchXP: '//div[@class="meta"][**alt**]/span[@class="date"]',
- listHelpXP: '//div[@class="post"]',
- listGen: 6,
- searchAllowLength: 1,
- delay: 100, //delayAutoWeighting: 0.6, // 5chサムネイル表示他のhNukiURLHokan()より後でないとメモを消せなくなる
- keyFunc: [{
- key: 'Shift+F', // Shift+F::refind2chでキーワード検索
- func: () => { searchWithHistory("find5ch,掲示板横断検索,re.find2ch,ff5ch", "find5ch,掲示板横断検索,re.find2ch,ff5ch", [`https://zzzsearch.com/bbs/#gsc.q=%22***%22&gsc.sort=date`, `https://refind2ch.org/search?q=***&sort=rate`, 'https://find.5ch.net/search?q=***', `https://ff5ch.syoboi.jp/?q=***`], " OR ") },
- }, {
- key: 'a', // a::
- func: () => {
- var sorttype = Number($('.yhmSortType')?.attr("id") || 0);
- $('.yhmSortType').remove();
- $(document.body).append(`<span class="yhmSortType" id="${++sorttype}"></span>`)
- popup2("A:ソート\n" + (["引用", "リンク", "古い順"].map((c, i) => " " + c + (i + 1 == sorttype ? " ←\n" : "\n")).join("")), 6, "min-width:6em;")
- $(".thread>br,#thread-body>br").remove()
- switch (sorttype) {
- case 1:
- domsort(eleget0('.thread,#thread-body'), elegeta('.post'), v => { return -(v.querySelectorAll('.allpopup').length) }, 1)
- break;
- case 2:
- domsort(eleget0('.thread,#thread-body'), elegeta('.post'), v => { return Number((v?.textContent?.match(/ttps?:\/\//gmi)?.length)) && -1 - Number((v.querySelectorAll('.allpopup').length)) || 0 }, 1)
- break;
- case 3:
- domsort(eleget0('.thread,#thread-body'), elegeta('.post'), v => { return (v.id) }, 1)
- $('.yhmSortType').remove();
- break;
- }
- $('.post').after("<br>")
- }
- }],
- wholeHelp: [() => 1, " A:ソート"],
- listTitleSearchFunc: (title) => { // レス中キーワードNG
- let resHit = [];
- if (typeof title === "string" && /\D/m.test(title)) { // textContentでサーチする
- for (let res of elegeta('.message')) { // レス本文
- if (res.textContent.indexOf(title) !== -1) resHit.push(res.parentNode);
- }
- for (let res of elegeta('.uid')) { // ID
- if (res.textContent.indexOf(title) !== -1) resHit.push(res.parentNode.parentNode);
- }
- }
- return resHit;
- },
- funcQ: function() {
- setTimeout(() => {
- $('div.post:hidden').next("br").css("display", "none");
- $('div.post:visible').next("br:hidden").css("display", "block");
- }, 200);
- }, //余計な改行を詰める
- funcB: () => SITE.funcQ(),
- funcOnlyFirst: () => {
- GM_addStyle('.uid:hover{background:#ddeeffc0; border: 0px solid #ddeeffc0; color: #000000; text-shadow: 0 0 4px #ddeeffc0; box-shadow: inset 0 0 6px #ddeeffc0, 0 0 6px #ddeeffc0; }')
- // 旧表示なら対応するために加工
- if (/\.shitaraba\.net\/bbs\/read\.cgi\/|\.shitaraba\.net\/bbs\/read_archive.cgi\//.test(location.href)) $('dl.rep-comment:hidden').remove(); // したらばでは本家の>>1等のアンカーの中に見えないHTMLのコピーがありQ等がそれに反応してしまうので消す
- if (/\.5ch\.net\/test\/read\.cgi\/|\.shitaraba\.net\/bbs\/read\.cgi\/|\.shitaraba\.net\/bbs\/read_archive.cgi\//.test(location.href) && eleget0("//div/dl/dt|//body/dl/dt")) {
- if (/\.shitaraba\.net\/bbs\/read/.test(location.href) && eleget0("//div/dl/dt|//body/dl/dt")) { $('dl>br').remove() }
- elegeta('.thread dd').forEach(e => elegeta('br', e)?.pop()?.remove()) // 本文末尾の空改行をtrim
- var res1 = elegeta("//div/dl/dt|//body/dl/dt").slice(0, 1001)
- var res2 = elegeta("//div/dl/dd|//body/dl/dd").slice(0, 1001)
- if (res1.length && res1.length == res2.length) {
- GM_addStyle('div.post{border-width: 1px; display: inline-block; border-style: none solid solid none; border-color: #ddd; background-color: #efefef; margin-bottom: 8px; padding: 8px;}div.meta { margin: 0 0 0.33em; } .message { font-size: 17px; color: #333; padding: 2px 0 10px; overflow-wrap: break-word; }')
- GM_addStyle('div.post2{background-color:#efefef; display:inline-block; padding:1em; margin:0; box-shadow: 1px 1px 2px #cccccc;} div.meta{margin:0 0 0.33em;} ') // line-height:1.2em;
- var e = eleget0('//div/dl[@class="thread"]/../../../..|//div[@id="thread-body-wrapper"]/..');
- if (e) e.style.backgroundColor = "#f2f3f7";
- var e = eleget0('//body/div/span[@style="float:left;"]');
- if (e) e.style.float = "none";
- res1.forEach((e, i) => {
- var res1t = e.textContent; // innerTextは遅い
- var res2o = res2[i].outerHTML; //alert(res2o)
- while (/<br>[\s]{0,22}\<\/dd\>/.test(res2o)) res2o = res2o.replace(/<br>[\s]{0,22}\<\/dd\>/, "</dd>"); // 後ろの空改行をtrim
- e.outerHTML = `<div class="post"><div class="meta" alt="${res1t.replace(/ |\s|:/g,"").trim()}"><span class="date">${res1[i].innerHTML}</span></div><div class="message"><span class="escaped">${res2o.replace(/^<dd>/,"").replace(/<\/dd>/,"")}</span></div></div><br>`;
- res2[i].remove();
- });
- }
- elegeta('//div[@class="post"]/div[1]/span[@class="date"]').slice(0, 1001).forEach(e => { e.closest(".post").id = e.textContent.trim().match0(/^\d+/) || null; })
- adja(document.body, "beforeend", "<span id='ch5styleoldnewmodend'><span>"); //加工終了を告げる
- }
- //ct(() => { if (ld(".5ch.net")) elegeta('.number').forEach(e => e.innerText = Number(e.innerText)) }) //test 25 / 1sec
- if (ld(".5ch.net") && lh('/test/read.cgi/')) elegeta('.number').forEach(e => e.innerText = Number(e.innerText)) //test 25 / 1sec
- //ct(() => { if (ld(".5ch.net")) elegeta('.number').forEach(e => e.textContent = Number(e.innerText)) }) //test 26 / 1sec
- //ct(() => { if (ld(".5ch.net")) elegeta('.number').forEach(e => e.innerText= Number(e.textContent)) }) //test 148 / 1sec
- //ct(() => { if (ld(".5ch.net")) elegeta('.number').forEach(e => e.textContent = Number(e.textContent)) }) //test 158 / 1sec
- },
-
- func: () => {
- for (let e of elegeta('//div[@class="meta"][not(@alt)]').slice(0, 1001)) { // レスの特定のために1行目をまとめてtitle属性に埋める
- let id = e.innerText.replace(/>>.*/g, "").replace(/ |\s|:/g, "").trim();
- e.setAttribute("alt", id); // e.style.pointerEvents="none";
- };
- SITE.funcQ();
- },
- hideSelectedWord: 1,
- },
- {
- id: 'NICODOUGA',
- urlRE: '//www.nicovideo.jp/ranking',
- title: 'h2.NC-CardTitle.NC-CardTitle_fixed3Line',
- box: 'div.NC-Card',
- redoWhenRefocused: 1,
- //listTitleXP: '//div/h2[@class="MediaObjectTitle VideoMediaObject-title MediaObjectTitle_fixed2Line"]',
- //listTitleSearchXP: '//div/h2[@class="MediaObjectTitle VideoMediaObject-title MediaObjectTitle_fixed2Line"][+++]/../../../../..',
- //listTitleMemoSearchXP: '//div/h2[@class="MediaObjectTitle VideoMediaObject-title MediaObjectTitle_fixed2Line"][+++]',
- //listGen: 6,
- },
- {
- id: 'NICODOUGA',
- urlRE: '//www.nicovideo.jp/series/',
- listTitleXP: '//div[@class="VideoMediaObject-title"]/a',
- listTitleSearchXP: '//div[@class="VideoMediaObject-title"]/a[+++]/../../../..',
- listTitleMemoSearchXP: '//div[@class="VideoMediaObject-title"]/a[+++]',
- listGen: 5,
- listTitleHelpXP: '//div[@class="VideoMediaObject-title"]/a/../../../..',
- redoWhenRefocused: 1,
- },
- {
- id: 'NICODOUGA', // nicosea::
- urlRE: '//www.nicovideo.jp/search/|//www.nicovideo.jp/tag/|//www.nicovideo.jp/watch/',
- title: 'ul.videoListInner li.item p.itemTitle>a,a.nrn-contributor-link,div h1.VideoTitle,.nrn-movie-tag-link,p.itemTitle>a',
- box: 'ul.videoListInner li.item , div.WatchAppContainer-main',
- redoWhenRefocused: 1,
- observe: 1000,
- forceTranslucentFunc: () => lh('https://www.nicovideo.jp/watch/'),
-
- //listGen: 7,
- preventHelpFunc: () => lh('https://www.nicovideo.jp/watch/') && document.fullscreenElement,
- /*detailURLRE: /\/watch\//,
- detailTitleXP: '//div/div[@class="HeaderContainer-topAreaLeft"]/h1[@class="VideoTitle"]',
- detailTitleSearchXP: '//div/div[@class="HeaderContainer-topAreaLeft"]/h1[@class="VideoTitle"][+++]',
- */
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- // key: "l", // l::
- key: "s", // s::
- func: (e, evt) => {
- let targets = (elegeta('//div/p[@class="itemTitle"]/a|//h1[contains(@class,"VideoTitle")]'))
- var one = document.elementFromPoint(mousex, mousey)
- //let hover=(eleget0('yt-formatted-string:hover,a:hover'))
- if (targets.includes(one)) {
- //動画タイトル上でsキーでその動画を含む再生リストを検索する
- let title = one?.innerText?.trim()
- let u = encodeURIComponent(title)
- if (u) {
- evt.preventDefault();
- evt.stopPropagation(); // 有効なlキーだったら本来の機能(10秒進む)をキャンセル
- let searchurl1 = `https://www.google.co.jp/search?q=${title.trim()} site:https://www.nicovideo.jp/user/*/mylist/`
- let searchurl = `https://www.google.co.jp/search?q=${u} site:https://www.nicovideo.jp/user/*/mylist/`
- if (confirm(`s:指したタイトルを含む再生リストを検索する\n\n${searchurl1}\n↓\n${searchurl}\n\nを開きます。よろしいですか?`)) {
- elegeta('video').forEach(v => v.pause());
- window.open(searchurl, "", "noreferrer")
- }
- }
- }
- return false;
- },
- },
- {
- key: 'a', // a::
- func: () => {
- if (lh("/watch")) return;
- var sorttype = GF.yhmSortType || 0;
- let menu = [
- { t: "メモ多", f: () => { sortdom(elegeta('ul.videoListInner li.item:visible'), v => Number(elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- { t: "タイトル", f: () => { sortdom(elegeta('ul.videoListInner li.item:visible'), v => eleget0('//p[@class="itemTitle"]/a', v)?.textContent) } },
- { t: "投稿者", f: () => { sortdom(elegeta('ul.videoListInner li.item:visible'), v => eleget0('//a[@class="nrn-contributor-link"]', v)?.textContent) } },
- { t: "いいね+マイリス", f: () => { sortdom(elegeta('ul.videoListInner li.item:visible'), v => (0 + Number(eleget0('//li[4]/span[@class="value"]', v)?.textContent || 0) + Number(eleget0('//li[3]/span[@class="value"]', v)?.textContent || 0)) || -1, 1) } },
- { t: "いいね+マイリス+コメント", f: () => { sortdom(elegeta('ul.videoListInner li.item:visible'), v => (Number(eleget0('//li[2]/span[@class="value"]', v)?.textContent || 0) + Number(eleget0('//li[4]/span[@class="value"]', v)?.textContent || 0) + Number(eleget0('//li[3]/span[@class="value"]', v)?.textContent || 0)) || -1, 1) } },
- { t: "いいね+マイリス+コメント+再生", f: () => { sortdom(elegeta('ul.videoListInner li.item:visible'), v => (Number(eleget0('//li[2]/span[@class="value"]', v)?.textContent || 0) + Number(eleget0('//li[4]/span[@class="value"]', v)?.textContent || 0) + Number(eleget0('//li[3]/span[@class="value"]', v)?.textContent || 0) + Number(eleget0('li.count.view>span', v)?.textContent?.replace(/\,/gm, "") || 0) / 1000) || -1, 1) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- }
- }, {
- key: 'u', // u::チャプターメモ
- func: (e) => {
- chapterMemo(/watch/, '//div/div[@class="HeaderContainer-topAreaLeft"]/h1[@class="VideoTitle"]', `https://www.nicovideo.jp/watch/${(location.href.match0(/\/watch\/([^/?]+)/))}?from=**time**`)
- },
- }, {
- key: 'Shift+U', // Shift+U::チャプターメモをクリップボードにコピー
- func: (e) => {
- chapterMemo(/watch/, '//div/div[@class="HeaderContainer-topAreaLeft"]/h1[@class="VideoTitle"]', `https://www.nicovideo.jp/watch/${(location.href.match0(/\/watch\/([^/?]+)/))}?from=**time**`, 1)
- },
- }
- ],
- funcOnlyFirst: () => {
- document.addEventListener('fullscreenchange', (event) => { if (document.fullscreenElement && $('video')[0] && $('video')[0].paused == false) { $("#yafuokuhelp").hide(200) } else { $("#yafuokuhelp").show(300) } })
- var observeUrlHasChangedhref = location.href;
- var observeUrlHasChanged = new MutationObserver(mutations => {
- if (observeUrlHasChangedhref !== location.href) {
- pauseAll = 1;
- prefCacheClear();
- observeUrlHasChangedhref = location.href;
- elegeta('//span[contains(@class,"yhmMyMemo")]/..').forEach(e => e.remove());
- setTimeout(() => {
- pauseAll = 0;
- run(document.body, "returned")
- }, 3500);
- }
- });
- observeUrlHasChanged.observe(document, { childList: true, subtree: true });
- },
- }, {
- id: 'NICODOUGA', // タイトルをキーにする
- urlRE: '//www.nicovideo.jp/user/.*/video|//www.nicovideo.jp/user/.*/series',
- title: 'h2.NC-MediaObjectTitle.NC-VideoMediaObject-title.NC-MediaObjectTitle_fixed2Line',
- box: 'div.NC-MediaObject',
- redoWhenRefocused: 1,
-
- /*listTitleXP: '//div[@class="NC-MediaObject-bodyTitle"]/h2',
- listTitleSearchXP: '//div[@class="NC-MediaObject-bodyTitle"]/h2[+++]/../../../../..',
- listTitleMemoSearchXP: '//div[@class="NC-MediaObject-bodyTitle"]/h2[+++]',
- listGen: 5,*/
- observe: 500,
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- let menu = [
- { t: "メモ総長順", f: () => { sortdom(elegeta('.NC-MediaObject.NC-VideoMediaObject.VideoContainer-item'), v => (elegeta('.yhmMyMemoO', v)?.reduce((a, b) => b?.textContent?.length + a, 0) || 0) - (elegeta('.yhmMyMemoX', v).reduce((a, b) => b?.textContent?.length + a, 0) || 0), 1) } }, // ○メモとチャプターメモは+文字数、×メモは-文字数評価
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == GF.yhmSortType ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF.yhmSortType].f()
- GF.yhmSortType = ((GF?.yhmSortType + 1) % menu.length)
- },
- }],
- // func: function(node) { for (let ele of elegeta('//div/p[@class="itemTitle"]/a', node)) ele.textContent = ele.title; }, // 長いタイトルが...で省略されているとヒットしないのでtitleプロパティから取り出す
- }, {
- id: 'NICODOUGA', // タイトルをキーにする
- urlRE: '//www.nicovideo.jp/user/.*?/mylist/', // バグらなくなった
- title: 'h2.NC-MediaObjectTitle.NC-VideoMediaObject-title.NC-MediaObjectTitle_fixed2Line',
- box: 'div.NC-MediaObject',
- redoWhenRefocused: 1,
-
- /*listTitleXP: '//div[@class="NC-MediaObject-bodyTitle"]/h2',
- listTitleSearchXP: '//div[@class="NC-MediaObject-bodyTitle"]/h2[+++]/../../../../..',
- listTitleMemoSearchXP: '//div[@class="NC-MediaObject-bodyTitle"]/h2[+++]',
- listGen: 6,*/
- observe: 500,
- listTitleXPIgnoreNotExist: 1,
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- key: 'a', // a::
- func: () => {
- let menu = [
- { t: "メモ総長順", f: () => { sortdom(elegeta('div.NC-MediaObject.NC-VideoMediaObject.MylistItem.MylistItemList-item.NC-VideoMediaObject_thumbnailWidth192.NC-MediaObject_withAction.NC-MediaObject_withFooter'), v => (elegeta('.yhmMyMemoO', v)?.reduce((a, b) => b?.textContent?.length + a, 0) || 0) - (elegeta('.yhmMyMemoX', v).reduce((a, b) => b?.textContent?.length + a, 0) || 0), 1) } }, // ○メモとチャプターメモは+文字数、×メモは-文字数評価
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == GF.yhmSortType ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF.yhmSortType].f()
- GF.yhmSortType = ((GF?.yhmSortType + 1) % menu.length)
- },
- }],
- // reloadWhenUrlHasChanged:1,
- },
- {
- id: 'NICODOUGA',
- urlRE: '//www.nicovideo.jp/my/mylist|www.nicovideo.jp/my/watchlater',
- listTitleXP: '//h2[@class="NC-MediaObjectTitle NC-VideoMediaObject-title NC-MediaObjectTitle_fixed2Line"]',
- listTitleSearchXP: '//h2[@class="NC-MediaObjectTitle NC-VideoMediaObject-title NC-MediaObjectTitle_fixed2Line"][+++]/../../../../../..',
- listTitleMemoSearchXP: '//h2[@class="NC-MediaObjectTitle NC-VideoMediaObject-title NC-MediaObjectTitle_fixed2Line"][+++]',
- redoWhenRefocused: 1,
- delay: 2000,
- listGen: 5,
- listTitleXPIgnoreNotExist: 1,
- // reloadWhenUrlHasChanged:1,
- wholeHelp: [() => 1, " A:ソート"],
- keyFunc: [{
- // key: "l", // l::
- key: "s", // s::
- func: (e, evt) => {
- let targets = (elegeta('//h2[@class="NC-MediaObjectTitle NC-VideoMediaObject-title NC-MediaObjectTitle_fixed2Line"]'))
- var one = document.elementFromPoint(mousex, mousey)
- //let hover=(eleget0('yt-formatted-string:hover,a:hover'))
- if (targets.includes(one)) {
- //動画タイトル上でsキーでその動画を含む再生リストを検索する
- let title = one?.innerText?.trim()
- let u = encodeURIComponent(title)
- if (u) {
- evt.preventDefault();
- evt.stopPropagation(); // 有効なlキーだったら本来の機能(10秒進む)をキャンセル
- let searchurl1 = `https://www.google.co.jp/search?q=${title.trim()} site:https://www.nicovideo.jp/user/*/mylist/`
- let searchurl = `https://www.google.co.jp/search?q=${u} site:https://www.nicovideo.jp/user/*/mylist/`
- if (confirm(`s:指したタイトルを含む再生リストを検索する\n\n${searchurl1}\n↓\n${searchurl}\n\nを開きます。よろしいですか?`)) {
- elegeta('video').forEach(v => v.pause());
- window.open(searchurl, "", "noreferrer")
- }
- }
- }
- return false;
- },
- },
- {
- key: 'a', // a::
- func: () => {
- if (lh("https://www.nicovideo.jp/my/watchlater|https://www.nicovideo.jp/my/mylist/")) {
- var sorttype = GF.yhmSortType || 0
- let menu = [
- // { t: "時間長", f: () => { sortdom(elegeta('//section[@class="WatchLaterContainer"]/div[last()]/div'), v => Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, "")), 1) } },
- // { t: "時間短", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => Number(v?.querySelector('span.ytd-thumbnail-overlay-time-status-renderer')?.textContent?.replace(/[^0-9]/gmi, ""))) } },
- { t: "メモ多", f: () => { sortdom(elegeta('//div[@class="VideoMediaObjectList"]/div'), v => (elegeta('.yhmMyMemoO', v)?.length || 0) - (elegeta('.yhmMyMemoX', v)?.length || 0), 1) } }, // ○メモとチャプターメモは+1、×メモは-1評価
- // { t: "タイトル", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('#video-title', v)?.textContent?.trim()) } },
- // { t: "投稿者", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('div.style-scope.ytd-channel-name yt-formatted-string a', v)?.textContent?.trim() || "") } },
- // { t: "再生多", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//yt-formatted-string[@id="video-info"]/span[@dir="auto" and @class="style-scope yt-formatted-string" and contains(text(),"回視聴")]', v)?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 1) } },
- // { t: "再生少", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//yt-formatted-string[@id="video-info"]/span[@dir="auto" and @class="style-scope yt-formatted-string" and contains(text(),"回視聴")]', v)?.textContent; return parseFloat(n) * (n?.match0("万") ? 10000 : n?.match0("億") ? 100000000 : 1) }, 0) } },
- // { t: "古い", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//div[@id="metadata"]/div/yt-formatted-string/span[contains(text(),"前")]', v)?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 1) } },
- //{ t: "新しい", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => { let n = eleget0('//div[@id="metadata"]/div/yt-formatted-string/span[contains(text(),"前")]', v)?.textContent; return parseFloat(n) * (n?.match0("時間") ? 0.0416 : n?.match0("分") ? 0.00025 : n?.match0("週間") ? 7 : n?.match0("か月") ? 31 : n?.match0("年") ? 365 : 1) }, 0) } },
- // { t: "逆順", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('//yt-formatted-string[@id="index"]', v)?.textContent, 1) } },
- // { t: "元順", f: () => { sortdom(elegeta('#contents ytd-playlist-video-renderer'), v => eleget0('//yt-formatted-string[@id="index"]', v)?.textContent, 0) } },
- ]
- popup2("A:ソート\n" + (menu.map((c, i) => " " + c.t + (i == sorttype ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[sorttype].f()
- GF.yhmSortType = (++sorttype) % menu.length
- return
- }
- }
- }
- ],
- },
- {
- id: 'RTINGS',
- urlRE: 'www.rtings.com/.*?/tools/table|//www.rtings.com/.*?/reviews/',
- listTitleXP: '//div/div[@class="table_cell_product-name"]',
- listTitleSearchXP: '//div/div[@class="table_cell_product-name"][***]/../../../../..',
- listTitleMemoSearchXP: '//div/div[@class="table_cell_product-name"][***]/..|//span[@class="e-page_title-primary"][***]',
- listGen: 3,
- listTitleXPIgnoreNotExist: 1,
- delay: 3000,
- observe: 1000,
- detailURLRE: /\/\/www.rtings.com\/.*?\/reviews\//,
- detailTitleXP: '//span[@class="e-page_title-primary"]',
- detailTitleSearchXP: '//span[@class="e-page_title-primary"][***]/../../../../..',
- },
- {
- id: 'TAMESHIYOMI',
- urlRE: 'csbs.shogakukan.co.jp',
- listTitleXP: '//div[1]/img[@class="is-item-cover loaded"]',
- listTitleSearchXP: '//div[1]/img[@class="is-item-cover loaded" and ++alt++]/../../..',
- listTitleMemoSearchXP: '//div[1]/img[@class="is-item-cover loaded" and ++alt++]',
- listGen: 3,
- listTitleXPIgnoreNotExist: 1,
- delay: 1000,
- observe: 1500,
- redoWhenReturned: 1,
- },
- {
- id: 'TAMESHIYOMI',
- urlRE: '//sokuyomi.jp/free_',
- listTitleXP: '//p[@class="title"]/a|//h1[@class="title"]',
- listTitleSearchXP: '//p[@class="title"]/a[++title++]/../..',
- listTitleMemoSearchXP: '//p[@class="title"]/a[++title++]', // 多分表示されない
- listGen: 3,
- observe: 900,
- listHelpXP: '//div[@id="content"]/div/ul/li',
- redoWhenReturned: 1,
- },
- {
- id: 'TAMESHIYOMI',
- urlRE: '//sokuyomi.jp/free\.',
- listTitleXP: '//img[@class="waku"]',
- listTitleSearchXP: '//img[@class="waku" and ++alt++]/../..',
- listTitleMemoSearchXP: '//img[@class="waku" and ++alt++]',
- listHelpXP: '//div[@id="content"]/div/ul/li',
- listGen: 3,
- observe: 600,
- redoWhenReturned: 1,
- },
- {
- urlRE: '//ebookjapan.yahoo.co.jp/viewer',
- func: () => {
- //$().ready(() => { setTimeout(() => { document.title = (eleget0('//div[@class="header__title"]').innerText || "") + " " + document.title; }, 2000); });
- },
- },
- {
- id: 'TAMESHIYOMI',
- urlRE: '//ebookjapan.yahoo.co.jp/free|//ebookjapan.yahoo.co.jp/ranking/details/free/',
- listTitleXP: '//p[@class="book-item__title"]',
- listTitleSearchXP: '//p[@class="book-item__title"][***]/../..',
- listTitleMemoSearchXP: '//p[@class="book-item__title"][***]',
- listGen: 3,
- titleProcessFunc: (title) => { return title.replace(/\s[0-90-9]+巻?$/gmi, "").replace(/[(\(][0-90-9]+巻?[)\)]$/gmi, "").replace(/【期間限定.*?】|【フルカラー】/g, "").replace(/\s\d+冊/gmi, "").replace(/\.\.\./gmi, "").trim() },
- observe: 1000,
- redoWhenReturned: 1,
- },
- {
- id: 'TAMESHIYOMI',
- urlRE: 'booklive.jp/index/no-charge',
- listTitleXP: '//p[@class="p-no-charge-book-item__title"]/a',
- listTitleSearchXP: '//p[@class="p-no-charge-book-item__title"]/a[***]/../../..',
- listTitleMemoSearchXP: '//p[@class="p-no-charge-book-item__title"]/a[***]',
- listGen: 5,
- titleProcessFunc: (title) => { return title.replace(/\s[0-90-9]+巻?$/gmi, "").replace(/[(\(][0-90-9]+巻?[)\)]/gmi, "").replace(/【.*?】|(.*?)|分冊版[\s::]*|合冊版[\s::]*/g, "").replace(/第?[0-90-9]+話?$/gmi, "").trim() },
- listTitleXPIgnoreNotExist: 1,
- observe: 1000,
- redoWhenReturned: 1,
- },
- {
- id: 'WCA',
- urlRE: 'webcomics\.jp',
- title: '.entry-title>a:first-child,.entry-site>a:first-child,div.comic-title>h2>a:nth-child(1),.comic-site>a',
- box: ".entry,#main-container #main",
- trim: 1,
- XP2name: 'サイト名 ',
- XP2memo: 1,
- listHelpJQS: 'div.entry',
- helpInBlock: 1,
- redoWhenReturned: 1,
- func: function(node) { // width 880-600→1180-900
- if (node === document.body && document.documentElement.clientWidth > 1200 && ($("#page").css("width")) == "880px") {
- $("#main-container").css("width", "900px");
- $("#page").css("width", "1180px");
- }
- },
- autoTranslucentURLRE: /mylist|bookmark|https:\/\/webcomics\.jp\/[^\/]+\/\d+$/,
- wholeHelp: [() => 1, ` u:重複作品を隠す h:ソート`],
- keyFunc: [{
- key: 'u', // u::uniq
- func: () => {
- let undup = [],
- dup = []
- elegeta('div.entry-title>a:first-child:visible').reverse().sort((a, b) => eleget0('.entry-site>a:first-child', a.closest(".entry")).innerText.match0(/ComicWalker|ヤンマガWeb|ガンマ/gmi) ? 1 : -1).forEach(e => {
- if (undup.includes(e.textContent?.trim())) {
- e.scrollIntoView({ behavior: "instant", block: "center", inline: "center" });
- $(e.closest(".entry")).hide(999, function() { $(this).remove() }); //e?.closest(".entry")?.remove()
- dup.push(e.textContent?.trim())
- } else { undup.push(e.textContent?.trim()) }
- })
- popup2(`u:重複タイトルを隠す\n${dup.join("\n")}`, 6)
- }
- }, {
- key: 'h', // h::
- func: () => {
- let menu = [
- { t: "メモ総長順", f: () => { sortdom(elegeta('.entry'), v => (elegeta('.yhmMyMemoO,[data-gakusai]', v)?.reduce((a, b) => b?.textContent?.length + a, 0) || 0) - (elegeta('.yhmMyMemoX', v).reduce((a, b) => b?.textContent?.length + a, 0) || 0), 1) } }, // ○メモとチャプターメモは+文字数、×メモは-文字数評価
- { t: "名前順", f: () => domsort("", elegeta('.entry'), (v) => { return ((v.querySelector('div.entry-title>a')).innerText?.trim()) || "" }, 3) },
- { t: "作者順", f: () => domsort("", elegeta('.entry'), (v) => { return eleget0('//a[@class="autele aut autname"]', v)?.innerText?.trim() || "" }, 3) },
- { t: "サイト順", f: () => domsort("", elegeta('.entry'), (v) => { return eleget0('//div[@class="entry-site"]/a', v).innerText?.trim() || "" }, 3) },
- ]
- popup2("h:ソート\n" + (menu.map((c, i) => " " + c.t + (i == GF.yhmSortType ? " ←\n" : "\n")).join("")), 6, `min-width:${menu.reduce((p,c)=>Math.max(p,c.t.length+3),0)}em;`);
- menu[GF.yhmSortType].f()
- GF.yhmSortType = ((GF?.yhmSortType + 1) % menu.length)
- },
- }],
- },
- {
- id: 'YAJ2', // yafuoku::
- urlRE: '://auctions.yahoo.co.jp/search/|://page.auctions.yahoo.co.jp/jp/auction/|://auctions.yahoo.co.jp/category/list/',
- title: 'h3.Product__title>a,h1.ProductTitle__text,div.Product__sellerArea>a,div>p.Seller__name>a,div p.Seller__name>a',
- titleSubstr: true,
- box: 'li.Product,div.l-contentsBody',
- forceTranslucentFunc: e => e?.closest('div.l-contentsBody') && lh("/auction/"),
- trim: 1,
- redoWhenRefocused: 1,
- listTitleXP2: '//div[@class="Product__sellerArea"]/a|//span[@class="Seller__name"]/a[1]|//p[@class="Seller__name"]/a',
- XP2name: '出品者名 ',
- XP2memo: 1,
- listGen: 6,
- listHelpXP: '//li[@class="Product"]',
- //helpInBlock: 1,
- wholeHelp: [() => 1, " " + KEYMAXP + ":価格上限"],
- detailURLRE: /:\/\/page.auctions.yahoo.co.jp\/jp\/auction\//, // automemoのために必要
- detailTitleXP: '//h1[@class="ProductTitle__text"]', // automemoのために必要
- detailTitleSearchXP: '//h1[@class="ProductTitle__text" and ***]/../../../..|//span[@class="Seller__name"]/a[+++]/../../../../../../../../../../..|.//span[@class="Seller__name"]/a[1][+++]|//p[@class="Seller__name"]/a[+++]/ancestor::div[@class="l-containerInner"]',
- func: () => { elegeta(SITE.title).forEach(e => e.innerText = e.innerText?.trim()) },
-
- maxpriceXP: '//input[@class="InputText__input" and @name="max"]',
- automemoForceFunc: () => lh("://page.auctions.yahoo.co.jp/jp/auction/"),
- automemoURLRE: "://page.auctions.yahoo.co.jp/jp/auction/",
- automemoSearchFunc: () => { return eletext('//div[@class="ProductExplanation__commentArea"]') + "\n" + eletext('//div[@id="ProductProcedures"]') + "\n" + eletext('//h1[@class="ProductTitle__text"]') + '\n' + eletext('//ul[@class="ProductInformation__items"]/li[2]') + '\n' + eletext('//div/div[@class="ProductDetail"]') + '\n' + eletext('//ul/li[@class="ProductInformation__item"]/section[@class="Section"]'); },
- automemoFunc: () => {
- for (let am of CUSTOMAUTOMEMORE) { autoMemo(am); }
- autoMemo(/(レターパック[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(クリックポスト[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(ゆうメール[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(ゆうパケット[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(ゆうパック[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(定形外[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(メール便[^0-90-9\n]*[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/送料.*(全国一律\s*[0-9,0-9,]*.*円[-~]?)/m);
- autoMemo(/送料\s*[::]?(.*[都道府県]は[0-9,0-9,]*円[-~]?)/m);
- autoMemo(/(Pentium.*?GHz)|(Celeron.*?GHz)|(Atom.*?GHz)|(Core\s?i\d.*?GHz)|(AMD.*APU)/mi) ? 0 :
- autoMemo(/(CPU[\s\S]{1,30}?GHz)/mi) ? 0 :
- autoMemo(/^(.*GHz)/gmi) ? 0 :
- autoMemo(/(Pentium[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)|(Celeron[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)|(Atom\s[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)|(Core\s?i\d.[0-9A-Za-z\-_.]*)|(Ryzen\s?\d[0-9A-Za-z\-_.]*\W*[0-9A-Za-z\-_.]*)/mi);
- autoMemo(/([0-90-9]{2,4}年製)/m) ? 0 :
- autoMemo(/([0-90-9]{2,4}年)/m) ? 0 :
- autoMemo(/([0-90-9]{2,4}年製)/m) ? 0 :
- autoMemo(/([0-90-9]{2,4}年)/m);
- autoMemo(/発送元:(.{1,4}[都道府県])/m);
- autoMemo(/(認証制限[\s\S]{1,3}あり)/m);
- },
- showFunc: () => { run(document.body, "returned") },
- },
- {
- id: 'YAJ2',
- urlRE: '://auctions.yahoo.co.jp/seller/',
- listTitleXP: '//a[@class="Product__titleLink"]|.//a[@class="Product__titleLink u-textBold"]|.//div[@class="a1wrp"]/h3/a',
- listTitleXP2: '//div/div[@class="seller__subInfo"]/span[@class="seller__yid"]',
- XP2name: '出品者名 ',
- XP2memo: 1,
- listGen: 4,
- listHelpJQS: "div.a1,#list01 table tbody tr td",
- listTitleSearchXP: '//div[@class="a1wrp"]/h3/a[***]/../../../..|.//div[@class="a1wrp"]/h3/a/em[***]/../../../../..|//div/div[@class="seller__subInfo"]/span[@class="seller__yid"][+++]',
- listTitleMemoSearchXP: '//div[@class="a1wrp"]/h3/a[***]|.//div[@class="a1wrp"]/h3/a/em[***]/..|//div/div[@class="seller__subInfo"]/span[@class="seller__yid"][+++]',
- redoWhenReturned: 1,
- },
- {
- id: 'YAJ2',
- urlRE: 'userbenchmark',
- },
- {
- id: 'AMAZON',
- urlRE: 'https://www.amazon.co.jp/product-reviews/',
- title: '//a[@data-hook="product-link"]',
- box: 'div#a-page',
- forceTranslucentFunc: e => 1,
- }, {
- id: 'AMAZON', //amazon:: ama::
- listTitleXPIgnoreNotExist: 1,
- // urlRE: /www\.amazon\.co\.jp\/s\?k\=|www\.amazon\.co\.jp.*\/dp\/.*/,
- urlRE: /www\.amazon\.co\.jp\/s\?|www\.amazon\.co\.jp.*\/dp\/.*/,
- //title: 'a.a-link-normal.s-underline-text.s-underline-link-text.s-link-style.a-text-normal>span,div#title_feature_div.celwidget[data-feature-name="title"]>div#titleSection.a-section.a-spacing-none>h1#title>span#productTitle,h1#title span',
- //box: 'div.s-asin,div#dp-container',
- //title: 'h2.a-size-mini.a-spacing-none.a-color-base.s-line-clamp-4,span#productTitle.a-size-large.product-title-word-break',
- title: 'span#productTitle.a-size-large.product-title-word-break,span.a-size-base-plus.a-color-base.a-text-normal', //'h2.a-size-mini.a-spacing-none.a-color-base.s-line-clamp-4,span#productTitle.a-size-large.product-title-word-break,span.a-size-base-plus.a-color-base.a-text-normal',
- //title: 'h2.a-size-mini.a-spacing-none.a-color-base.s-line-clamp-4,span#productTitle.a-size-large.product-title-word-break,span.a-size-base-plus.a-color-base.a-text-normal',
- box: 'div.s-asin,div#dp-container',
- memoFunc: e => e.parentNode,
- //delay:1600,observe:1600, // 非表示の前にヨドバシ量単価を先に処理させるため1500以上にしたほうがいい
- redoWhenReturned: 1,
-
- //memoFunc: e => e.parentNode.parentNode,
- forceTranslucentFunc: e => e.closest('div#dp-container'),
- detailTitleSearchXP: '//span[@id="productTitle" and ***]/../../../../../..|//h1/a[@class="a-link-normal" and ***]/../../../../../../../../../../../../..|//div[@class="p13n-sc-truncate-desktop-type2 p13n-sc-truncated"][***]/../../../../..',
- listGen: 12,
- listHelpXP: '//div[@data-asin][.//span[@class="a-size-base a-color-base a-text-normal"]]|.//div[@data-asin][.//span[contains(@class,"a-size-medium a-color-base a-text-normal")]]',
- trim: true,
- func: () => {
- // !lh(/\/dp\/|\/gp\//)&&lh(/\/s\?|\/b\//)&&elegeta('[data-asin] span.a-icon-alt:not([data-starpop])').forEach(e=>{after(e?.parentNode,`<span style="float:right;" data-estars="${parseFloat(e?.textContent.match0(/5つ星のうち([0-9\.]+)/)) }">${e?.textContent}</span>`);e.dataset.starpop=1;})
- //!lh(/\/dp\/|\/gp\//)&&lh(/\/s\?|\/b\//)&&elegeta('[data-asin] span.a-icon-alt:not([data-starpop])').forEach(e=>{after(e?.parentNode,` <span data-estars="${parseFloat(e?.textContent.match0(/5つ星のうち([0-9\.]+)/)) }">(${e?.textContent.match0(/5つ星のうち([0-9\.]+)/)})</span>`);e.dataset.starpop=1;})
- !lh(/\/dp\/|\/gp\//) && lh(/\/s\?|\/b\//) && elegeta('[data-asin] span.a-icon-alt:not([data-starpop])').forEach(e => {
- before(e?.parentNode, `<span data-estars="${parseFloat(e?.textContent.match0(/5つ星のうち([0-9\.]+)/)) }">${e?.textContent.match0(/5つ星のうち([0-9\.]+)/||"0")+" "||""}</span>`);
- e.dataset.starpop = 1;
- })
-
- //elegeta('//*[@class="s-line-clamp-2"]|.//*[@class="s-line-clamp-3"]').forEach(e => e.style.maxHeight = "auto");
- //elegeta('//div[@class="a-section a-spacing-none"]/div[1]/h2/a[@class="a-link-normal a-text-normal"]/span').forEach(e => e.style.display = "inline-block") // 商品名を広く表示する
- },
- observeTagName: "DIV",
- // listHelpJQS: 'div[data-asin]',
- detailURLRE: /\/dp\/|\/product-reviews\//,
- detailTitleXP: '//h1[@id="title"]/span[@id="productTitle"]',
- hideListEvenDetail: 1,
-
- automemoURLRE: /https:\/\/www.amazon.co.jp.*\/dp\//,
- // automemoSearchFunc: () => { return eletext(['//div[@id="ppd"]/div[4]', '//div/div[@data-template-name="productDescription" and @id="productDescription_feature_div"]', '//div[@data-template-name="productDescription"]', '//div[@id="important-information"]', '//div[@id="prodDetails"]']); },
- automemoSearchFunc: () => { return eletext([`//div[contains(@class,"celwidget aplus-module module-9 aplus-standard")]`, '//div[@id="ppd"]/div[4]', '//div/div[@data-template-name="productDescription" and @id="productDescription_feature_div"]', '//div[@data-template-name="productDescription"]', '//div[@id="important-information"]', '//div[@id="prodDetails"]', '//div[@class="a-box a-last"]/div[@class="a-box-inner"]', 'div#buyBoxAccordion.a-box-group.a-accordion.a-spacing-large']); },
- automemoFunc: () => {
- if (eleget0('//div[@id="nav-subnav" and @data-category="beauty"]|//div[@id="nav-subnav" and @data-category="hpc"]|//div[@id="nav-subnav" and @class="spacious subnav-untied"]')) {
- [/(イソプロピルメチルフェノール)/m, /(IPMP)/m, /(塩化セチルピリジニウム|塩化セシルピリジニウム|セチルピリジニウム塩化物)/m, /(CPC)/m, /(塩化ベンザルコニウム)/m, /(BKC)/m, /(ラウロイルサルコシンナトリウム|ラウロイルサルコシンNa|ラウロイルサルコシンNa)/m, /(LSS)/m, /(塩化ベンゼトニウム)/m, /(BTC)/m, /(クロルヘキシジン)/m, /(CHG)/m, /(グリチルリチン酸アンモニウム)/m, /(イプシロン.アミノカプロン酸)/m, /(ε.ACA)/m, /(トラネキサム酸)/m, /(TXA)/m, /(グリチルリチン酸ジカリウム|グリチルリチン酸二カリウム|グリチルリチン酸2K|グリチルリチン酸2K|GK2)/mi, /(1\,?450\s?ppm)/m, /(高?濃?度?フッ化ナトリウム|高?濃?度?フッ素)/m, /(ハイドロオ?キシアパタイト)/m, /(リン酸化オリゴ糖カルシウム)/m, /(POs-Ca|POs-Ca)/mi, /(カゼインホスホペプチド.非結晶性リン酸カルシウム|リカルデント)/m, /(CPP-ACP)/m, /(チモール)/m, /(サリチル酸メ?チ?ル?)/m, /(1\,8-シネオール)/m, /(トリクロサン)/m, /(トリクロカルバン)/m, /(オクトピロックス|オクトロピックス|ピロクトン.?オラミン)/m, /(Znピリチオン|ジンクピリチオン)/m, /(硫黄|イオウ)/m, /(アラントイン)/m, /(グリチルリチン酸アンモニウム)/m, /(ミコナゾール硝?酸?塩?)/m, /(クロラムフェニコール)/m, /(フラジオマイシン硫?酸?塩?)/m, /(ナイスタチン)/m, /(塩化亜鉛)/m, /(ポビドン.?ヨード)/m, /(ラウリルジアミノエチルグリシンナトリウム)/m, /(カキタンニン)/m, /(チャエキス)/m, /(ローズマリー)/m, /(カンゾウ)/m, /(クマザサ)/m, /(セージ)/m, /(シソエキス)/m, /(β?-?グリチルレチン酸?)/m, /(メントール)/m, /(ポリリン酸ナトリウム|ポリリン酸Na)/m, /(ヒノキチオール)/m, /(ティーツリー油オ?イ?ル?)/m, /(ティートゥリー油オ?イ?ル?)/m].forEach(m => autoMemo(m));
- }
- if (eleget0('//div/div[@id="nav-subnav" and @data-category="electronics"]|//div/div[@data-category="musical-instruments"]/a[1]')) {
- [/([\d\s\,]+mAh)/m, /([\d\s\,]+mAh)/m, /([\d\s\,]{2,9}回)/m, /(感度.{1,20}dB)/mi].forEach(m => autoMemo(m));
- // [/([\d\s\,]+mAh)/m, /([\d\s\,]+mAh)/m, /([\d\s\,]{2,9}回)/m].forEach(m => autoMemo(m));
- }
- if (eleget0('//div[@id="nav-subnav" and @data-category="kitchen"]|//div[@id="nav-subnav" and @data-category="home"]')) {
- [/([0-90-9++]+?物質)/m, /([0-90-9++]+?項目)/m, /(交換.{1,19}[0-9.]+ヶ月)|(交換.{1,19}[0-9.]+年)|(取替.{1,19}[0-9.]+ヶ月)|(取替.{1,19}[0-9.]+年)/m].forEach(m => autoMemo(m));
- [/(低圧\D?\d+kpa)/mi, /(高圧\D?\d+kpa)/mi, /(圧力[\::]\d+kPa)/mi].forEach(m => autoMemo(m));
- }
- if (eleget0('//div[@id="nav-subnav" and @data-category="food-beverage"]')) {
- [/(食物繊維\D{0,9}[0-9.]+[gg])/m].forEach(m => autoMemo(m));
- }
- if (eleget0('//div/a/span/img[@alt="AMAZON FASHION"]|//span[@class="nav-a-content" and contains(text(),"産業・研究開発用品")]')) {
- [/(ハイパーV)|(Hyper.?V)|(.?先芯.{0,3})/mi].forEach(m => autoMemo(m));
- }
- if (eleget0('//div[@data-category="diy"]/a[1]/span[contains(text(),"DIY・工具・ガーデン")]')) {
- [/(容量[\s\S]{0,3}[0-9\.\, ]+(?:L|L|リットル))/mi, /(容量\((?:L|L|リットル)\):[0-9\.\, ]+)/mi].forEach(m => autoMemo(m));
- }
- if (eleget0('//span[@class="a-list-item"]/a[contains(text(),"カップ・マグ・ソーサー")]|//div[@id="wayfinding-breadcrumbs_container"]/div[@id="wayfinding-breadcrumbs_feature_div"]/ul/li/span/a[contains(text(),"ボウル")]|//a[@class="a-link-normal a-color-tertiary" and contains(text(),"食器・グラス・カトラリー")]')) {
- [/(容量[\s約\:]*[0-9\.\,]+\s*(?:ml|cc|L|L|リットル))/mi, /(容量\((?:ml|cc|L|L|リットル)\):[0-9\.\,]+)/mi].forEach(m => autoMemo(m));
- }
-
- let cat = elegeta('//li/span[contains(@class,"a-list-item")]/a[contains(@class,"a-link-normal a-color-tertiary")]')
- if (cat.find(e => e.textContent.match0("食器用洗剤")))[/(界面活性剤\s*[\((]+\s*\d+[\%%]+[^\))]*[\))]+)/m].forEach(m => autoMemo(m));
-
- // [/(出荷元\s*Amazon)/mi, /(発送元\s*\:*\s*Amazon)/mi].forEach(m => autoMemo(m, t => t.replace(/\n/gm, " ")));
- //[/(出荷元\s*\w+)/mi, /(発送元\s*\:*\s*\w+)/mi].forEach(m => autoMemo(m, t => t.replace(/\n/gm, " ")));
- [/(出荷元\s*\S+)/mi, /(発送元\s*\:*\s*\S+)/mi].forEach(m => autoMemo(m, t => t.replace(/\n/gm, " ")));
- },
- funcOnlyFirst: () => {
- Math.random() > 0.5 && addstyle.add('.s-line-clamp-2 { -webkit-line-clamp: none; max-height: 9em; text-align: initial; display: inline !important; } .s-line-clamp-1, .s-line-clamp-2, .s-line-clamp-3, .s-line-clamp-4, .s-line-clamp-5 { -webkit-box-orient: initial; }') // タイトルを…で省略させない
-
- var observeUrlHasChangedhref = location.href;
- var observeUrlHasChanged = new MutationObserver(mutations => {
- if (observeUrlHasChangedhref !== location.href) {
- prefCacheClear();
- observeUrlHasChangedhref = location.href;
- elegeta('//span[contains(@class,"yhmMyMemo")]').forEach(e => e.parentNode.remove());
- setTimeout(() => { run(document.body, "returned") }, 2500);
- }
- });
- observeUrlHasChanged.observe(document, { childList: true, subtree: true });
- },
- },
- /* { // doc::
- id: '', // GM_setValueで保存するグループ名 同じグループは設定が共通になる
- urlRE: '', // 動作するサイトのURLの一部(正規表現)
- necessaryToWorkFunc: null, // この関数がありfalseなら動作を停止する urlREだけでは非対応ページを絞り込めない時に使用
- listTitleXP: '', // 項目一覧ページの項目名を特定できる要素のXPath title>text>altの順にあるものから利用される
- listTitleXP2: '', // 項目一覧ページの項目名の第2候補を指すXPath これにホバーしていればQキーでこれのinnerTextでもNG登録できる
- XP2name: '', // XP2にホバーした時のガイドに表示する文字列
- XP2memo: 0, // 1だとXP2でも1-6キーのメモを許可
- listTitleSearchXP: '', // 項目一覧ページの項目を消すブロック要素をサーチするXPath 通常listTitleXPにサーチ用マクロを付け/..をいくつかつけたもの
- listTitleSearchFunc: null, // 項目一覧ページの項目を消すブロック要素をサーチする関数 5chのレス本文キーワードNGなどで使用
- listTitleMemoSearchXP: '', // 項目一覧ページと詳細ページのメモを付ける要素をサーチするXPath(一覧と詳細の両方を|でOR記述) 通常listTitleXPやdetailTitleXPにサーチ用マクロを付け/..をいくつかつけたもの
- listTitleMemoSearchXPSameGen: 0, // 1だとメモをタイトルと同じ世代の要素として付ける 0だと1つ親世代
- // サーチ用マクロ; ***:textをcontainsで検索 +++:textを=で検索 ++alt++:altを=で検索 ++title++:titleを=で検索 **url**:hrefをcontainsで検索(要useURL) ++url++:hrefを=で検索(要useURL)
- listGen: 3, // Q12を押した場所の要素からいくつ上まで遡った要素までを当たり判定にするか 必要最小限にする
- listHelpJQS: '', // 項目一覧ページで操作ガイドを表示する要素のJQueryセレクタ ↓でも良い 両方を省略するとlistTitleXPの2つ親の要素で代用 当たり判定とは関係ない
- listHelpXP: '', // 項目一覧ページで操作ガイドを表示する要素のXpath ↑でも良い 両方を省略するとlistTitleXPの2つ親の要素で代用 当たり判定とは関係ない
- helpInBlock: 0, // 1だと操作ガイドを要素のブロック内に表示する
- preventHelpFunc: null, // ()=>trueを返したらヘルプを表示しない判定関数
- detailURLRE: //, // URLにmatchする正規表現、matchすると個別詳細画面だと判断する
- detailTitleXP: '', // 詳細画面で項目名を指すXPath
- detailTitleSearchXP: '', // 詳細画面で非表示化時に表示を薄くする要素をサーチするXPath
- func: null, // 処理時にそのサイトでのみ実行したい関数があれば書く
- funcQ: null, // Qキー処理時にそのサイトでのみ実行したい関数があれば書く
- funcMemo: null, // 5/6などメモ関係処理時にそのサイトでのみ実行したい関数があれば書く
- funcFinally: null, // そのサイトで非表示やメモの処理が終わった後に実行したい関数があれば書く
- funcOnlyFirst: null, // ページ開始時に1回だけ実行したい関数 通常通りのDelayが効く
- funcOnlyFirstWithoutDelay: null, // ページ開始時に1回だけ実行したい関数 Delayなしで最速で実行する
- titleProcessFunc: null, // 項目名を保存する前に加工したければ関数を書く
- autoTranslucentURLRE: //, // 強制的に半透明モードにするURLの正規表現 Web漫画アンテナのマイリスト等
- listTitleXPIgnoreNotExist: 0, // 通常listTitleXPにヒットする要素が1つもなくobserveも0なら動作を停止するがこれがtrueだと停止をしない 項目が動的に追加されるページなどで使用
- forceRunIffunc: null, // これがありtrueを返したらlistTitleXPIgnoreNotExist=1と同様に動作の停止をしない 項目が動的に追加されるページ、先に加工を要するページ(旧5ch)などで使用
- delay: 0, // ミリ秒 ページ読み込み後処理を開始するまでの遅延
- delayAutoWeighting: 0, // 0以外ならページ開始時から処理開始までの遅延の係数(省略可) delayと排他利用
- observe: 0, // ミリ秒 1以上だと要素追加ごとにこのミリ秒の遅延を置いて再処理する(とても遅い) 項目が動的に追加されるページなどで使用
- observeFunc:null, // これがあると追加された要素ごとにtrueを返した要素のみが処理対象になる判定関数 (addedElement)=>{return addedElement==~})
- observeId: "", // これがあるとobserve有効時にこのIDの要素でないものは無視する YouTubeなどの高速化に重要
- observeClass: [], // これがあるとobserve有効時にこれに含まれるClassNameでない要素は無視する futapoなどの高速化に重要
- observeClassNameNot:[], // これがあるとobserve有効時にこのclassNameの要素は処理しない
- observeTagName:"", // これがあるとobserve有効時にこのtagNameの要素は処理しない
- trim: 0, // 1だと項目名をtrimしてから保存 Amazonでは項目名が一覧と詳細で揺れるため1にする
- automemoURLRE: null, // 自動メモを収集するURL
- automemoSearchFunc: null, // 自動メモの対象要素のテキストを収集する関数
- automemoFunc: null, // 自動メモを実行する関数
- redoWhenReturned: 0, // これが1かdetailTitleXPが存在すれば他ウインドウや他タブから戻ってきた時に全体を再処理する disableUrlREを見る
- redoWhenRefocused: 0, // これが1なら他タブから戻ってきた時に全体を再処理する disableUrlREを無視
- showFunc: null, // QWで項目を再表示した時に実行したい関数があれば書く
- hideListEvenDetail: 0, // 1なら詳細画面でも一覧画面用の非表示を実行する ニコニコ静画(イラスト)などで使用
- detailRangeFunc: null, // 詳細画面で項目対象が2つ以上ある場合に指した要素から遡る等の処理があれば書く関数
- //useURL: 0, // 1なら項目名としてAタグのhrefを取り込み、使う ジモティ等、完全に同名の項目名が付けられやすいサイトで使用
- useURL: 0, // 1なら項目名としてAタグのhrefを取り込み、使う(?以降は無視) ジモティ等、完全に同名の項目名が付けられやすいサイトで使用
- useText: 0, // 1なら項目名としてtextContentを取り込み、使う Pubmed等IDではない@titleが設定されているためテキストを優先したいサイトで使用
- hideSelectedWord: 1, // 1ならQキーを押した時に文字列選択中ならその文字列を非表示リストに入れる 5chのレス本文キーワードNGなどで使用
- disableHelpForce: 0, // 1ならENABLE_HELP_CONCLUSIONを常に0にしヘルプやガイドを一切表示しない
- disableHelpUrlRE: '', // 正規表現 URLにマッチすると全体ヘルプを抑制する
- disableKeyB: 0, // 1ならBキーは効かなくする youtubeなどで使用
- searchAllowLength: 0, // 1ならQ12キーの当たり判定をゆるくする(説明しづらい) 5chで使用
- reloadWhenUrlHasChanged:0, // 1ならURLが変わった時にリロードする SPAサイトなどで使用
- helpOnDNI: 0, // 1ならdniでの継ぎ足し時非表示にしたレポートを逐一表示する
- disableUrlRE: "", // URLにマッチしたらキー操作を無効にする正規表現 YouTubeなどSPAサイトで動画視聴ページでキー操作の機能を無効にするために使用
- urlHasChangedCommonFunc: null, // urlが変わったら実行する関数 uniqlo等シングルページアプリケーションで一覧と詳細を行き来するサイト等で使用
- WhateverFirstAndEveryAPFunc: null, // 対象要素がなくてもurlREにマッチしたページならとにかく最初とAutoPagerize時に実行する関数
- memoStyle:"", // メモのstyle=""指定に特別に追加する文字列
- ignoreDNI:null, // これがあるとDOMNodeInsertedイベントでe.targetを受け取りtrueを返したらそのノードは無視する判定関数 ニコ動watch画面等で使用 (e)=>{if(e==無視すべきノード)return false} などと使う
- forceTranslucentFunc:null, // これがあると非表示にした要素eがtrueを返すときは半透明に消す判定関数 e=>e.closest("***") のように使う
- //isMemoPartialMatch: 0, // 全体ヘルプの表示だけメモを部分一致にする
- isHidePartialMatch: 0, // 全体ヘルプの表示だけ非表示を部分一致にする=Bキーのガイドを出す 5ch/ふたばなどの特殊本文NGができるサイトでBキーのヘルプを出すためだけに使用
- preventMemo: null, // (memo内容)=>return true だと通常のメモの内容表示を抑制する判定関数 futapoで使用
- // 新方式(titleとboxで1セット、listTitle~を代替)
- title: '', // 項目名を指すXPath/CSS これとboxだけで要素を特定する新フォーマット title→textContentの順に優先して同一判定する 現在===判定のみ
- box: '', // titleを包含し項目全体の枠になる先祖要素(枠)を指すCSS(XPath不可) boxの中にtitleがある
- titleSubstr: false, // これがtrueだとメモがtitleに対して部分一致でヒットするようになる ヤフオクでCPUスコアの自動メモを表示するために使用
- memoFunc: null, // メモを付ける位置は通常はtitleのafterendだがこれがあるとtitle要素から辿って変更できる デフォルトは(titleEle)=>{return titleEle}
- memoPosition: '', // メモを付ける位置は通常はtitleのafterendだがこれがあると変更できる afterbegin等
- nfd: 0, // 1:項目のタイトルをすべてNFDエンコードにしてから一致判定する 壮絶に遅い タイトルのエンコードが一定でないサイトで使用 YouTubeの新仕様で必要になるかも
- Bsyntax2: 0, // 1:bキーの非表示ワード直接入力で独自構文を使えるようにする
- }, // doc::
- */
- ];
-
- var siteinfo = Object.assign(SITEINFO, pref("MY_SITEINFO") || []); //alert(siteinfo);return;
- // thissiteを決定
- var thissite = null;
- for (var i = 0; i < siteinfo.length; i++) {
- if (siteinfo[i].urlRE === "") break;
- if (typeof siteinfo[i].urlRE == "function" && siteinfo[i].urlRE() || location.href.match(siteinfo[i].urlRE)) {
- // if (siteinfo[i].urlRE == "") break;
- // if (location.href.match(siteinfo[i].urlRE)) {
- thissite = i;
- var SITE = Object.create(siteinfo[thissite]);
- if (SITE.disableKeyB === undefined && (!(/\*\*\*|\*\*title\*\*|\*\*alt\*\*/.test(SITE.detailTitleSearchXP || "") || /\*\*\*|\*\*title\*\*|\*\*alt\*\*/.test((SITE.listTitleSearchXP || "") || /\*\*\*|\*\*title\*\*|\*\*alt\*\*/.test(SITE.listlTitleMemoSearchXP || ""))))) SITE.disableKeyB = 1;
- break;
- }
- }
- if (thissite === null || (!ENABLE_EXCEPT_YAJ && SITE.id != "YAJ2")) return;
-
- // 実験的に全てON
- //SITE.redoWhenRefocused = 1
- //SITE.redoWhenReturned = 1
-
- let ENABLE_HELP_CONCLUSION = lh(SITE?.disableHelpUrlRE || /$^/) ? 0 : SITE.disableHelpForce ? 0 : ENABLE_HELP;
-
- const MEMOSTYLE = SITE.memoStyle ? SITE.memoStyle : "";
- const CUSTOMAUTOMEMORE = [/(Windows.*bit)/gmi, /((?:HDD|HDD|SSD|SSD|ハードディスク|ストレージ).*?(?:GB|TB|GB|TB|無し|なし|無|欠品|欠))/mi, /((?:10|テン)(?:key|キー))/mi, /(768.{1,3}576)|(800.{1,3}600)|(832.{1,3}624)|(1024.{1,3}768)|(1152.{1,3}864)|(1,?280.{1,3}960)|(1400.{1,3}1050)|(1440.{1,3}1080)|(1600.{1,3}1200)|(2048.{1,3}1536)|(2304.{1,3}1728)|(3200.{1,3}2400)|(854.{1,3}480)|(1024.{1,3}576)|(1136.{1,3}640)|(1280.{1,3}720)|(1,?36\d?.{1,3}768)|(1,?920.{1,3}1,?080)|(2048.{1,3}1152)|(2,?560.{1,3}1,?440)|(3200.{1,3}1800)|(3,?840.{1,3}2,?160)|(7680.{1,3}4320)|(640.{1,3}400)|(1280.{1,3}800)|(1,?440.{1,3}900)|(1680.{1,3}1050)|(1,?920.{1,3}1,?200)|(2560.{1,3}1600)|(2880.{1,3}1800)|(3840.{1,3}2400)|(480.{1,3}320)|(960.{1,3}640)|(176.{1,3}144)|(400.{1,3}240)|(352.{1,3}288)|(640.{1,3}350)|(720.{1,3}480)|(800.{1,3}480)|(864.{1,3}480)|(1024.{1,3}480)|(1024.{1,3}600)|(1280.{1,3}600)|(1120.{1,3}750)|(1280.{1,3}768)|(1152.{1,3}870)|(1280.{1,3}1024)|(1,?600.{1,3}900)|(1,?600.{1,3}1024)|(2048.{1,3}1080)|(4096.{1,3}2160)|(8192.{1,3}4320)/m, /(非光沢|ノングレア|ノーグレア|アンチグレア|光沢|グレア)/m, /((?:30|40)\s?(?:pin|ピン))/mi, /(LVDS.*$|eDP)/mi, /^(.*リカバリ.*)$/mi, /(仕事率[^0-90-9\n]*[0-9,0-9,]*\s*[wW])/mi, /(\[?\s?関東[^0-9,0-9,\n]*[0-9,0-9,]*\s*円[-~]?)/m, /(\[?\s?本州[^0-9,0-9,\n]*[0-9,0-9,]*\s*円[-~]?)/m, /(HDMI.{0,10}入力.{2,3}|入力.{0,20}HDMI.{2,3})/mi, /(電源入り.{2,10})/mi, /(\d\d鍵)/m];
- //const CUSTOMAUTOMEMORE = [/$()^/]; // 無指定
- // ,/(フルHD|Full\s?HD|FHD|WXGA|FWXGA|QVGA|WXGA\+|SXGA|SXGA\+|HD\+|WXGA\+\+|WSXGA|WSXGA\+|UXGA|FHD|2K|WUXGA|FHD\+|UltraWideFHD|QXGA|WQHD|WQXGA|UltraWideQHD\+|QUXGA|QFHD|UHD4K|DCI4K|8KFUHD)/m
- const alsoClearBenchMemoWhenClearAutoMemo = 0; // 1:Shift+"で自動メモのみ削除する時CPUスコアのメモも削除する 0:CPUスコアのメモは残す
-
- const LogMatch = 0;
-
- debug && sw("start")
- var mousex = 0;
- var mousey = 0;
- //var maey = 0;
-
- // userbenchmarkでの動作
- if (location.href.match(/cpu.userbenchmark.com\/.*\/Rating\/|cpu.userbenchmark.com\/SpeedTest\//i)) { //userbenchmark
- setTimeout(() => {
- let cpuscore = $(eleget0('//td[@class="mcs-hl-col" and contains(text(),"64-Core")]/span')).css("border", "4px dotted blue").text();
- let cpuscore1t = "1C:" + $(eleget0('//td[@class="mcs-hl-col" and contains(text(),"1-Core")]/span')).css("border", "4px dotted blue").text();
- cpuscore = cpuscore.replace(/(.*\%).*/, "$1").trim();
- let ubmodel = eleget0('//h1[@class="pg-head-title"]/a[@class="stealthlink"]').innerText.trim();
- let lasttitle = pref("lastItemName") || "";
- let modelno = (ubmodel.replace(/^core i\d-?(\S?\s?\d{3,5}.*$)/gi, "$1").replace(/^Core2 Duo (.?\d{3,5}.*$)/gi, "$1").trim());
- for (let title of (lasttitle ? lasttitle.indexOf(modelno) != -1 ? [modelno] : [lasttitle, modelno] : [modelno])) {
- //for (let memo of [
- [document?.body?.innerText?.match(/(TDP\s*\d+\s*W)/mi)?.[1]?.replace(/\s/gm, " ") || "",
- cpuscore, cpuscore1t,
- ].forEach((memo, i) => {
- //]) {
- var tmp = pref('YAJ2 : SearchMyMemo') || [];
- var isExist = tmp.filter(e => e.t == title && e.m == memo);
- popup3(title + "\n" + memo, i * 3);
- if (isExist.length == 0) {
- if (title && memo) {
- let tmp = pref('YAJ2 : SearchMyMemo') || [];
- tmp.push({ t: title, m: memo, c: COLORCPUSCORE })
- pref('YAJ2 : SearchMyMemo', tmp)
- }
- }
- })
- }
- pref("lastItemName", "");
- //popup3("Task completed");
- }, 500);
- //return;
- }
- if (location.href.indexOf("userbenchmark.com") != -1) {} else {
- pref("lastItemName") ? (pref("lastItemName", ""), popup3("UBM Task has been cleared")) : 0;
- }
-
- if (SITE.id == "5CH") {
- var oldmemo = pref(SITE.id + ' : SearchMyMemo') || []
- var newmemo = JSON.parse(JSON.stringify(oldmemo)) || []
- newmemo.forEach(c => {
- c.t = c.t.replace(document.title, "").replace(/ |\s|:/g, "").trim()
- })
- if (JSON.stringify(oldmemo) != JSON.stringify(newmemo)) {
- pref(SITE.id + ' : SearchMyMemo', newmemo)
- alert("前バージョンからのメモの変換に成功しました") //JSON.stringify(newmemo))
- }
- }
-
- //ct1(()=>{
- // メモのc属性を7文字から4文字に削減 12ms
- var oldmemo = pref(SITE.id + ' : SearchMyMemo') || []
- let memoRE = new RegExp(`\"c\"\:\"${OLD_COLOR1}\"|\"c\"\:\"${OLD_COLOR2}\"|\"c\"\:\"${OLD_COLOR3}\"|\"c\"\:\"${OLD_COLORVIDEOTIME}\"|\"c\"\:\"${OLD_COLORCPUSCORE}\"`)
- if (memoRE.test(JS(oldmemo))) {
- var newmemo = JSON.parse(JSON.stringify(oldmemo)) || []
- newmemo = newmemo?.map(v => {
- if (v?.c) {
- let i = [OLD_COLOR1, OLD_COLOR2, OLD_COLOR3, OLD_COLORVIDEOTIME, OLD_COLORCPUSCORE].indexOf(v?.c)
- if (i >= 0) v.c = [COLOR1, COLOR2, COLOR3, COLORVIDEOTIME, COLORCPUSCORE][i]
- }
- return v;
- })
- if (JSON.stringify(oldmemo) != JSON.stringify(newmemo)) {
- pref(SITE.id + ' : SearchMyMemo', newmemo)
- //alert(`ヤフオクで非表示とメモ:\nメモの旧形式からの変換に成功しました\n`) //JSON.stringify(newmemo)
- }
- }
- //})
- oldmemo = null;
- newmemo = null;
-
- if (SITE.funcOnlyFirstWithoutDelay) SITE.funcOnlyFirstWithoutDelay();
- if (SITE.funcOnlyFirst) setTimeout(() => { SITE.funcOnlyFirst(); }, (SITE.delayAutoWeighting || 0) * WAIT || (SITE.delay || 0));
- if (SITE.WhateverFirstAndEveryAPFunc) {
- setTimeout(() => { SITE.WhateverFirstAndEveryAPFunc(); }, (SITE.delayAutoWeighting || 0) * WAIT || (SITE.delay || 0));
- document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) { SITE.WhateverFirstAndEveryAPFunc(evt.target); }, false);
- }
-
- if (SITE.keyFunc) { // SITEINFOにあるkeyFunc
- document.addEventListener('keydown', e => {
- if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable || ((e.target.closest('#chat-messages,ytd-comments-header-renderer') || document.activeElement.closest('#chat-messages,ytd-comments-header-renderer')))) return;
- let ele = document.elementFromPoint(mousex, mousey)
- var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
- keyFuncDispatch(key, e, ele)
- /*SITE.keyFunc.forEach(c => {
- if (typeof c.key === "string" ? key === c.key : key.match0(c.key)) { c.func(key) }
- })*/
- //}
- // }, false)
- }, true)
-
- function keyFuncDispatch(key, opt = null) {
- SITE.keyFunc.forEach(c => {
- if (typeof c.key === "string" ? key === c.key : key.match0(c.key)) { c.func(key, opt) }
- })
- }
- }
-
- if (SITE.reloadWhenUrlHasChanged) {
- var observeUrlHasChangedhref = location.href;
- var observeUrlHasChanged = new MutationObserver(mutations => { if (observeUrlHasChangedhref !== location.href) location.reload() });
- observeUrlHasChanged.observe(document, { childList: true, subtree: true });
- }
- if (SITE.runWhenUrlHasChanged) {
- var observeUrlHasChangedhrefRun = location.href;
- var observeUrlHasChangedRun = new MutationObserver(mutations => {
- if (observeUrlHasChangedhrefRun !== location.href) {
- prefCacheClear();
- setTimeout(() => { run(document.body, "returned") }, 2500);
- }
- });
- observeUrlHasChangedRun.observe(document, { childList: true, subtree: true });
- }
-
- // 詳細画面?
- var isDetail = (SITE.detailURLRE && location.href.match(SITE.detailURLRE)) ? 1 : 0;
- debug && dc("isDetail : " + isDetail)
-
- var isHidePartialMatch = SITE.isHidePartialMatch || (SITE.listTitleSearchXP && SITE.listTitleSearchXP.indexOf("**") != -1) ? 1 : 0;
- var isMemoPartialMatch = SITE.isMemoPartialMatch || (SITE.listTitleMemoSearchXP && SITE.listTitleMemoSearchXP.indexOf("**") != -1) ? 1 : 0;
-
- // ヤフオク上限価格はIME offにする
- if (SITE.id == "YAJ2") $(eleget0('//input[@class="InputText__input" and @name="max"]')).css('ime-mode', 'inactive');
-
- // 自動的に半透明モードにするページ
- var disableHide = (SITE.autoTranslucentURLRE && location.href.match(SITE.autoTranslucentURLRE)) || (pref("translucent") == "on");
-
- // 非対応ページ
- if (!isDetail && ((SITE.listTitleXP && !eleget0(SITE.listTitleXP)) || (SITE.title && !elegeta(SITE.title)))) {
- if ((SITE.listTitleXPIgnoreNotExist) || (SITE.observe) || (SITE.forceRunIffunc && SITE.forceRunIffunc())) {} else {
- if (debug) popup3("対象要素がないのでこのページでは働きません");
- return;
- }
- }
- if (SITE.necessaryToWork && (document.body.innerText.match(SITE.necessaryToWork)) == null) { //prompt(document.body.innerText,document.body.innerText.match(SITE.necessaryToWork))
- if (debug) popup3("非対応ページなのでこのページでは働きません");
- return;
- }
-
- if (SITE.selectedHelp) {
- $('body').on('mouseup', function(e) {
- var selectedStr;
- if (window.getSelection) {
- selectedStr = window.getSelection().toString();
- if (selectedStr !== '' && selectedStr !== '\n') {
- if (selectedStr.indexOf("\n") !== -1) SITE.selectedHelp.multi ? popup3(SITE.selectedHelp.multi, 11, 5000) : 0;
- else SITE.selectedHelp.help ? popup3(`『${sani(selectedStr)}』を\n` + SITE.selectedHelp.help.join("\n"), 11, 5000) : 0;
- }
- }
- });
- }
-
- String.prototype.replaceTitle = function(title) {
- if (title && SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
- if (!title) title = "空の文字列";
- return this.replace(/\*\*\*/g, "contains(text(),\"" + title + "\")").replace(/\+\+\+/g, "text()=\"" + title + "\"").replace(/\+\+alt\+\+/g, "@alt=\"" + title + "\"").replace(/\*\*alt\*\*/g, "contains(@alt,\"" + title + "\")").replace(/\*\*title\*\*/g, "contains(@title,\"" + title + "\")").replace(/\+\+title\+\+/g, "@title=\"" + title + "\"").replace(/\+\+url\+\+/g, "@href=\"" + title + "\"").replace(/\*\*url\*\*/g, "contains(@href,\"" + title + "\")");
- };
-
- var keyListen = function(e) {
- if (SITE.disableUrlRE && (location.href.match(SITE.disableUrlRE))) {
- var one = document.elementFromPoint(mousex, mousey);
- // if (!SITE.listTitleXP || !elegeta(SITE.listTitleXP).concat(elegeta(SITE.listTitleXP2)).concat(elegeta(SITE.title)).find(v => v == one)) { return; }
- if (!SITE.listTitleXP || ![...elegeta(SITE.listTitleXP), ...elegeta(SITE.listTitleXP2), ...elegeta(SITE.title)].some(e => e.contains(one))) { return; }
- } //youtube視聴画面では反応する項目にホバーしているとき以外はキーを無効にする
-
- if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable || ((e.target.closest('#chat-messages,ytd-comments-header-renderer') || document.activeElement.closest('#chat-messages,ytd-comments-header-renderer')))) return;
- var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
- if (key === KEYCHANGE_DEBUG) { // D::change debug mode
- debug = (debug + 1) % 4;
- popup3("debug mode : " + debug)
- }
- if (key === KEYHIDE) { // Q::hide
- e.preventDefault();
- if (SITE.hideSelectedWord) { // 選択された文字列をNG / 5ch等
- let sel = String(window.getSelection());
- if (sel) {
- if (sel.indexOf("\n") !== -1) { popup2("複数行の選択は NG に入れられません", 1); } else { addNG(sel); }
- if (SITE.funcB) SITE.funcB();
- return false;
- }
- }
- if (SITE.title) { // 直接ホバーしている要素が非表示対象ならそれで非表示登録(1つのbox内に複数の対象(作品名に対する作者名など)がある時にどちらで登録するかを選べるための処理)
- var ele = document.elementFromPoint(mousex, mousey);
- ele = elegeta(SITE.title)?.find(e => e.contains(ele))
- if (ele) { // if (elegeta(SITE.title)?.some(e=>e.contains(ele) )) {
- debug && dc(`Direct element Q : 『${ele?.textContent?.trim()||ele?.title?.trim() }』\nbox : ${e2sel(ele)}`)
- addNG(ele?.textContent?.trim() || ele?.title?.trim())
- if (SITE.funcQ) SITE.funcQ(ele);
- return false;
- }
- }
- if (SITE.listTitleXP2) { // 2つ目の項目名がありそこにホバーしていればそれで非表示登録
- var ele = document.elementFromPoint(mousex, mousey);
- ele = elegeta(SITE.title)?.find(e => e.contains(ele))
- if (ele) { // if (elegeta(SITE.listTitleXP2).indexOf(ele) != -1) {
- blockElement(ele); //hideByTitle(ele.innerText);
- if (SITE.funcQ) SITE.funcQ(ele);
- return false;
- }
- }
- var ele = (SITE.detailTitleXP && isDetail) ? (eleget0(SITE.detailTitleXP, (SITE.detailRangeFunc ? SITE.detailRangeFunc(document.elementFromPoint(mousex, mousey)) : document.elementFromPoint(mousex, mousey))) || eleget0(SITE.detailTitleXP)) : document.elementFromPoint(mousex, mousey);
- debug && dc("Q start element : " + ele.tagName);
- blockElement(ele);
- if (SITE.funcQ) SITE.funcQ(ele);
- return false;
- }
- if (key == KEYUNDO) { // W::undo
- e.preventDefault();
- let resist = pref(SITE.id + ' : SearchHideTitle') || [];
- let title = resist.pop();
- let title2 = resist.slice(-1)[0] || "";
- title2 = title2 ? ("。次のアンドゥ対象は\n『" + title2 + "』") : ""
- pref(SITE.id + ' : SearchHideTitle', resist) || [];
- showByTitle(title);
- if (isDetail && SITE.showFunc) SITE.showFunc();
- if (title) popup2("『" + title + "』\nを非表示登録から削除しました" + title2, 1);
- else popup2("登録された非表示項目はありません", 1);
- // }
- if (SITE.funcQ) SITE.funcQ();
- return false;
- }
- if (key == KEYBW && !SITE.disableKeyB) { // B::NGword
- e.preventDefault();
- addNGWord();
- if (SITE.funcB) SITE.funcB();
- return false;
- }
- if (key == KEYTOGGLEtranslucent) { // T:: 半透明
- e.preventDefault();
- if (pref("translucent") == "on") restoreHidden();
- pref("translucent", pref("translucent") == "on" ? "off" : "on");;
- popup2(KEYTOGGLEtranslucent + ": 半透明モードを" + pref("translucent") + "にします");
- disableHide = (SITE.autoTranslucentURLRE && location.href.match(SITE.autoTranslucentURLRE)) || (pref("translucent") == "on");
- if (pref("translucent") == "on") {
- restoreTranslucent();
- run(document.body, "returned");
- }
- // location.reload();
- // else restoreHidden();
- return false;
- }
-
- if (key === KEYEDIT) { // shift+Q:: edit NGs
- e.preventDefault();
- prefRestrict(SITE.id + ' : SearchHideTitle', "array");
- let sht = (JSON.stringify(pref(SITE.id + ' : SearchHideTitle') || ""));
- if (sht === '""') sht = "";
- // let tmp = prompt(SITE.id + "\n\n" + KEYEDIT + ":\n非表示にするタイトル(現在" + (pref(SITE.id + ' : SearchHideTitle') || []).length + ")をJSON形式で編集してください\n正規表現ではありません\n空欄を入力すれば全削除できます\n先頭の[の前に+を付けると現在のデータに追加(マージ)します\n\n" + sht, sht);
- let tmp = prompt(`${SITE.id}\n\n${ KEYEDIT }:\n非表示にするタイトル(現在${ (pref(SITE.id + ' : SearchHideTitle') || []).length })をJSON形式で編集してください${SITE.QRule||"\n正規表現ではありません"}\n空欄を入力すれば全削除できます\n先頭の[の前に+を付けると現在のデータに追加(マージ)します\n\n${ sht}`, sht);
- if (tmp !== null) { // ESCで抜けたのでなければ
- try {
- if (tmp.match(/^\+|^+/)) {
- tmp = tmp.replace(/^\+|^+/, "")
- var tmp2 = pref(SITE.id + ' : SearchHideTitle') || []
- tmp = JSON.parse(tmp || "") || []
- var tmp3 = tmp.concat(tmp2)
- tmp = JSON.stringify(tmp3)
- }
- tmp = tmp ? JSON.parse(tmp) : []
- pref(SITE.id + ' : SearchHideTitle', tmp)
- prefRestrict(SITE.id + ' : SearchHideTitle', "array");
- var a = pref(SITE.id + ' : SearchHideTitle')
- var b = [...new Set(a)]; // uniq
- pref(SITE.id + ' : SearchHideTitle', b || []);
- // document.body.remove();
- location.reload();
- } catch (e) {
- alert(e + "\n入力された文字列がうまくparseできなかったので設定を変更しません\n正しいJSON書式になっているか確認してください");
- return false
- }
- return false
- }
- }
- if (key == KEYMEMO5EDIT || key == KEYMEMO6EDIT) { // Shift+5::5memo設定 Shift+6::6memo設定
- e.preventDefault();
- //var date = new Date();
- var memo = window.getSelection().toString().trim() || prompt((key == KEYMEMO5EDIT ? KEYMEMO5 : KEYMEMO6) + "キーのメモ内容を設定してください", (key == KEYMEMO5EDIT ? MEMO5WORD : MEMO6WORD) || getDefault56memo())
- if (key == KEYMEMO5EDIT) {
- MEMO5WORD = memo;
- key = KEYMEMO5
- } else {
- MEMO6WORD = memo;
- key = KEYMEMO6
- }
- if (SITE.funcMemo) SITE.funcMemo();
- if (memo == false) return false;
- }
- if (key == KEYMEMO5 || key == KEYMEMO6) { // 5::5memo 6::6memo
- e.preventDefault();
- if (SITE.title) { // 直接ホバーしている要素が対象ならそれで登録(1つのbox内に複数の対象(作品名と作者名など)がある時にどちらで登録するかを選べるための処理)
- var ele = document.elementFromPoint(mousex, mousey);
- ele = elegeta(SITE.title)?.find(e => e.contains(ele))
- if (ele) { // if (elegeta(SITE.title)?.some(e=>e.contains(ele) )) {//if (elegeta(SITE.title).find(e => e == ele)) {
- //var date = new Date();
- var dateStr = (key == KEYMEMO5 ? MEMO5WORD : MEMO6WORD) || getDefault56memo();
- // memoElement(ele.innerText, document, key == KEYMEMO5 ? COLOR5 : COLOR6, window.getSelection().toString().trim() || dateStr);
- memoElement(ele.textContent?.trim(), document, key == KEYMEMO5 ? COLOR5 : COLOR6, window.getSelection().toString().trim() || dateStr);
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- }
-
- if (SITE.listTitleXP2 && SITE.XP2memo) { // 2つ目の項目名がありそこにホバーしていればそれで56
- var ele = document.elementFromPoint(mousex, mousey);
- ele = elegeta(SITE.listTitleXP2)?.find(e => e.contains(ele))
- if (ele) { //if (elegeta(SITE.listTitleXP2).indexOf(ele) != -1) {
- //var date = new Date();
- var dateStr = (key == KEYMEMO5 ? MEMO5WORD : MEMO6WORD) || getDefault56memo();
- memoElement(ele.innerText, document, key == KEYMEMO5 ? COLOR5 : COLOR6, window.getSelection().toString().trim() || dateStr);
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- }
-
- var ele = (SITE.detailTitleXP && isDetail) ? (eleget0(SITE.detailTitleXP, (SITE.detailRangeFunc ? SITE.detailRangeFunc(document.elementFromPoint(mousex, mousey)) : document.elementFromPoint(mousex, mousey))) || eleget0(SITE.detailTitleXP)) : document.elementFromPoint(mousex, mousey);
- //var date = new Date();
- var dateStr = (key == KEYMEMO5 ? MEMO5WORD : MEMO6WORD) || getDefault56memo();
- memoElement(ele, document, key == KEYMEMO5 ? COLOR5 : COLOR6, window.getSelection().toString().trim() || dateStr);
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- if (key == KEYMEMO1 || key == KEYMEMO2) { // 1::1memo 2::2memo
- e.preventDefault();
- var ele = document.elementFromPoint(mousex, mousey);
- if (SITE.listTitleXP2 && SITE.XP2memo) { // 2つ目の項目名がありそこにホバーしていればそれで12
- // var ele = document.elementFromPoint(mousex, mousey);
- ele = elegeta(SITE.listTitleXP2)?.find(e => e.contains(ele))
- if (ele) { // if (elegeta(SITE.listTitleXP2).indexOf(ele) != -1) {
- //memoElement(ele.innerText, document, key == KEYMEMO2 ? COLOR2 : COLOR1);
- memoElement(ele?.textContent, document, key == KEYMEMO2 ? COLOR2 : COLOR1); // ここはtextContentじゃないと連続半角スペースの省略で違う項目名と判定されてしまう
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- }
- if (SITE.title) { // 直接ホバーしている要素が対象ならそれで登録(1つのbox内に複数の対象(作品名と作者名など)がある時にどちらで登録するかを選べるための処理)
- // var ele = document.elementFromPoint(mousex, mousey);
- ele = elegeta(SITE.title)?.find(e => e.contains(ele))
- if (ele) { // if (elegeta(SITE.title).find(e => e == ele)) {
- //memoElement(ele.innerText?.trim(), document, key == KEYMEMO2 ? COLOR2 : COLOR1) //, window.getSelection().toString().trim() || dateStr);
- memoElement(ele?.textContent?.trim(), document, key == KEYMEMO2 ? COLOR2 : COLOR1) //, window.getSelection().toString().trim() || dateStr);// ここはtextContentじゃないと連続半角スペースの省略で違う項目名と判定されてしまう
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- }
- // var ele = eleget0(SITE.detailTitleXP) ? eleget0(SITE.detailTitleXP) : document.elementFromPoint(mousex, mousey);
- var ele = (SITE.detailTitleXP && isDetail) ? (eleget0(SITE.detailTitleXP, (SITE.detailRangeFunc ? SITE.detailRangeFunc(document.elementFromPoint(mousex, mousey)) : document.elementFromPoint(mousex, mousey))) || eleget0(SITE.detailTitleXP)) : document.elementFromPoint(mousex, mousey);
- memoElement(ele, document, key == KEYMEMO2 ? COLOR2 : COLOR1);
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- if ((key == KEYMEMO1S || key == KEYMEMO2S)) { // 3:: 4:: free memo
- e.preventDefault();
- var target = (prompt(`メモを付けたい項目のタイトルが含むキーワードを入力してください\nこのページでは${SITE?.listTitleMemoSearchXP?.indexOf("**")!=-1?"部分一致です":"全体一致です"}\n\n`) || "")?.trim();
- if (!target) return;
- var memo = (prompt("『" + target + "』\nに付けるメモを書いてください") || "").trim();
- if (!memo) return;
- storeMemo(target.trim(), memo, key == KEYMEMO1S ? COLOR1 : COLOR2)
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- if (key == KEYRESETMEMO) { // Shift+1::!::reset memo
- e.preventDefault();
- prefRestrict(SITE.id + 'SearchMyMemo', "array");
- let smm = JSON.stringify(pref(SITE.id + ' : SearchMyMemo') || []);
- if (smm === '[]') smm = "";
- var tmp = prompt(SITE.id + "\n\n" + KEYRESETMEMO + ":\nメモ(現在" + (pref(SITE.id + ' : SearchMyMemo') || []).length + ")をJSON形式で編集してください\n重複は自動的に削除されます\n空欄を入力すれば全削除されます\n先頭の[の前に+を付けると現在のデータに追加(マージ)します\n\n" + smm, smm);
-
- if (tmp === smm) return false;
- if (tmp !== null) { // ESCで抜けたのでなければ
- //pref(SITE.id + ' : SearchMyMemo', tmp.trim() || []);
- try {
- var mergemode = tmp?.trim()?.match(/^\+|^+/)
- if (mergemode) {
- tmp = tmp?.trim()?.replace(/^\+|^+/, "")?.trim()
- var tmp2 = pref(SITE.id + ' : SearchMyMemo') || []
- tmp = JSON.parse(tmp || "") || []
- var tmp3 = tmp.concat(tmp2)
- tmp = JSON.stringify(tmp3)
- }
- tmp = tmp ? JSON.parse(tmp) : []
- pref(SITE.id + ' : SearchMyMemo', tmp);
- prefRestrict(SITE.id + 'SearchMyMemo', "array");
- var a = pref(SITE.id + ' : SearchMyMemo') || []
- var b = (Array.from(new Set(a.map(v => JSON.stringify(v))))).map(v => JSON.parse(v)) // uniq:オブジェクトの配列→JSON文字列配列→uniq→オブジェクトの配列//var b = a.reduce((a, v) => { if (!a.some((e) => (e.t === v.t && e.m === v.m && e.c === v.c))) { a.push(v); } return a; }, []); // uniq
-
- var found = 0; // 同一タイトルに5/6キーの日時メモが日時違いで重複していたら削除
- var dups = []
- var c = [...b]
- if (mergemode) {
- do {
- found = 0
- for (let v of b) {
- if (v?.m?.match(/^\d\d\d\d\.\d\d\.\d\d(?:\s\(.\))?$/)) {
- var e2 = b.find(v2 => nfd(v?.t) == nfd(v2?.t) && v?.c == v2?.c && v2?.m?.match(/^\d\d\d\d\.\d\d\.\d\d(?:\s\(.\))?$/) && v2 != v)
- //var e2 = b.find(v2 => v?.t == v2?.t && v?.c == v2?.c && v2?.m?.match(/^\d\d\d\d\.\d\d\.\d\d(?:\s\(.\))?$/) && v2 != v)
- if (e2) {
- var ea = [v, e2].sort((a, b) => a?.m > b?.m ? 1 : -1)
- var dup = b.find(v3 => JS(v3) == JS(ea[1]))
- dups.push(dup);
- b = b.filter(f => f != dup)
- found = 1
- break
- }
- }
- }
- } while (found)
- }
- if (mergemode && dups.length) {
- if (confirm(`同一のタイトルに5/6キーの日時メモが複数付いているものが${dups.length}個ありました\nこれを重複とみなし最も古い日時のメモ以外を削除することもできますが\nそうしますか?\n\n削除する項目:\n${JS(dups).replace(/\},{\"t\"\:/g,'},\n{"t":')}`)) {
- c = b
- }
- }
- pref(SITE.id + ' : SearchMyMemo', c || []);
- //document.body.remove();
- setTimeout(() => {
- location.reload();
- }, 1000)
- return false
- } catch (e) {
- alert(e + "\n入力された文字列がうまくparseできなかったので設定を変更しません\n正しいJSON書式になっているか確認してください");
- return false
- }
- }
- }
- if (key == KEYRESETMEMOAUTO) { // Shift+2::reset automemo
- e.preventDefault();
- var str = pref(SITE.id + ' : SearchMyMemo') || [];
- if (alsoClearBenchMemoWhenClearAutoMemo) {
- var newstr = str.filter(e => !(e.c == COLOR3 || e.c == COLORCPUSCORE)); // CPUスコアもリセット
- var newstr2 = str.filter(e => (e.c == COLOR3 || e.c == COLORCPUSCORE)); // CPUスコアもリセット
- } else {
- var newstr = str.filter(e => !([COLOR3, COLOR_ALERT_WORD].includes(e.c)));
- var newstr2 = str.filter(e => !(newstr.includes(e)));
- }
- if (confirm(SITE.id + "\n\n" + KEYRESETMEMOAUTO + ":\n自動メモ(" + newstr2.length + ")のみ全て削除します。良いですか?\n\n消すもの:\n" + JSON.stringify(newstr2))) {
- pref(SITE.id + ' : SearchMyMemo', JSON.stringify(newstr));
- popup2("自動メモをクリアしました", 1);
- document.body.remove();
- location.reload();
- }
- return false;
- }
- if (key == "Shift+#") { // Shift+3::#::hide/show memo
- e.preventDefault();
- GF.numbersign = ((GF.numbersign || 0) + 1) % 4
- if (GF.numbersign == 1) $('#pickbox:visible,.setSlider:visible,[floated]:visible,.relallArea,span#notiApiOn.ignoreMe,table#ftbl input[name="upfile"]:visible').hide()
- if (GF.numbersign == 2) $(`[data-mbt]:visible`).attr("data-numbersign", "1").hide()
- if (GF.numbersign == 3) $(`.ignoreMe.shibo:visible,#shiboButton:visible,#5chVerticalThreadTitle:visible,.setSlider:visible,#ftxa:visible,.quoteSpeechBalloon:visible,.quoteSpeechBalloonImg:visible`).attr("data-numbersign", "1").hide()
- if (GF.numbersign == 0) $(`[data-mbt]:hidden,.ignoreMe.shibo:hidden,#shiboButton:hidden,#5chVerticalThreadTitle:hidden,.setSlider:hidden,#ftxa:hidden,.quoteSpeechBalloon:hidden,.quoteSpeechBalloonImg:hidden,[floated]:hidden,.relallArea,span#notiApiOn.ignoreMe,table#ftbl input[name="upfile"]:hidden`).attr("data-numbersign", "0").show()
- if (SITE.funcMemo) SITE.funcMemo();
- return false;
- }
- if (SITE.maxpriceXP && !isDetail) {
- if (key == KEYMAXP) { // maxpriceXP
- e.preventDefault();
- let ele = eleget0(SITE.maxpriceXP);
- if (ele) {
- ele.focus();
- ele.scrollIntoView({ behavior: "smooth", block: "center", inline: "center" });
- ele.select();
- popup2("上限価格にフォーカス", 1);
- }
- }
- return false;
- //}
- }
- }
- // document.addEventListener('keydown', keyListen, false)
- document.addEventListener('keydown', keyListen, true) // youtube/watchで先取りするためにtrue
-
- document.addEventListener("mousemove", e => ((mousex = e.clientX), (mousey = e.clientY), (hovertimer = 0), undefined), false)
- //document.addEventListener("mousemove", function(e) { mousex = e.clientX; mousey = e.clientY; hovertimer = 0; }, false);
-
- // AP継ぎ足しを監視
- setTimeout(() => { run() }, (SITE.delayAutoWeighting || 0) * WAIT || (SITE.delay || 0));
- document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) { run(evt.target, "APed"); }, false);
-
- // DOM追加を監視
- var DNIDelay = null;
- // if (!isDetail && SITE.observe) {
- if (SITE.observe) {
- debug && dc("observe DNI");
- document.body.addEventListener('DOMNodeInserted', dnifunc, false);
- //document.body.addEventListener('transitionend', dnifunc, false); // テスト
-
- function dnifunc(e) {
- let ele = e.target;
- // if (DNIDelay) return;
- if (ele?.classList?.contains("ignoreMe")) return;
- if (SITE.observeId && (ele.id !== SITE.observeId)) return;
- if (SITE.observeClass && !SITE.observeClass.includes(e.target.className)) return;
- if (SITE.observeTagName && SITE.observeTagName !== ele.tagName) return;
- if (SITE.ignoreDNI && SITE.ignoreDNI(ele)) return;
- if (ele.className && SITE.observeClassNameNot && SITE.observeClassNameNot.includes(ele.className)) return;
- //debug&&console.log(`accept dni:`,ele)
- if (DNIDelay) {
- if (dniCancel || SITE.dniCancel) { clearTimeout(DNIDelay) } else { return; }
- }
-
- DNIDelay = setTimeout(
- // ((ele)=>{return ()=>{
- (function(ele) {
- return function() {
- run(document.body, "observed", ele); // ここで run(ele.parentNode.parentNode, "observed"); などとすると速くなるが~searchXPが何世代まで親を参照するか分からないので全サイトの動作確認が必要
- // run(SITE.observeFunc?ele.parentNode:document.body, "observed", ele); // ここで run(ele.parentNode.parentNode, "observed"); などとすると速くなるが~searchXPが何世代まで親を参照するか分からないので全サイトの動作確認が必要
- DNIDelay = null;
- }
- // })(ele), SITE.observe || 0);
- })(ele), Math.max(GF?.runElapsed || 0, SITE?.observe || 0) || SITE.observe || 0);
- // console.log(Math.max(GF?.runElapsed,SITE?.observe||0) || SITE.observe || 0)
- }
- }
-
- // タブにフォーカスが戻ったら再実行
- // if (SITE.redoWhenRefocused) window.addEventListener("focus", () => { restoreHidden() })
- if (SITE.redoWhenRefocused) window.addEventListener("focus", () => {
- // if (JS(prefCache[SITE.id + ' : SearchMyMemo'] || []) !== JS(pref(SITE.id + ' : SearchMyMemo') || []) || JS(prefCache[SITE.id + ' : SearchHideTitle'] || []) !== JS(pref(SITE.id + ' : SearchHideTitle') || [])) {
- //if (!prefCacheEqual(SITE.id + ' : SearchMyMemo') || !prefCacheEqual(SITE.id + ' : SearchHideTitle')) {
- // if (!prefCacheEqual(SITE.id + ' : SearchMyMemo') || !prefCacheEqual(SITE.id + ' : SearchHideTitle') ) {
- //if (!(!prefChanged("translucent") && !prefChanged(SITE.id + ' : SearchMyMemo') && !prefChanged(SITE.id + ' : SearchHideTitle'))) {
- if (prefChanged("translucent") || prefChanged(SITE.id + ' : SearchMyMemo') || prefChanged(SITE.id + ' : SearchHideTitle')) {
- restoreHidden()
- } // prefCache:キャッシュと保存されたデータが同一だったら再実行しない
- })
-
- // 詳細画面に対応しているサイトかredoWhenReturnedが1ならタブにフォーカスが戻ったら再実行する
- if (SITE.detailTitleXP || SITE.redoWhenReturned) {
- var hidden, visibilityChange;
- if (typeof document.hidden !== "undefined") {
- hidden = "hidden";
- visibilityChange = "visibilitychange";
- } else if (typeof document.msHidden !== "undefined") {
- hidden = "msHidden";
- visibilityChange = "msvisibilitychange";
- } else if (typeof document.webkitHidden !== "undefined") {
- hidden = "webkitHidden";
- visibilityChange = "webkitvisibilitychange";
- }
- document.addEventListener(visibilityChange, handleVisibilityChange, false);
-
- function handleVisibilityChange() {
- if (SITE.disableUrlRE && (location.href.match(SITE.disableUrlRE))) { return; }
- if (document[hidden]) {} else {
-
- // if (!(JS(prefCache[SITE.id + ' : SearchMyMemo'] || []) !== JS(pref(SITE.id + ' : SearchMyMemo') || []) || JS(prefCache[SITE.id + ' : SearchHideTitle'] || []) !== JS(pref(SITE.id + ' : SearchHideTitle') || []))) { return }
- if (!prefChanged("translucent") && !prefChanged(SITE.id + ' : SearchMyMemo') && !prefChanged(SITE.id + ' : SearchHideTitle')) { return }
-
- let prefHide = (SITE.autoTranslucentURLRE && location.href.match(SITE.autoTranslucentURLRE)) || (pref("translucent") == "on");
- if (prefHide !== disableHide) {
- disableHide = (SITE.autoTranslucentURLRE && location.href.match(SITE.autoTranslucentURLRE)) || (pref("translucent") == "on");
- restoreTranslucent();
- }
- restoreHidden();
- }
- }
- }
-
- // タブにフォーカスが戻った時等用 隠していた要素のうち非表示登録から外されたものを再表示
- function restoreHidden() {
- if (isDetail) {
- // showByTitle(eleget0(SITE.detailTitleXP).textContent.replaceTitle());
- // var dtitle = eleget0(SITE.detailTitleXP).textContent.replaceTitle();
- var d = eleget0(SITE.detailTitleXP)
- if (d && !(/\"/.test(d.textContent?.normalize("NFC").replaceTitle()))) showByTitle(d.textContent?.normalize("NFC").replaceTitle());
- }
- if (!isDetail || SITE.hideListEvenDetail) {
- //let resist = pref(SITE.id + ' : SearchHideTitle') || [];
- let resist = JP(JS(pref(SITE.id + ' : SearchHideTitle') || []).normalize("NFC"))
- debug && sw("")
- for (let ele of elegeta('//*[@data-hidden="1" or @data-hidden="2"]')) {
- //let title = getTitleFromParent(ele, 1); // これだとXP2はヒットしないので再表示されない:保留
- let title = ele.dataset.yhmkey;
- if (SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
- let i = resist.indexOf(title); // ここは常に全体一致判定なのでcontains判定のサイトでは少し余計に再表示してしまう(でもまたすぐ隠す)
- if (i === -1) {
- showByTitle(title);
- //if(debug)V&&dc(title + "は再表示")
- }
- }
- debug && sw("show by returned")
-
- }
- setTimeout(() => { run(document.body, "returned"); }, 0);
- if (SITE.funcQ) SITE.funcQ();
- }
-
- // ヤフオク キーワードの検索対象を切り替えるボタン
- if (SITE.id == "YAJ2") {
- if (location.href.indexOf("://page.auctions.yahoo.co.jp/jp/auction/") == -1) {
- for (let kw of [{ t: "タイトルからのみ検索する", s: "&f=0x2" }, { t: "タイトルと商品説明から検索する", s: "&f=0x4" }]) {
- var ele = eleget0('//div[@class="ptsOption"]/a/../../..');
- if (ele && !(location.href.match(kw.s))) {
- var ele2 = ele.parentNode.insertBefore(document.createElement("a"), ele.nextSibling);
- ele2.innerHTML = kw.t + " ";
- ele2.href = location.href.replace(/\&f\=.*(\&|$)/, "") + kw.s;
- }
- }
- }
- }
-
- // URL変化を監視、変化したら再実行
- if (SITE.urlHasChangedCommonFunc && !observeUrlHasChangedCommon) {
- var observeUrlHasChangedhrefCommon = location.href;
- var observeUrlHasChangedCommon = new MutationObserver(function(mutations) {
- if (observeUrlHasChangedhrefCommon !== location.href) {
- prefCacheClear();
- observeUrlHasChangedhrefCommon = location.href;
- SITE.urlHasChangedCommonFunc();
- }
- });
- observeUrlHasChangedCommon.observe(document, { childList: true, subtree: true });
- }
-
- function run(node = document.body, runmode = "1st", ele = null) { // 1st observed returned
- GF.runStart = Date.now()
- // if(debug)V&&dc("runmode : " + runmode + " / node tag: " + node?.tagName + " / ele.tag : " + ele?.tagName + " / ele.class : " + ele?.className + " ele.id : " + ele?.id); // beautify
- debug && dc("runmode : " + runmode + " / node tag: " + (node.tagName ? node.tagName : "-") + (ele ? (" / ele.tag : " + (ele.tagName ? ele.tagName : "-") + " | ele.class : " + (ele.className ? ele.className : "-") + " | ele.id : " + (ele.id ? ele.id : "-")) : ""));
- debug && sw("reset");
- if (pauseAll) return;
- debug && sw("run");
-
- // if (debug>=3) { elegeta(SITE.listTitleXP).forEach(e => debugEle(e, "force"));elegeta(SITE.listTitleXP2).forEach(e => debugEle(e, "force")) }
- if (debug >= 3 && !(SITE.disableUrlRE && (location.href.match(SITE.disableUrlRE)))) {
- elegeta(SITE.listTitleXP).concat(elegeta(SITE.listTitleXP2)).forEach(e => {
- debugEle(e, "force autoRemove");
- //setTimeout(()=>{debugEle(e,"remove");},2000);
- });
- }
- // サイトごとの個別処理
- if (SITE.func) { SITE.func(node); }
-
- //if (SITE.disableUrlRE && (SITE.disableUrlRE.test(location.href))) { return; }
-
- // ホバー時の操作案内のポップアップを登録
- // if (ENABLE_HELP_CONCLUSION) {
- if ((debug >= 1 || ENABLE_HELP_CONCLUSION) && !(SITE.disableUrlRE && (location.href.match(SITE.disableUrlRE))) && (!SITE?.preventHelpFunc || !SITE?.preventHelpFunc())) {
- var lh = (!isDetail && SITE.helpInBlock) ? $("<span class='ignoreMe phov' id='yafuokuhelp' style='cursor:pointer; color:#505050; font-size:15px; background:#ffffffb0; padding:0px 4px 0px 4px; border-radius:9px;border:#505050 1px solid; position: absolute; bottom:2px; right: 20em;' title='クリックでこのガイドを一時的に消す'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>") : $("<span class='ignoreMe phov' id='yafuokuhelp' style='all:initial; cursor:pointer; z-index:1000; color:#505050; font-size:15px; background:#ffffffc0; padding:3px; border-radius:9px;border:#505050 1px solid; position:fixed; bottom:1em; right: 1em;' title='クリックでこのガイドを一時的に消す'>Q:非表示 W:アンドゥ 1:○メモ 2:×メモ</span>");
- var lh2 = $(`<span class='ignoreMe phov2' id='yafuokuhelp' style='all:initial; cursor:pointer; z-index:2147483647; color:#505050; font-size:15px; background:#ddeeffc0; padding:3px; border-radius:9px;border:#304050 1px solid; position:fixed; bottom:1em; right: 1em;' title='クリックでこのガイドを一時的に消す'>${SITE.XP2name||""}Q:非表示 W:アンドゥ${ SITE.XP2memo?" 1:○メモ 2:×メモ":""}</span>`);
- // 画面全体で1つだけ=詳細画面の方
- if (SITE.detailURLRE && location.href.match(SITE.detailURLRE)) {
- $('span.phov').remove();
- lh.appendTo(document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
- debug && sw("zentai help");
- //SITE.listTitleXP2 + "" → SITE.listTitleXP2 + "/../.."
- $(node).find(elegeta(SITE.listHelpXP2 || (SITE.listTitleXP2 ? SITE.listTitleXP2 + "" : undefined))).off("mouseenter mouseleave").hover(function() {
- $('span.phov').fadeTo(0, 0);
- lh2.appendTo(document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
- }, function() {
- $(".phov2").remove();
- $('span.phov').fadeTo(0, 1);
- }); // test
- } else {
- // 一画面に複数ある=検索結果&セラー画面の方
- if (runmode !== "observed") { // 初処理+追記部分のみ=重複しない処理
- $(elegeta(SITE?.box, node).concat(elegeta(SITE.listHelpJQS, node)).concat(elegeta(SITE.listHelpXP, node)) || (elegeta(SITE.listTitleXP ? SITE.listTitleXP + "/../.." : "", node))).off("mouseenter mouseleave").hover(function() { lh.appendTo(SITE.helpInBlock ? this : document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) }); }, function() { $(".phov").remove() });
-
- $(node).find(elegeta(SITE.listHelpXP2 || (SITE.listTitleXP2 ? SITE.listTitleXP2 + "" : undefined))).off("mouseenter mouseleave").hover(function() {
- $('span.phov').fadeTo(0, 0);
- lh2.appendTo(document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
- }, function() {
- $(".phov2").remove();
- $('span.phov').fadeTo(0, 1);
- }); // test
- } else { // 重複ありの処理
- $(elegeta(SITE?.box, node).concat(elegeta(SITE.listHelpJQS, node)).concat(elegeta(SITE.listHelpXP, node)) || (elegeta(SITE.listTitleXP ? SITE.listTitleXP + "/../.." : "", node))).off("mouseenter mouseleave").hover(function() { lh.appendTo(SITE.helpInBlock ? this : document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) }); }, function() { $(".phov").remove() });
- $(node).find(elegeta(SITE.listHelpXP2 || (SITE.listTitleXP2 ? SITE.listTitleXP2 + "" : undefined))).off("mouseenter mouseleave").hover(function() {
- $('span.phov').fadeTo(0, 0);
- lh2.appendTo(document.body).click(function() { $(this).fadeOut(100).queue(function() { $(this).remove() }) });
- }, function() {
- $(".phov2").remove();
- $('span.phov').fadeTo(100, 1);
- }); // test
- }
- debug && sw("1gyou help");
- }
- }
-
- // 高速化のためにtitleXP/2の要素のtextContentに含まれるメモ・NGだけの集合を作る>documemtのtextContent>documemtのinnerHTML の順
- let fastmode = !fasttest ? null : SITE.listTitleSearchFunc ? null : SITE.title || (!(/\*\*alt\*\*|\+\+alt\+\+|\+\+title\+\+|\+\+url\+\+|\*\*url\*\*/.test(SITE.listTitleSearchXP + " " + SITE.detailTitleSearchXP + " " + SITE.listTitleMemoSearchXP)) && !SITE.listTitleSearchFunc);
- // let fasttext = !fasttest ? null : fastmode ? node.textContent || "" : node.innerHTML || "";
- let fasttext = !fasttest ? null : fastmode ? node.textContent || "" : node.innerHTML + node.textContent || ""; // +node.textContentはnew5chで必要 他にバグ出るかも?
- if (fasttext > "") fasttext = fasttext.replace(/\\u0026|&/gm, "&"); //prompt(fasttext,fasttext) // node.innerText中の&がunicodeエスケープされているのでもとに戻す youtubeで必要
- fasttext = fasttext?.normalize("NFC")
- var fastMatch = null; // !fasttest ? null : fastmode ? (SITE.title ? elegeta(SITE.title, node) : []).concat(SITE.listTitleXP ? elegeta(SITE.listTitleXP, node) : []).concat((SITE.listTitleXP2 ? elegeta(SITE.listTitleXP2, node) : [])).concat((SITE.detailTitleXP ? elegeta(SITE.detailTitleXP, node) : [])) : null;
- debug && sw(fastmode ? "use fast test" : "NOT fast mode")
- if (fasttest && fastmode) { debug && sw("draft by fastMatch") } else { debug && sw("draft by innerHTML") }
-
- // メモ貼りを実行 memo::
- if (runmode === "observed" || runmode === "returned") {
- debug && sw("reset");
- $('span[data-mbt="1"]').remove();
- debug && sw("removing memo");
- }
- var isnotChrome = (window.navigator.userAgent.toLowerCase().indexOf('chrome') == -1);
-
- var titles = pref(SITE.id + ' : SearchMyMemo') || []
- if (SITE?.memoOnRead) titles = SITE.memoOnRead(titles)
- if (titles) { // if (pref(SITE.id + ' : SearchMyMemo')) {
- var i = 0;
- var hitTitle = [];
- // var titles = pref(SITE.id + ' : SearchMyMemo')
- //var titles = JP(JS(pref(SITE.id + ' : SearchMyMemo')).normalize("NFC"))
- if (fasttest) {
- if (fastMatch) {
- for (let ele of fastMatch) { hitTitle = hitTitle.concat(titles.filter(t => { return ele.textContent.indexOf(t.t?.normalize("NFC")) !== -1 })); } debug && sw("mymemo draft-test");
- debug && sw("memo/fastMatch")
- } else { // document.innerHTMLにタイトルが含まれるメモに絞り込む
- // hitTitle = hitTitle.concat(titles.filter(t => fasttext.indexOf(t.t?.normalize("NFC")) !== -1)); //453,463
- hitTitle = hitTitle.concat(titles.filter(t => fasttext.includes(t.t?.normalize("NFC")))); //453,463
- debug && sw(`memo/indexOf ${hitTitle.length}`)
- }
- hitTitle = [...new Set(hitTitle)];
- for (let a of hitTitle.sort(function(a, b) { return isnotChrome ? (a.c == COLORCPUSCORE && b.c !== COLORCPUSCORE ? 1 : 0) : (a.c != COLORCPUSCORE && b.c == COLORCPUSCORE ? -1 : 0); })) {
- memoByTitle(a.t, a.m, node, a.c || COLOR1, a.u);
- }
- debug && sw("memo/fastTest")
- } else {
- for (let a of pref(SITE.id + ' : SearchMyMemo').sort(function(a, b) { return isnotChrome ? (a.c == COLORCPUSCORE && b.c !== COLORCPUSCORE ? 1 : 0) : (a.c != COLORCPUSCORE && b.c == COLORCPUSCORE ? -1 : 0); })) {
- memoByTitle(a.t, a.m, node, a.c || COLOR1, a.u);
- }
- debug && sw("memo/slow")
- }
- }
- debug && sw("mymemo ( draft-matched : " + ((hitTitle || []).length) + " )"); //JSON.stringify(hitTitle)
-
- // 非表示を実行 hide::
- var help = (KEYHIDE + ":非表示 " + KEYUNDO + ":アンドゥ " + (isHidePartialMatch ? (SITE.disableKeyB ? "" : KEYBW + ":NGワード ") : "") + KEYEDIT + ":NG編集 " + KEYMEMO1 + KEYMEMO2 + ":メモを追加 " + KEYMEMO1S + KEYMEMO2S + ":自由メモ " + KEYMEMO5 + KEYMEMO6 + ":定型メモ " + KEYRESETMEMO + ":メモを編集 " + (SITE.automemoURLRE ? KEYRESETMEMOAUTO + ":自動メモのみ全削除 " : "") + KEYTOGGLEtranslucent + ":半透明") + ((SITE.wholeHelp && SITE.wholeHelp[0]() && SITE.wholeHelp[1]) || "");
- if (pref(SITE.id + ' : SearchHideTitle')) {
- var i = 0;
- var hitTitle = [];
- // var titles = pref(SITE.id + ' : SearchHideTitle') //.map(q=>q?.nfd())
- var titles = JP(JS(pref(SITE.id + ' : SearchHideTitle')).normalize("NFC")) //.map(q=>q?.nfd())
- if (fasttest) {
- if (fastMatch) {
- for (let ele of fastMatch) {
- var a = titles.filter(t => ele.textContent.indexOf(t) !== -1);
- if (a) hitTitle = hitTitle.concat(a);
- } //console.log(hitTitle)
- } else { // document.innerHTMLにタイトルが含まれるメモに絞り込む
- hitTitle = titles.filter(t => { return fasttext.indexOf(t) !== -1 });
- }
- hitTitle = [...new Set(hitTitle)];
- debug && sw("block draft-test");
- for (let title of hitTitle || []) { i += hideByTitle(title, node); }
- debug && sw("block ( actually : " + i + " / draft-matched : " + ((hitTitle || []).length) + (fastMatch ? " / target : " + fastMatch.length : "") + " )");
- } else {
- for (let title of pref(SITE.id + ' : SearchHideTitle') || []) { i += hideByTitle(title, node); }
- debug && sw("block ( actually : " + i + " )");
- }
- if (i) { help = i + "個を非表示にしました\n" + help + (debug && fasttest ? " \n\nドラフトでマッチ:" + (JSON.stringify(hitTitle.slice(0, 9))) : ""); }
- }
- // 全体ヘルプを表示
- // if (debug || (ENABLE_HELP_CONCLUSION && (SITE.helpOnDNI || (runmode === "1st" && SITE.listTitleXP)) && !(SITE.disableUrlRE && (location.href.match(SITE.disableUrlRE))))) popup2(help, 1);
- if (debug || (ENABLE_HELP_CONCLUSION && (SITE.helpOnDNI || (runmode === "1st" && (SITE.title || SITE.listTitleXP))) && !(SITE.disableUrlRE && (location.href.match(SITE.disableUrlRE))))) popup2(help, 1.5);
-
- // 自動メモを探索&製作
- function mekeautomemo() {
- if (ENABLE_AUTOMEMO && SITE?.automemoFunc &&
- (SITE?.automemoURLRE && location?.href?.match(SITE.automemoURLRE) || isDetail || (SITE?.automemoForceFunc && SITE?.automemoForceFunc()))
- ) { SITE?.automemoFunc(); }
- }
- mekeautomemo()
- for (let t = 0; t < ENABLE_AUTOMEMO; t++) {
- setTimeout(() => {
- mekeautomemo()
- }, (t + 1) * 2000)
- }
- debug && sw("automemo")
- //debug&&t>0?popup3( t * t / 2 * 1000,2,1):0; }
- //}
-
- if (SITE.funcFinally) SITE.funcFinally(disableHide, i); // Qが有効、非表示にした個数
- GF.runElapsed = Date.now() - GF.runStart
- debug && sw(`run total : ${GF.runElapsed}`)
- return;
- }
-
- function restoreTranslucent() {
- if (pref(SITE.id + ' : SearchHideTitle')) {
- let fastmode = !fasttest ? null : SITE.listTitleSearchFunc ? null : SITE.title || (!(/\*\*alt\*\*|\+\+alt\+\+|\+\+title\+\+|\+\+url\+\+|\*\*url\*\*/.test(SITE.listTitleSearchXP + " " + SITE.detailTitleSearchXP + " " + SITE.listTitleMemoSearchXP)) && !SITE.listTitleSearchFunc);
- // var fasttext = !fasttest ? null : fastmode ? document.body.textContent?.nfd() || "" : document.body.innerHTML?.nfd() || "";
- var fasttext = !fasttest ? null : fastmode ? document.body.textContent || "" : document.body.innerHTML || "";
- fasttext = fasttext?.normalize("NFC")
-
- var fastMatch = null //!fasttest ? null : fastmode ? (SITE.title ? elegeta(SITE.title) : []).concat(SITE.listTitleXP ? elegeta(SITE.listTitleXP) : []).concat((SITE.listTitleXP2 ? elegeta(SITE.listTitleXP2) : [])).concat((SITE.detailTitleXP ? elegeta(SITE.detailTitleXP) : [])) : null;
-
- debug && dc(fastmode ? "restoreTranslucent : use fastmode" : "restoreTranslucent : not use fastmode")
- debug && sw("reset")
- var i = 0;
- var hitTitle = [];
- //var titles = pref(SITE.id + ' : SearchHideTitle').map(e => e = e)
- var titles = JP(JS(pref(SITE.id + ' : SearchHideTitle')).normalize("NFC"))
- if (fasttest) {
- if (fastMatch) {
- for (let ele of fastMatch) {
- //var a = titles.filter(t => ele.textContent.indexOf(t) !== -1);
- var a = titles.filter(t => ele.textContent?.normalize("NFC")?.indexOf(t) !== -1);
- if (a) hitTitle = hitTitle.concat(a);
- }
- } else {
- hitTitle = titles.filter(t => { return fasttext.indexOf(t) !== -1 });
- }
- hitTitle = [...new Set(hitTitle)];
- } else {
- hitTitle = pref(SITE.id + ' : SearchHideTitle') || []
- }
- for (let title of hitTitle) showByTitle(title, 0);
- debug && sw("restoreTranslucent")
- }
- if (SITE.funcOnTOn) SITE.funcOnTOn();
- }
-
- function eletext(xpa, xp) {
- if (typeof xpa == "string") { // string
- let e = eleget0(xpa);
- if (e) debugEle(e);
- return e ? e.innerText : "";
- } else { // array
- let text = "";
- xpa.forEach(xp => {
- elegeta(xp).forEach(e => {
- e = e.cloneNode(true, true) // 繰り替えさないようにメモは除外
- elegeta('.yhmMyMemo', e).forEach(v => v.remove())
- debugEle(e);
- text = text + (e.innerText + "\n");
- })
- })
- return text;
- }
- }
-
- function autoMemo2(automemotarget, re) {
- let node = document.body;
- let sou = automemotarget?.match(re);
- if (sou && sou.length) {
- sou.shift();
- var memo = Array.from(new Set(sou)).join(" ").replace(/[A-Za-z0-9.,]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248) }).replace(/\s{2,99}| /gm, " ").trim();
- var title = getDetailTitle()
- if (!title) return;
- var tmp = pref(SITE.id + ' : SearchMyMemo') || [];
- var isExist = tmp.filter(e => e.t == title && e.m == memo);
- if (isExist.length == 0) {
- if (debug) popup3(memo, 2, 5000);
- storeMemo(title, memo, COLOR3, node);
- }
- return true;
- }
- return false;
- }
-
- function autoMemo(re, func) {
- let automemotarget = SITE.automemoSearchFunc();
- if (func) automemotarget = func(automemotarget)
- let node = document.body;
- let sou = automemotarget.match(re);
- if (sou && sou.length) {
- sou.shift();
- var memo = Array.from(new Set(sou)).join(" ").replace(/[A-Za-z0-9.,]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248) }).replace(/\s{2,99}| /gm, " ").trim();
- // node.innerHTML=node.innerHTML.replace(re,"<mark>$1</mark>");
- var title = getDetailTitle()
- if (!title) return;
- var tmp = pref(SITE.id + ' : SearchMyMemo') || [];
- var isExist = tmp.filter(e => e.t == title && e.m == memo);
- if (isExist.length == 0) {
- if (debug) popup3(memo, 2, 5000);
- storeMemo(title, memo, COLOR3, node);
- }
- return true;
- }
- return false;
- }
-
- function getDetailTitle(x, y) {
- var ele = ((SITE.detailTitleXP && isDetail) && eleget0(SITE.detailTitleXP)) || (eleget0(SITE?.title)) || document.elementFromPoint(mousex, mousey);
- if (!ele) return;
- var title = getTitleFromParent(ele);
- if (!title) return;
- return title;
- }
-
- function getTitleFromParent(ele, nodisplay = 0) { // ele要素の親の出品物タイトルを返す
- if (!nodisplay)
- debug && dc("start at : " + ele.innerText);
- if (SITE.title) {
- let box = ele?.closest(SITE.box)
- if (box) {
- let title = eleget0(SITE.title, box)?.textContent?.trim()
- if (title) { return title }
- return
- }
- }
- // if (isDetail) return tri((SITE.useText ? ele.textContent.replace(/\|/g, '\|') : ele.title || ele.textContent.replace(/\|/g, '\|') || ele.alt));
- if (isDetail) return tri((SITE.useText ? ele.textContent.replace(/\|/g, '\|') : SITE.useURL ? ele.getAttribute("href").replace(/\?.*$/, "") : ele.title || ele.textContent.replace(/\|/g, '\|') || ele.alt));
- for (let i = 0; i < (SITE.listGen); i++) {
- if (!nodisplay)
- debug && dc("go up (" + i + ") : " + ele.innerText)
- var ele2 = elegeta(SITE.listTitleXP, ele);
- if (!nodisplay)
- debug && dc("length:" + ele2.length)
- if (ele2.length === 1 || (SITE.searchAllowLength && ele2.length)) {
- if (!nodisplay)
- debug && dc("href : " + ele2[0].getAttribute("href") + "\ntitle : " + tri((ele2[0].title + " \ntextContent : " + ele2[0].textContent.replace(/\|/g, '\|') + " \nalt : " + ele2[0].alt)));
- return SITE.useURL ? ele2[0].getAttribute("href").replace(/\?.*$/, "") : SITE.useText ? tri(ele2[0].textContent.replace(/\|/g, '\|')) : tri((ele2[0].title || ele2[0].textContent.replace(/\|/g, '\|') || ele2[0].alt));
- }
- if (ele === document) return;
- ele = ele.parentNode;
- }
- return;
- }
-
- function tri(str) {
- if (!str) return "";
- if (str.match(/\"/)) { popup3("項目名に \" を含むので多分うまく処理できません"); return ""; }
- return (SITE.trim) ? str.trim() : str;
- }
-
- function memoElement(ele, node, color = COLOR1, memoword = "") { //12 memo
- if (!ele) return;
- var title = typeof ele === "string" ? ele : getTitleFromParent(ele);
- if (!title) return;
- if (SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
- if (!title) return;
- var memo = memoword || (prompt("『" + title + "』\nのメモを書いてください") || "").trim();
- // storeMemo(title, sani(memo), color, node);
- storeMemo(title, memo, color, node);
- return true;
- }
-
- function storeMemo(title, memo, color = COLOR1, node = document, jumpUrl = null) {
- if (title && memo) {
- memo = sani(memo)
- let tmp = pref(SITE.id + ' : SearchMyMemo') || [];
-
- var isExist = tmp.filter(e => e.t === title && e.c === color && e.m === memo); // 重複してなければ
- if (isExist.length == 0) {
-
- jumpUrl ? tmp.push({ t: title, m: memo, c: color, u: jumpUrl }) : tmp.push({ t: title, m: memo, c: color })
- pref(SITE.id + ' : SearchMyMemo', tmp)
- memoByTitle(title, memo, node, color, jumpUrl);
- }
- }
- }
-
- function memoByTitle(title, memo, node, color, jumpUrl = null) {
- let titleNfc = title?.normalize("NFC")
-
- if ((SITE.preventMemo && SITE.preventMemo(memo)) || (title.indexOf('"') !== -1 && !SITE.box)) return; // todo:タイトルに"があると正しく検索できないので処理しない
- // var xp = SITE?.listTitleMemoSearchXP?.replaceTitle(title?.nfd());
- var xp = SITE?.listTitleMemoSearchXP?.replaceTitle(title);
- let isChapterMemo = color === COLORVIDEOTIME; // && memo.match0(/^([\d:]+)\s/)
- let memoPosition = SITE.memoPosition || "afterend"
- for (let titleEle of
- SITE.title ?
- // SITE.titleSubstr ? elegeta(SITE.title, node).filter(e => e?.textContent.indexOf(title) !== -1) :
- // elegeta(SITE.title, node).filter(e => e?.textContent === title || e?.title === title || SITE.trim && e?.textContent?.trim() === title) :
- SITE.titleSubstr ? elegeta(SITE.title, node).filter(e => e?.textContent?.normalize("NFC").indexOf(titleNfc) !== -1) :
- elegeta(SITE.title, node).filter(e => e?.textContent?.normalize("NFC") === titleNfc || e?.title?.normalize("NFC") === titleNfc || SITE.trim && e?.textContent?.normalize("NFC")?.trim() === titleNfc) :
- elegeta(xp, node)) {
- //for (let titleEle of SITE.title ? elegeta(SITE.title, node).filter(e => e?.textContent?.trim()?.nfd() === title?.nfd() || e?.title?.nfd() === title?.nfd() || SITE.trim && e?.textContent?.trim()?.nfd() === title?.nfd()) : elegeta(xp, node)) {
- if (titleEle) {
- var ele1 = SITE.memoFunc ? SITE.memoFunc(titleEle) : // titleノードから位置をずらす関数
- SITE.listTitleMemoSearchXPSameGen ? titleEle :
- titleEle.parentNode;
- if (!ele1) return;
- let isCPU = memo.match(/Pentium|Celeron|Core\s?i\d|Ryzen|GHz|AMD.*APU/i);
-
- if (isChapterMemo && GF?.isNico && titleEle?.href) jumpUrl = `${titleEle?.href?.replace(/\?.*$/,"")}?from=${hms2sec(memo.match0(/^([\d:]+)\s/))}`;
-
- //ele1.insertAdjacentHTML(memoPosition, '<span data-mbt="1" class="ignoreMe"><span class="ignoreMe yhmMyMemo yhmMyMemo' + (color === COLOR2 ? "X" : "O") + '" id="' + escape(title + memo + color) + '" title="『' + title.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/\`/g, '`').replace(/</g, "<").replace(/>/g, ">").replace(/\n/gm, "<br>") + '』についたメモ(クリックで削除)' + (isCPU ? "\n\n右クリックでuserbenchmark検索\nhttps://duckduckgo.com/?q=!ducky+" + memo.replace(/[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf\s]+/g, "+") + "+userbenchmark" : "") + (isChapterMemo ? "\n右クリックでこの位置から再生\n" + (jumpUrl ? jumpUrl + "\n" : "") + "Shift+Uで再生位置の列挙をコピー" : "") + '" style="' + MEMOSTYLE + (isCPU ? " cursor:help; " : "") + ' background-color:' + color + ';">' + memo + '</span>')
- ele1.insertAdjacentHTML(memoPosition, `<span data-mbt="1" class="ignoreMe"><span class="ignoreMe yhmMyMemo yhmMyMemo${color === COLOR2 ? "X" : "O"}" data-yhmc="${color}" id="${escape(title + memo + color)}" title="『${ title.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/\`/g, '`').replace(/</g, "<").replace(/>/g, ">").replace(/\n/gm, "<br>")}』についたメモ(クリックで削除)${(isCPU ? "\n\n右クリックでuserbenchmark検索\nhttps://duckduckgo.com/?q=!ducky+" + memo.replace(/[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf\s]+/g, "+") + "+userbenchmark" : "") + (isChapterMemo ? "\n右クリックでこの位置から再生\n" + (jumpUrl ? jumpUrl + "\n" : "") + "Shift+Uで再生位置の列挙をコピー" : "")}" style="${ MEMOSTYLE + (isCPU ? " cursor:help; " : "") } background-color:${color};">${ memo }</span>`)
- var ele = memoPosition !== "afterend" ? ele1.firstElementChild : ele1.nextElementSibling.firstElementChild
- //if (!memofast) $(ele).hide().fadeIn(SITE.observe ? 0 : 150);
- $(ele).hide().fadeIn(SITE.observe || memofast ? 0 : 150);
- //$(ele).hide().fadeIn(SITE.observe ? 0 : 150);
-
-
- if (SITE?.callGKSIafterMemo) {
- clearTimeout(GF?.gksiAfterMemo)
- GF.gksiAfterMemo = setTimeout(() => document.dispatchEvent(new CustomEvent('plzGKSI')), 999)
- }
-
- // CPUモデルナンバーを右クリックでuserbenchmark検索
- if (isCPU) {
- $(ele).on('contextmenu', (function(title, memo) {
- return function() {
- if (pref("lastItemName") == undefined) { // 前回の処理が終わってないとだめ
- pref("lastItemName", title);
- popup3(title);
- memo = memo.replace(/[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf\s]+/g, "+");
- window.open("https://duckduckgo.com/?q=!ducky+" + memo + "+userbenchmark", "", "noreferrer");
- setTimeout(() => {
- if (pref("lastItemName")) {
- popup3("Investigating " + memo + " timed out");
- pref("lastItemName", "");
- }
- }, 30000); // 30秒以内に見ないとだめ
- }
- return false;
- }
- })(title, memo));
- }
- // チャプターメモメモを右クリックでその場所に移動 u::
- if (isChapterMemo) {
- ele.dataset.cm = "1"
- // if(!GF.plNotFlex){GM_addStyle("#meta.ytd-playlist-panel-video-renderer{display:block}"),GF.plNotFlex=1;} // プレイリストがdisplay:flexで1行に詰め込めないので外す試用
- // var p=ele.closest('#meta');if(p)p.style.display="block !important"
- if (/\/watch/.test(location.href) && (ele.closest("#title,.ytd-video-primary-info-renderer") || ele1?.classList?.contains("HeaderContainer-topAreaLeft"))) {
- // $(ele).on('contextmenu', (function(title, memo) {
- ele.addEventListener('contextmenu', e => {
- var videoEle = eleget0('//video');
- if (!videoEle) return
- videoEle.currentTime = hms2sec(memo.match0(/^([\d:]+)\s/)) || videoEle.currentTime
- //videoEle.scrollIntoView({ block: "center", behavior: "smooth" })
- e.preventDefault()
- return false;
- })
- //})(title, memo));
- } else {
- var p = ele.closest('.ytd-playlist-panel-video-renderer')?.style?.display;
- p = "block !important"
- if (jumpUrl) ele.dataset.url = jumpUrl
- ele.addEventListener('contextmenu', e => {
- var jumpUrl = e.target.dataset.url || null
- if (jumpUrl) {
- (eleget0('//video') && !eleget0('//video')?.paused) || e.ctrlKey ? (eleget0('//video')?.pause(), window.open(jumpUrl, "", "noreferrer")) : location.href = jumpUrl;
- e.preventDefault()
- return false;
- }
- })
- }
- }
- setRemoveMemo(ele, title, memo, color)
- }
- }
- }
-
- function setRemoveMemo(ele, title, memo, color) { // メモをクリックで消す処理
- $(ele).on("click", e => { // 遅いかも?
- e.preventDefault();
- e.stopPropagation();
- //pref(SITE.id + ' : SearchMyMemo', (pref(SITE.id + ' : SearchMyMemo') || []).filter(n => !(n.t == title && n.m == memo && n.c == color)))
- pref(SITE.id + ' : SearchMyMemo', (pref(SITE.id + ' : SearchMyMemo') || []).filter(n => !(n.t?.normalize("NFC") == title?.normalize("NFC") && n.m == memo && n.c == color)))
- for (let e of elegeta('//span[contains(@class,"yhmMyMemo") and @id="' + escape(title + memo + color) + '"]')) $(e).hide(200).queue(function() { $(this.parentNode).remove() }); //e.remove(); //ele.remove();
- document.body.dispatchEvent(new Event('yhmMyMemoRemoved'))
- //adja(document.body, "afterbegin", "<yhmmymemoremoved></yhmmymemoremoved>");
- //eleget0('yhmmymemoremoved')?.remove(); // 学園祭用に消去を告知
- })
- }
-
- function blockElement(ele) { //Q:: toggle
- if (!ele) return;
- var title = getTitleFromParent(ele);
- debug && dc(`got (${SITE?.box}→${SITE?.title}): 『${ title}』`)
- addNG(title);
- }
-
- function hideByTitle(titleOrEle, node, targetXP = SITE.listTitleSearchXP) {
- if (typeof titleOrEle === "object") { titleOrEle = titleOrEle.textContent }
- var titleNfcH = titleOrEle.normalize("NFC")
- let i = 0;
- if (!isDetail || SITE.hideListEvenDetail) {
- let resHit = [];
- if (SITE.listTitleSearchFunc) resHit = SITE.listTitleSearchFunc(titleOrEle); // 主に5ch用、レス中キーワードNG
- // 1項目ずつ
- // for (let ele of typeof titleOrEle === "object" ? [titleOrEle] : elegeta(targetXP.replaceTitle(titleOrEle), node).concat(resHit)) { // titleがテキストなら項目タイトルにヒットする要素、DOM要素なら直接それを隠す
- // for (let ele of (typeof titleOrEle === "object" ? [titleOrEle] : SITE.title ? elegeta(SITE.title, node).filter(v => (SITE.titleProcessFunc ? SITE.titleProcessFunc(v.textContent?.trim()) : v.textContent?.trim()) === titleOrEle).map(v => v.closest(SITE.box)) : elegeta(targetXP.replaceTitle(titleOrEle), node)).concat(resHit)) { // titleがテキストなら項目タイトルにヒットする要素、DOM要素なら直接それを隠す
- for (let ele of (typeof titleOrEle === "object" ? [titleOrEle] : SITE.title ? elegeta(SITE.title, node).filter(v => (SITE.titleProcessFunc ? SITE.titleProcessFunc(v.textContent?.normalize("NFC")?.trim()) : v.textContent?.normalize("NFC")?.trim()) === titleNfcH).map(v => v.closest(SITE.box)).concat(resHit) : elegeta(targetXP.replaceTitle(titleOrEle), node)).concat(resHit)) { // titleがテキストなら項目タイトルにヒットする要素、DOM要素なら直接それを隠す
- //for (let ele of (typeof titleOrEle === "object" ? [titleOrEle] : SITE.title ? elegeta(SITE.title, node).filter(v => (SITE.titleProcessFunc ? SITE.titleProcessFunc(v.textContent?.normalize("NFC")?.trim()) : v.textContent?.normalize("NFC")?.trim()) === titleNfc).map(v => v.closest(SITE.box)) : elegeta(targetXP.replaceTitle(titleOrEle), node)).concat(resHit)) { // titleがテキストなら項目タイトルにヒットする要素、DOM要素なら直接それを隠す
-
- if (!ele) continue;
- i++;
- // ele.dataset.hidden = "1";
- // if (!disableHide && !SITE.forceTranslucentFunc?.includes(ele?.tagName)) {
- // if (!disableHide && !SITE.forceTranslucentFunc?.test(ele?.tagName)) {
- // if (!disableHide && (!SITE.forceTranslucentFunc || !ele.closest(SITE.forceTranslucentFunc))) {
- // if (!disableHide && (!SITE.forceTranslucentFunc || !ele.closest(SITE.forceTranslucentFunc)) && (!SITE.forceTranslucentFunc || !SITE.forceTranslucentFunc(ele))) {
- gmDataList_add(ele, "gmHideByyhm");
- if (!disableHide && (!SITE.forceTranslucentFunc || !SITE.forceTranslucentFunc(ele))) {
- // if (!disableHide && (!SITE.forceTranslucentFunc || (typeof SITE.forceTranslucentFunc==="String"? !ele.closest(SITE.forceTranslucentFunc)):(!SITE.forceTranslucentFunc(ele)))) {
- $(ele).fadeOut(17);
- ele.dataset.hidden = "1";
- // ele.dataset.yhmkey = titleOrEle;
- ele.dataset.yhmkey = titleNfcH
- } else {
- ele.style.opacity = "0.75";
- setTimeout(function() { ele.style.opacity = "0.50" }, 17 * 2);
- ele.dataset.hidden = "2"; // 必要?
- // ele.dataset.yhmkey = titleOrEle;
- ele.dataset.yhmkey = titleNfcH
- elegeta('//*[text()="' + titleOrEle + '"]').forEach(e => { debugEle(e, "autoRemove") });
- // if (!ele.title && typeof titleOrEle === "string") { ele.dataset.whyitishidden = `非表示登録『${titleOrEle}』にヒット` }
- // if (!ele.title && typeof titleOrEle === "string") { ele.dataset.whyitishidden = `非表示登録『${titleOrEle}』にヒット`; ele.title=`非表示登録『${titleOrEle}』にヒット` }
- if (!ele.title) ele.title = `非表示登録『${titleOrEle}』にヒット`
- ele.dataset.whyitishidden = `非表示登録『${titleOrEle}』にヒット`
- }
- }
- }
- if (isDetail) {
- // 詳細:画面全体
- if (isDetail && SITE.detailTitleXP && SITE.detailTitleSearchXP) {
- var xp = SITE.detailTitleSearchXP.replaceTitle(titleOrEle) // isearでハイライトされていると×
- for (let ele of elegeta(xp, node)) {
- if (!ele) continue;
- gmDataList_add(ele, "gmHideByyhm");
- debug && dc(xp, ele, ele.textContent);
- i++;
- ele.style.opacity = "0.5";
- if (!ele.title) ele.title = `非表示登録『${titleOrEle}』にヒット`
- ele.dataset.whyitishidden = `非表示登録『${titleOrEle}』にヒット`
- }
- }
- }
- return i;
- }
-
- function showByTitle(titleOrEle, time = 34, xpath = SITE.listTitleSearchXP) {
- if (typeof titleOrEle === "object") { titleOrEle = titleOrEle.textContent }
- if (typeof titleOrEle === "string") { var titleNfcH = titleOrEle.normalize("NFC") }
-
- // if (!xpath) return
- if (!isDetail || SITE.hideListEvenDetail) {
- let resHit = [];
- if (SITE.listTitleSearchFunc) resHit = SITE.listTitleSearchFunc(titleOrEle);
- // 1項目ずつ
- //var xp = xpath.replaceTitle(titleOrEle);
- // SITE.title ? elegeta(SITE.title, node).filter(v => (SITE.titleProcessFunc?SITE.titleProcessFunc(v.textContent):v.textContent) === titleOrEle).map(v => v.closest(SITE.box)) :
- // for (let ele of typeof titleOrEle === "object" ? [titleOrEle] : SITE.title ? elegeta(SITE.title).filter(e => e?.textContent == titleOrEle).map(e => e?.closest(SITE.box)) : elegeta(xpath.replaceTitle(titleOrEle)).concat(resHit)) {
-
- // for (let ele of (typeof titleOrEle === "object" ? [titleOrEle] : SITE.title ? elegeta(SITE.title).filter(v => (SITE.titleProcessFunc ? SITE.titleProcessFunc(v.textContent?.trim()) : v.textContent?.trim()) === titleOrEle).map(e => e?.closest(SITE.box)) : elegeta(xpath.replaceTitle(titleOrEle))).concat(resHit)) {
- for (let ele of (typeof titleOrEle === "object" ? [titleOrEle] : SITE.title ? elegeta(SITE.title).filter(v => (SITE.titleProcessFunc ? SITE.titleProcessFunc(v.textContent?.normalize("NFC")?.trim()) : v.textContent?.normalize("NFC")?.trim()) === titleNfcH).map(e => e?.closest(SITE.box)).concat(resHit) : elegeta(xpath.replaceTitle(titleNfcH))).concat(resHit)) {
-
- if (!ele) continue;
-
- gmDataList_remove(ele, "gmHideByyhm");
- if (!gmDataList_includesPartial(ele, 'gmHideBy')) {
-
- if (ele) ele.style.opacity = "1";
- $(ele).fadeIn(time);
- // delete ele.dataset.hidden;
- if (ele) ele.dataset.hidden = null; //ele.dataset.yhmkey=null;
- //setTimeout(function() { ele.style.opacity = "1" }, 17 * 2);
- }
- }
- }
- if (isDetail) {
- // 詳細:画面全体
- if (isDetail && SITE.detailTitleXP && SITE.detailTitleSearchXP) {
- var xp = SITE.detailTitleSearchXP.replaceTitle(titleOrEle) // isearでハイライトされていると×
- for (let ele of elegeta(xp)) {
- if (!ele) continue;
- gmDataList_remove(ele, "gmHideByyhm");
- if (!gmDataList_includesPartial(ele, 'gmHideBy')) {
- ele.style.opacity = "1";
- }
- }
- }
- }
- }
-
- function addNGWord() {
- let tips = SITE?.Bsyntax2 ? "独自構文Tips:\n「ABCやDEFを含まず、GHIかJKLを含み、かつMNOとPQRも含む」\n!ABC|DEF GHI|JKL MNO PQR\n\n" : "";
- var newWord = (prompt(`非表示にしたい項目が含むNGワードを入力してください${SITE.QRule||""}\nすでに登録されている文字列を入力するとそれを削除します\n\n${tips}現在の全体\n${JSON.stringify(pref(SITE.id + ' : SearchHideTitle') || []) }\n\n`) || "").trim();
- newWord = SITE?.Bsyntax2 ? newWord.replace(/^S$/, "??").replace(/^S([\s \||])/, "??$1").replace(/([\s \||!!])S([\s \||])/, "$1??$2").replace(/([\s \||!!])S$/, "$1??").replace(/|/gm, "|").replace(/^[\!|!](\S*)/, "^(?!.*($1)).*").replace(/(\S*)[ ](\S*)/gm, "^(?=.*($1))(?=.*\($2\))").replace(/\s| /gm, ".*") : newWord // 独自構文を正規表現に変換
- if (newWord && (pref(SITE.id + ' : SearchHideTitle') || []).includes(newWord) && confirm(`${newWord}\nはすでに存在します\n削除しますか?\n\n`) == false) return;
- addNG(newWord);
- }
- /* function addNGWord() {
- var newWord = (prompt(`非表示にしたい項目が含むNGワードを入力してください${SITE.QRule||""}\nすでに登録されている文字列を入力するとそれを削除します\n\n現在の全体\n${JSON.stringify(pref(SITE.id + ' : SearchHideTitle') || []) }\n\n`) || "").trim();
- if (newWord && (pref(SITE.id + ' : SearchHideTitle') || []).includes(newWord) && confirm(`${newWord}\nはすでに存在します\n削除しますか?\n\n`) == false) return;
- addNG(newWord);
- }
- */
-
- function addNG(title) {
- if (!title) return;
- if (SITE.titleProcessFunc) title = SITE.titleProcessFunc(title);
- if (!title) return;
- let resist = pref(SITE.id + ' : SearchHideTitle') || [];
- let i = resist.indexOf(title);
- if (i !== -1) {
- resist.splice(i, 1);
- pref(SITE.id + ' : SearchHideTitle', resist);;
- popup2("『" + title + "』\nを非表示登録から削除しました", 1);
- showByTitle(title);
- if (isDetail && SITE.showFunc) SITE.showFunc();
- } else {
- resist.push(title);
- pref(SITE.id + ' : SearchHideTitle', resist);
- popup2("『" + title + "』\nを非表示登録しました(" + KEYUNDO + ":取り消し " + KEYEDIT + ":編集)", 1);
- hideByTitle(title);
- }
- }
-
- // キャッシュ付き
- var elegetaCacheXP = "";
- var elegetaCacheLastTime = new Date();
- var elegetaCacheResult = [];
- var elegetaCacheNode = "";
- var ehit = 0;
- var emiss = 0;
-
- function elegeta(xpath, node = document) {
- if (!xpath || !node) return [];
- //if (typeof xpath === "function") return xpath() // !!!
- if (Array.isArray(xpath)) return xpath.map(v => elegeta(v, node)).filter(v => v.length).flat();
- // let xpath2 = xpath.replace(/:inv?screen|:visible|:text\*=[^:]*/g, "") // text*=~中で:は使えない
- let xpath2 = xpath.replace(/:inscreen|:visible|:text\*=[^:]*/g, "") // text*=~中で:は使えない
- let array = []
- try {
- if (!/^\.?\//.test(xpath)) {
- array = [...node.querySelectorAll(xpath2)]
- } else {
- // var snap = document.evaluate("." + xpath2, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null)
- var snap = document.evaluate("." + xpath2, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
- let l = snap.snapshotLength
- for (var i = 0; i < l; i++) array[i] = snap.snapshotItem(i)
- }
- if (/:visible/.test(xpath)) array = array.filter(e => e.offsetHeight)
- //if (/:invscreen/.test(xpath)) array = array.filter(e => { var eler = e.getBoundingClientRect(); return (eler.bottom >= 0 && eler.top <= document.documentElement.clientHeight) }) // 画面縦内に1ピクセルでも入っている
- if (/:inscreen/.test(xpath)) array = array.filter(e => { var eler = e.getBoundingClientRect(); return (eler.bottom >= 0 && eler.right >= 0 && eler.left <= document.documentElement.clientWidth && eler.top <= document.documentElement.clientHeight) }) // 画面内に1ピクセルでも入っている
- if (/:text\*=./.test(xpath)) { let text = xpath.replace(/^.*:text\*=([^:]*)$/, "$1"); if (text) array = array.filter(e => new RegExp(text).test(e?.textContent)) }
- } catch (e) { alert(`XPath/CSS構文にエラーがあるかもしれません\n2023/12以前にインストールしたFirefoxを使っている場合はabout:configでlayout.css.has-selector.enabled を true にすると解決するかもしれません\n\n${e}\n\n${xpath}\n\n${JSON.stringify(node)}`); return []; }
- //} catch (e) { return []; }
- return array
- }
-
- function eleget0(xpath, node = document) {
- if (!xpath || !node) return null;
- //if (typeof xpath === "function") return xpath() // !!!
- // if (/:inv?screen|:visible|:text\*=/.test(xpath)) return elegeta(xpath, node)?.shift();
- if (/:inscreen|:visible|:text\*=/.test(xpath)) return elegeta(xpath, node)?.shift();
- if (!/^\.?\//.test(xpath)) return node.querySelector(xpath);
- try {
- // var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
- var ele = document.evaluate("." + xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- return ele.snapshotLength > 0 ? ele.snapshotItem(0) : null;
- } catch (e) { alert(`XPath/CSS構文にエラーがあるかもしれません\n2023/12以前にインストールしたFirefoxを使っている場合はabout:configでlayout.css.has-selector.enabled を true にすると解決するかもしれません\n\n${e}\n\n${xpath}\n\n${JSON.stringify(node)}`); return null; }
- //} catch (e) { alert(e + "\n" + xpath + "\n" + JSON.stringify(node)); return null; }
- }
-
- function dc(str, force = 0) {
- //if (debug == 1) console.log(str);
- if (debug >= 1 || force) popup3(str, 0, 31000, "top");
- return str;
- }
-
- function popup3(text, i = 0, timer = 5000, alignY = "bottom") {
- if (!ENABLE_HELP_CONCLUSION) return;
- if (text === undefined || text === null) text = "<null>"
- if (typeof text == "string") text = text.slice(0, 200);
- // if (typeof text == "number") text = String(text);
- if (typeof text == "number") text = String(text);
- text = text.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/`/g, '`').replace(/</g, "<").replace(/>/g, ">").replace(/\n/gm, "<br>")
- let id = Math.random().toString(36).substring(2);
- let maey = alignY == "bottom" ? 0 : elegeta(".wcspu3top").map(e => e.getBoundingClientRect().bottom).reduce((a, b) => Math.max(a, b), 0) + 2;
- if (i > 0) $(`.pu3line${i}s`).remove()
- var ele = $(`<span id="wcspu3${id}" class="ignoreMe wcspu3${alignY} pu3line${i}s" style="all:initial; max-width:33%; max-height:100vh; overflow-y:auto; scrollbar-width:thin; font-family:sans-serif; position: fixed; right:0em; ${ alignY }:${((maey) + i * 18)}px; z-index:2147483647; opacity:1; font-size:15px; margin:0px 1px; text-decoration:none !important; padding:1px 6px 1px 6px; word-break: break-all !important; border-radius:12px; background-color:#6080ff; color:white; ">${ text }</span>`).appendTo('body');
- let ey = ele[0]?.getBoundingClientRect()?.height
- // if (ele[0].getBoundingClientRect().bottom >= (window.innerHeight)) {
- if (ele[0].getBoundingClientRect().bottom >= (window.innerHeight)) {
- elegeta('.wcspu3top').forEach(e => { e.style.top = parseFloat(e?.style?.top) - (ey) - 2 + "px" })
- }
- if (typeof text == "string") { maey += (text.match(/<br>/gmi) || []).length || 0; } //console.log((text.match(/<br>/gmi) || [] ).length) }
- setTimeout(() => {
- eleget0('//span[@id="wcspu3' + id + '"]')?.remove();
- }, timer);
- }
- var maet;
-
- function popup2(text, i = 0, style = "", position = "bottom") {
- if (!ENABLE_HELP_CONCLUSION) return;
- text = String(text).replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/`/g, '`').replace(/</g, "<").replace(/>/g, ">").replace(/\n/gm, "<br>")
- var mae = eleget0('//span[@id="yhmbox"]');
- if (maet && mae) {
- mae.remove();
- clearTimeout(maet);
- }
- let bgcol = (pref("translucent") != "on") ? "#6080ff" : "#909090";
- var ele = $(`<span id="yhmbox" class="ignoreMe" style="all:initial; max-height:100vh; overflow-y:auto; scrollbar-width:thin; font-family:sans-serif; cursor:pointer; position: fixed; right:0em; ${position}:${(i * 2 + 2) }em; z-index:2147483647; opacity:1; font-size:15px; margin:0px 1px; text-decoration:none !important; padding:1px 6px 1px 6px; word-break: break-all !important; border-radius:12px; background-color:${bgcol}; color:white; ${style}">${text}</span>`).appendTo('body');
- maet = setTimeout(function() {
- var mae = eleget0('//span[@id="yhmbox"]');
- if (mae) { mae.remove(); }
- }, 5000);
- $(ele).attr("title", "クリックでこのガイドを一時的に消す").click(function() {
- $(this).fadeOut(200).queue(function() {
- $(this).remove();
- clearTimeout(maet);
- })
- });
- }
-
- function prefChanged(id) { // prefのkeyをキャッシュと見比べて変化したか?他タブで変更されていることを想定している
- let cache = prefCache[id] || null
- let present = pref(id) || null
- if (typeof cache === "object") cache = JS(cache)
- if (typeof present === "object") present = JS(present)
- return cache !== present
- //return JS(prefCache[key] || []) !== JS(pref(key) || [])
- }
-
- function prefCacheEqual(id) {
- return JS(prefCache[id] || []) === JS(pref(id) || [])
- }
-
- function prefCacheClear() { prefCache = [] }
-
- function pref(name, store = null) { // prefs(name,data)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)、prefs(name)で読み出し
- if (store === null) { // 読み出し
- let data = GM_getValue(name) || GM_getValue(name);
- if (data == undefined) return null; // 値がない
- if (data.substring(0, 1) === "[" && data.substring(data.length - 1) === "]") { // 配列なのでJSONで返す
- // try { return JSON.parse(data || '[]'); } catch (e) {
- try {
- let a = JSON.parse(data || '[]');
- prefCache[name] = a;
- return a
- } catch (e) {
- alert("データベースがバグってるのでクリアします\n" + e);
- pref(name, []);
- prefCache[name] = []
- return;
- }
- // } else return data;
- } else {
- prefCache[name] = data;
- return data;
- }
- }
- if (store === "" || (Array.isArray(store) && store?.length == 0)) { // 書き込み、削除
- GM_deleteValue(name);
- prefCache[name] = store;
- return;
- } else if (typeof store === "string") { // 書き込み、文字列
- GM_setValue(name, store);
- prefCache[name] = store
- return store;
- } else { // 書き込み、配列
- // try { GM_setValue(name, JSON.stringify(store)); } catch (e) {
- try {
- let a = JSON.stringify(store);
- GM_setValue(name, a);
- prefCache[name] = a
- } catch (e) {
- alert("データベースがバグってるのでクリアします\n" + e);
- pref(name, "");
- }
- return store;
- }
- }
-
- function prefRestrict(name, type) {
- let data = pref(name);
- if (!data) return data;
- if (type === "array") {
- if (typeof data === "object") {
- // alert("correct");
- return data;
- } else {
- alert("データベースの形式に誤りがある(配列/オブジェクトでない)ためクリアします\n");
- pref(name, "");
- return [];
- }
- }
- return data;
- }
-
- function prefl(name, store = undefined, logLen = 50) { // prefl(name,data,len)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)・"name+Log"にlen個の履歴保存、prefl(name)で読み出し
- if (store === undefined) { // 読み出し
- return pref(name);
- } else { // 書き込み、削除
- if (store) {
- var a = pref(name + "Log") || [];
- a.unshift(store);
- a = [...new Set(a)];
- pref(name + "Log", a.slice(0, logLen));
- }
- return pref(name, store);
- }
- }
-
- function debugEle(ele, command = "") {
- if (!ele) return
- if (command.indexOf("remove") !== -1) {
- ele.style.outline = "";
- ele.style.boxShadow = "";
- return;
- }
- if (ENABLE_HELP_CONCLUSION && (debug || command.indexOf("force") !== -1)) {
- var col = getColorFromText(ele.innerText);
- if (command.indexOf("random") !== -1) col = '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6);
- ele.style.outline = "3px dotted " + col;
- ele.style.boxShadow = " 0px 0px 4px 4px " + col + "30, inset 0 0 100px " + col + "20";
- // ele.title='\n@class="'+ele.className+'"\n@id="'+ele.id+'"';
- if (command.indexOf("autoRemove") !== -1) {
- setTimeout(() => {
- ele.style.outline = "";
- ele.style.boxShadow = "";
- }, 60000)
- }
- }
- }
-
- function getColorFromText(str) {
- if (!str) return "#808080"
- var col = 0;
- for (letter of str) { col = (col + str.charCodeAt(letter) ** 3); }
- return '#' + (0x1000000 + col % 0xffffff).toString(16).substr(1, 6);
- }
-
- function advertiseEle(ele, force = "") {
- if (debug || force == "force") {
- if (ele) ele.style.outline = "4px dotted red";
- }
- }
-
- function sw(job, mode = "dc") {
- // if (ENABLE_MEASURE_TIME_SPENT == 0) return;
- if (debug < 2 && !ENABLE_MEASURE_TIME_SPENT) return;
- if (job !== "reset") {
- if (mode === "dc")
- debug && dc(job + " : " + ((new Date().getTime()) - (swb.getTime())) + " ms");
- if (mode === "notify") notifyMe(job + " : " + ((new Date().getTime()) - (swb.getTime())) + " ms");
- }
- if (job !== "reset")
- swb = new Date();
- }
-
- function isSeller() {
- return location.href.match(/\/seller\//);
- }
-
- function proInput(prom, defaultval, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) {
- let r = window.prompt(prom, defaultval)
- if (r === null) return null
- return Math.min(Math.max(
- Number(r.replace(/[A-Za-z0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248); }).replace(/[^-^0-9^\.]/g, "")), min), max);
- }
-
- // function notifyMe(body, title = "", clickfunc = null, img = null,requireInteraction=false) {
-
- function notifyMe(body, title = "", clickfunc = null, img = null, command = false) {
- if (!("Notification" in window)) return;
- else if (Notification.permission == "granted") {
- var notify = img ? new Notification(title, { body: body, icon: img, requireInteraction: command }) : new Notification(title, { body: body, requireInteraction: command });
- if (clickfunc) {
- notify.onclick = clickfunc
- }
- } else if (Notification.permission !== "denied") Notification.requestPermission().then(function(permission) {
- if (permission === "granted") new Notification(title, { body: body });
- });
- }
-
- function setupbutton(id, title, func, tips, command) {
- $(`<span id='${id}' class='ignoreMe' title='${tips}' style='cursor:pointer; color:#505050; font-size:15px; background:#ffffffc0; padding:3px; border-radius:9px;border:#505050 1px solid; position:fixed; bottom:3em; right: 1em;'>${title}</span>`).appendTo(document.body).click(function() { func(); if (/removeWhenClicked/.test(command)) { $(this).remove(); } });
- }
-
- // eleはスクロール画面内に入ってる?
- function isinscreen(ele, evencorner = 0, borderHeight = 0) {
- if (!ele) return;
- var eler = ele.getBoundingClientRect();
- if (evencorner) return (eler.top > 0 - eler.height - borderHeight && eler.left > 0 && eler.left < document.documentElement.clientWidth && eler.top < Math.min(window.innerHeight, document.documentElement.clientHeight) + borderHeight);
- else return (eler.top > 0 - 0 && eler.left > 0 && eler.left + eler.width < document.documentElement.clientWidth && eler.top + eler.height < Math.min(window.innerHeight, document.documentElement.clientHeight) + 0);
- }
-
- function autoPagerized(callback, command) { // 複数回呼んではいけない
- if (command !== "not1st") callback(document.body)
- document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) { callback(evt.target); }, false);
- // document.body.addEventListener('2chanReloaded', function() { setTimeout(() => { callback() }, 1) }, false);
- if (lh(".2chan.")) document.body.addEventListener('2chanReloaded', function() {
- setTimeout(() => {
- GF.fromSecond = 1;
- callback()
- }, 1)
- }, false);
- }
-
- function autoPagerizedD(id, callback, command) { // 複数回呼んで良い、連続で呼んだ時は収まるまで遅延する
- if (command !== "not1st") callback(document.body)
- if (!GF?.[id]) {
- document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) {
- clearTimeout(GF?.apdTO)
- GF.apdTO = setTimeout(callback, 500)
- }, false);
- GF[id] = 1;
- }
- }
-
- function searchWithHistory(id, sitename, url, orSeparator = "|") {
- var selection = null;
- url = [url].flat()
- let prev = pref(id + " : searchWithHistory")
- if (orSeparator) {
- let query = prompt(`${sitename}で全体検索します\n|でOR\n\n履歴(${id}):\n${ (pref(id + " : searchWithHistoryLog") || []).slice(0, 50).join("\n") }\n\n` + url.map(v => v.replace(/\*\*\*/, "${キーワード}")).join("\n") + '\nを開きます\n\n', selection || (prev ? prev + "|" : ""))
- if (query) {
- query = Array.from(new Set(query.replace(/\|/g, "|").replace(/|+/gmi, "|").split("|"))).join("|").replace(/^[|\|]+|[|\|]+$/gmi, "").trim() // 重複自動削除
- if (!selection) prefl(id + " : searchWithHistory", query.replace(/\|/g, "|"))
- url.forEach((v, i) => {
- setTimeout(() => { GM.openInTab(`${v.replace(/\*\*\*/,encodeURI(query.replace(/|/g,orSeparator)))}`); }, i * 333)
- })
- }
- } else {
- let query = prompt(`${sitename}で全体検索します\n\n履歴(${id}):\n${ (pref(id + " : searchWithHistoryLog") || []).slice(0, 50).join("\n") }\n\n` + url.map(v => v.replace(/\*\*\*/, "${キーワード}")).join("\n") + '\nを開きます\n\n', selection || prev || "")
- if (query) {
- if (!selection) prefl(id + " : searchWithHistory", query?.trim())
- url.forEach((v, i) => {
- setTimeout(() => { GM.openInTab(`${v.replace(/\*\*\*/,encodeURI(query?.trim()))}`); }, i * 333)
- })
- }
- }
- return false;
- }
-
- function sec2hms(s) {
- return new Date(s * 1000).toISOString().substr(11, 8).replace(/^00\:0|^00\:/, "");
- }
-
- function hms2sec(s) {
- return ((s.match0(/^(\d+):\d+:\d+$/) || 0) * 60 * 60) + ((s.match0(/^\d+:(\d+):\d+$/) || 0) * 60) + ((s.match0(/^(\d+):\d+$/) || 0) * 60) + ((s.match0(/^\d+:\d+:(\d+)$/) || 0) * 1) + ((s.match0(/^\d+:(\d+)$/) || 0) * 1);
- }
-
- // function chapterMemo(requireUrlRE, videoTitleXP, newUrl, copy = 0) {
- function chapterMemo(requireUrlRE, videoTitleXP, newUrl, copy = 0) {
- if (!location.href.match0(requireUrlRE)) return
- var videoEle = eleget0('//video');
- if (!videoEle) { return; } else { var currentTime = sec2hms(Math.floor(videoEle.currentTime)); }
- if (typeof videoTitleXP == "string") {
- var videoTitleEle = eleget0(videoTitleXP);
- if (!videoTitleEle) return;
- var videoTitle = videoTitleEle.textContent;
- } else { var videoTitle = videoTitleXP(); if (!videoTitle) return false; } //eleget0(videoTitleXP);
-
- var curMemos = pref(SITE.id + ' : SearchMyMemo') || [];
- var chaMemos = curMemos.filter(e => (e.t == videoTitle && e.c == COLORVIDEOTIME)).sort((a, b) => hms2sec(a.m.match0(/^([\d:]+)\s/)) > hms2sec(b.m.match0(/^([\d:]+)\s/)) ? 1 : -1);
- var chaMemoTU = "";
- //chaMemos.forEach(c => { chaMemoTU += `${videoTitle} ${c.m}\n${newUrl.replace(/\*\*time\*\*/,hms2sec(c.m.match0(/^([\d:]+)\s/)))}\n` })
- chaMemos.forEach(c => { chaMemoTU += `${videoTitle} - YouTube ▶ ${c.m}\n${newUrl.replace(/\*\*time\*\*/,hms2sec(c.m.match0(/^([\d:]+)\s/)))}\n` })
- if (!copy) {
- var jumpUrl = location.href.match0(/https:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9_\-]{11})/);
- if (jumpUrl) jumpUrl = `https://youtu.be/${jumpUrl}&t=${Math.floor(videoEle.currentTime)}`;
-
- var word = window.getSelection().toString().trim() || (prompt(`『${videoTitle}』\n${currentTime=="0:00"?"に付ける":"の "+currentTime+" に付けるチャプター"}メモを入力してください\n${chaMemoTU?"\n\n列挙(Shift+Uでコピー):\n"+chaMemoTU:""}\n`) || "").trim();
- if (!word) return;
- storeMemo(videoTitle, (currentTime != "0:00" ? currentTime + " " : "") + word.trim(), currentTime == "0:00" ? COLOR1 : COLORVIDEOTIME, document, jumpUrl || "")
- } else {
- GM.setClipboard(chaMemoTU)
- popup2(chaMemoTU, -1, "", "top")
- //var newstr = (pref(SITE.id + ' : SearchMyMemo') || []).filter(e => (e.c === COLORVIDEOTIME));
- //prompt(`チャプターメモから再生するURLの列挙をコピーしました\n\n入力フォームよりチャプターメモのエクスポートとマージが行えます\nコピーしてテキストファイル等に保存すればエクスポートとなり、他環境からエクスポートしたものを入力すればマージになります\n変更せずにEnterかEscを押せば何もしません\n\n${JSON.stringify(newstr)}`, JSON.stringify(newstr))
- }
- }
-
- // intervalが1以上かつ設定値がdefValueと違っていればintervalミリ秒事に再処理、そうでなければ割り込みはせず、初回の実行もしない
- function setSlider(placeEle, min = 0, max = 100, defValue = 0, title = "", key = "SliderValue", onchangecallback, interval = 0, addProperty = "") { // interval:1なら初回一度だけcallbackも実行、2~ならそのms間隔で定期実行
- if (placeEle && !eleget0(`//input[@id="setSlider${key}"]`)) {
- let val = pref(key) || defValue;
- placeEle.insertAdjacentHTML("afterend", `<input type="range" class="setSlider" id="setSlider${key}" min="${min}" max="${max}" value="${val}" ${addProperty} title="${title.replace("***",val)}\n右クリック:デフォルトに戻す" oninput="this.title='${title}\\n右クリック:デフォルトに戻す'.replace('***',this.value);" oncontextmenu="this.value='${defValue}'; this.dispatchEvent(new Event('input')); return false;">`)
-
- let adjustFunc = function(key, interval = 0, defValue = 0, onchange = 0) {
- //popup2(`${interval} ${onchange}`)
- let sliderEle = eleget0(`#setSlider${key}`)
- let sliderEleNum = Number(sliderEle.value)
- onchangecallback(sliderEleNum)
- if (onchange) pref(key, sliderEleNum)
- if (interval && sliderEleNum != defValue) setTimeout(() => { adjustFunc(key, interval, defValue) }, interval)
- // if (interval>0 && sliderEleNum != defValue) setTimeout(() => { adjustFunc(key, interval, defValue) }, interval)
- }
- let sliderEle = eleget0(`#setSlider${key}`)
- if (sliderEle) {
- sliderEle.addEventListener('input', () => adjustFunc(key, interval, defValue, 1));
- if (Number(sliderEle.value) != defValue) adjustFunc(key, interval, defValue)
- }
- //if (interval == 1) adjustFunc(key, 0, defValue)
- if (interval == 1) onchangecallback(Number(eleget0(`#setSlider${key}`)?.value || defValue))
- }
- }
-
- function domsort(container, doms, func, prepend = 0) { // container:domsの入っている大枠、省略時はdomsの1つ親 doms:並べ替える要素たち prepend:0:containerの最後に付ける 1:最初に付ける(逆順) 2:最後につける(逆順)(0or2) 3:最初に付ける(昇順) // 1と3のほうが継ぎ足し位置マーカーが上に来ないので多分良い
- if (container === "") container = doms[0]?.parentNode
- if (!container || !doms.length) return
- if (Array.isArray(container)) container = container.shift()
- let col = new Intl.Collator("ja", { numeric: true, sensitivity: 'base' })
- if (prepend == 2 || prepend == 3) doms.map(function(v, i) { return { dom: v, value: func(v, i) } }).sort(function(b, a) { return (!isNaN(b.value) && !isNaN(a.value) ? b.value == a.value ? 0 : (b.value - a.value) : b.value == a.value ? 0 : (col.compare(a.value, b.value))) }).forEach(function(v) { prepend == 3 ? container?.prepend(v.dom) : container?.appendChild(v.dom) })
- if (prepend == 1 || prepend == 0) doms.map(function(v, i) { return { dom: v, value: func(v, i) } }).sort(function(a, b) { return (!isNaN(b.value) && !isNaN(a.value) ? b.value == a.value ? 0 : (b.value - a.value) : b.value == a.value ? 0 : (col.compare(a.value, b.value))) }).forEach(function(v) { prepend ? container?.prepend(v.dom) : container?.appendChild(v.dom) })
- }
-
- function sortdom(doms, func, prepend = 0) { // doms:並べ替える要素たち prepend:0:昇順 1:降順
- let position = doms[0]?.previousElementSibling
- let container = doms[0]?.parentNode
- if (!container || !doms.length) return
- let col = new Intl.Collator("ja", { numeric: true, sensitivity: 'base' })
- let fragment = new DocumentFragment();
- doms.map((v, i) => { return { dom: v, value: func(v, i) } }).sort((a, b) => (prepend == 0 ?
- (!isNaN(b.value) && !isNaN(b.value) ? a.value == b.value ? 0 : (a.value - b.value) : a.value == b.value ? 0 : (col.compare(a.value, b.value))) :
- (!isNaN(a.value) && !isNaN(b.value) ? a.value == b.value ? 0 : (b.value - a.value) : a.value == b.value ? 0 : (col.compare(b.value, a.value)))
- )).forEach(v => fragment?.append(v.dom))
- position ? position.parentNode.insertBefore(fragment, position.nextSibling) : container.prepend(fragment)
- }
-
- function before(e, html) { e?.insertAdjacentHTML('beforebegin', html); return e?.previousElementSibling; }
-
- function begin(e, html) { e?.insertAdjacentHTML('afterbegin', html); return e?.firstChild; }
-
- function end(e, html) { e?.insertAdjacentHTML('beforeend', html); return e?.lastChild; }
-
- function after(e, html) { e?.insertAdjacentHTML('afterend', html); return e?.nextElementSibling; }
-
- function ct1(callback, name = "test", time = 10) {
- console.time(name);
- callback();
- console.timeEnd(name)
- } // 速度測定(1回だけ)
- function ctLong(callback, name = "test", time = 10) { console.time(name); for (let i = time; i--;) { callback() } console.timeEnd(name) } // 速度測定(もともと長くかかるもの)
- function ct(callback, name = "test", time = 10) { let i = 0; let st = Date.now(); while (Date.now() - st < 1000) { i++, callback() } console.log(`${name} ${i} / 1sec`) } // 速度測定(一瞬で終わるもの)
- function lh(re) { let tmp = location.href.match(re); if (!tmp) { return null } else if (tmp.length > 1) { return tmp[1] } else return tmp[0] } // gフラグ不可
- function ld(re) { let tmp = location.hostname.match(re); if (!tmp) { return null } else if (tmp.length > 1) { return tmp[1] } else return tmp[0] } // gフラグ不可
- function JS(v) { try { return JSON.stringify(v) } catch { return null } }
-
- function JP(v) { try { return JSON.parse(v) } catch { return null } }
-
- function e2sel(ele) { return `${ele.tagName?.toLowerCase()}${ele.id?"#"+ele.id:""}${ele.className?"."+ele.className.replace(/\s/g,"."):""}` }
-
- function han(str) { return str?.replace(/[A-Za-z0-9]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248) }) || "" }
-
- function sani(s) { return s?.replace(/&/g, "&")?.replace(/"/g, """)?.replace(/'/g, "'")?.replace(/`/g, '`')?.replace(/</g, "<")?.replace(/>/g, ">") || "" }
-
- function gettime(_fmt = 'YYYY/MM/DD hh:mm:ss.iii', _dt = new Date()) {
- return [
- ['YYYY', _dt.getFullYear()],
- ['MM', _dt.getMonth() + 1],
- ['DD', _dt.getDate()],
- ['hh', _dt.getHours()],
- ['mm', _dt.getMinutes()],
- ['ss', _dt.getSeconds()],
- ['iii', _dt.getMilliseconds()],
- ].reduce((s, a) => s.replace(a[0], `${a[1]}`.padStart(a[0].length, '0')), _fmt)
- }
-
- function isValidRE(str) {
- try { new RegExp(str) } catch (e) { return false }
- return true
- }
-
- function matchGG(str, re) {
- return str?.match(new RegExp(re, "gm"))?.map(v => v?.match(new RegExp(re, "m"))?.[1])
- }
-
- // element.dataset.gmDataListプロパティにclassList.add/removeのような命令セット
- function gmDataList_add(ele, name) {
- let data = ele?.dataset?.gmDataList?.split(" ") || []
- if (!data.includes(name)) {
- data.push(name);
- ele.dataset.gmDataList = data.join(" ")
- }
- }
-
- function gmDataList_remove(ele, name) {
- let data = ele?.dataset?.gmDataList?.split(" ") || []
- if (data.includes(name)) {
- data = data.filter(v => v !== name)
- if (data.length) ele.dataset.gmDataList = data.join(" ");
- else delete ele.dataset.gmDataList;
- }
- }
-
- function gmDataList_includesPartial(ele, name) {
- let data = ele?.dataset?.gmDataList?.split(" ") || []
- return data.find(v => v.includes(name))
- }
-
- function sound(type, sec, freq = 440) { // type:sine, square, sawtooth, triangleがある
- let ctx = new AudioContext();
- let osc = ctx.createOscillator();
- osc.type = type;
- osc.frequency.setValueAtTime(freq, ctx.currentTime); // 440HzはA4(4番目のラ)
- osc.connect(ctx.destination);
- osc.start();
- osc.stop(sec);
- }
-
- function clientHeight() { return Math.min(document.documentElement.clientHeight, window.innerHeight) }
-
- function clientWidth() { return document.documentElement.clientWidth }
-
- function cldtd(title) { debug && console.log(title + " : " + (new Date()).toLocaleString("ja-JP", { timeZone: "Asia/Tokyo" })) } // console.log date time
- function cldt(title) { debug && console.log(title + " : " + gettime()) } // console.log date time
-
- function getDefault56memo() {
- var date = new Date();
- // return date.getFullYear() + "." + ("0" + (date.getMonth() + 1)).slice(-2) + "." + ("0" + date.getDate()).slice(-2) + " (" + ["日", "月", "火", "水", "木", "金", "土"][date.getDay()] + ")"
- //return `${date.getFullYear()}.${("0" + (date.getMonth() + 1)).slice(-2)}.${("0" + date.getDate()).slice(-2)} (${["日", "月", "火", "水", "木", "金", "土"][date.getDay()]})`
- return `${date.getFullYear()}.${("0" + (date.getMonth() + 1)).slice(-2)}.${("0" + date.getDate()).slice(-2)}`
- }
-
- function img2dhash(img) {
- if (!img || !img.complete || !img.naturalWidth || !img.naturalHeight) return null;
- var canvas = document.createElement("canvas");
- canvas.width = 8;
- canvas.height = 7;
- var context = canvas.getContext("2d", { alpha: false });
- try {
- context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, canvas.width, canvas.height);
- } catch (e) {
- return null;
- }
- var pixels = context.getImageData(0, 0, canvas.width, canvas.height);
- var gray = [...Array(pixels.width * pixels.height)].map((v, i) => pixels.data[i * 4] + pixels.data[i * 4 + 1] + pixels.data[i * 4 + 2])
- var dHash = gray.reduce((a, v, i) => ((i + 1) % canvas.width !== 0) ? (v < gray[i + 1] ? "1" : "0") + a : a, "");
- return parseInt(dHash, 2).toString(16);
- }
-
- function keyFuncAdd(keyarr) {
- if (!GF?.keyFuncC) {
- document.addEventListener('keydown', e => {
- if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable || ((e.target.closest('#chat-messages,ytd-comments-header-renderer') || document.activeElement.closest('#chat-messages,ytd-comments-header-renderer')))) return;
- var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
- let f = GF?.keyFuncC?.find(v => v.key == key)
- if (f) f.func();
- })
- }
- keyarr.forEach(v => {
- if (!GF?.keyFuncC?.includes(v)) GF.keyFuncC = GF?.keyFuncC ? GF.keyFuncC.push(v) : [v];
- })
- }
-
- function minmax(v, min, max) {
- return Math.min(Math.max(v, min), max)
- }
-
- function dragElement(ele, handleSel = "*", cancelSel = "") {
- let x, y;
- (handleSel == "*" ? [ele] : elegeta(handleSel, ele)).forEach(e => e.onmousedown = dragMouseDown)
-
- function dragMouseDown(e) {
- if (e.target.closest(cancelSel) || e.button != 0) return;
- e = e || window.event;
- e.preventDefault();
- ele.style.minWidth = `${$(ele).width()}px`;
- [x, y] = [e.clientX, e.clientY];
- document.onmouseup = closeDragElement;
- document.onmousemove = elementDrag;
- }
-
- function elementDrag(e) {
- e = e || window.event;
- e.preventDefault();
-
- if (ele.style.right) { // right:かbottom:で張り付いてるものなら剥がしてleft/topにする
- ele.style.left = `${ele.offsetLeft}px`
- ele.style.right = ""
- }
- if (ele.style.bottom) { // right:かbottom:で張り付いてるものなら剥がしてleft/topにする
- ele.style.top = `${ele.offsetTop}px`
- ele.style.bottom = ""
- }
-
- ele.style.top = `${(ele.offsetTop - (y - e.clientY))}px`;
- ele.style.left = `${(ele.offsetLeft - (x - e.clientX))}px`;
- [x, y] = [e.clientX, e.clientY];
- }
-
- function closeDragElement() {
- document.onmouseup = null;
- document.onmousemove = null;
- }
- }
-
- function waitdo(checkFunc, func, timeout = 3000, start = Date.now()) { // checkFuncがtrueになったらfuncを実行
- let ret = checkFunc();
- if (ret || ret?.length > 0) { func(ret) } else if (Date.now() - start < timeout) { setTimeout(waitdo, 111, checkFunc, func, timeout, start) }
- }
-
- function nfd(str) { return str?.normalize("NFD") || "" }
-
- function hoverHelp(cb) {
- let latest, helpEle;
- SITE.preventHelpFunc = () => 1,
- document.addEventListener("mousemove", e => {
- if (latest != e?.target) {
- helpEle?.remove()
- let text = cb(e.target)
- if (text) helpEle = end(document.body, `<div id="hoverHelpPopup" style="z-index:999999999; bottom:1em; right:1em; position:fixed; background-color:#ffffffe0; padding:1px 0.5em; border:1px solid #505050; font-size:15px; color:#505050; border-radius:0.75em;">${text}</div>`)
- latest = e.target
- if (document.elementFromPoint(e.clientX, e.clientY) == helpEle) {
- helpEle.style.bottom = "";
- helpEle.style.top = "1em";
- }
- }
- })
- }
-
- })();