// ==UserScript== // @name web漫画にショートカットキーを追加 // @description ←→:前/次のページ S:スクロール速度変更 A:頭出しオンオフ f [:全画面化 Shift+←→か ] Enter:前の話/次の話に移動 Shift+↑:作品情報ページに戻る (ニコニコ静画のみ)C:コメントオンオフ H:ヘッダ固定追従変更 (作品情報ページで)→:第1話に移動、Enter:最新話に移動、Shift+↑:パンくずリスト1つ上に移動 Shift+@:インスタントsibling登録 // @version 0.1.12 // @run-at document-idle // @match *://*.5ch.net/* // @match *://bokete.jp/* // @match *://cakes.mu/* // @match *://cho-animedia.jp/comic_category/* // @match *://cho-animedia.jp/comic/* // @match *://ci.nii.ac.jp/* // @match *://comic-days.com/episode/* // @match *://tonarinoyj.jp/episode/* // @match *://shonenjumpplus.com/episode/* // @match *://kuragebunch.com/episode/* // @match *://pocket.shonenmagazine.com/episode/* // @match *://viewer.heros-web.com/episode/* // @match *://comic-fuz.com/* // @match *://comic-meteor.jp/* // @match *://comic-trail.jp/* // @match *://comic-walker.com/* // @match *://comic.mag-garden.co.jp/* // @match *://comic.pixiv.net/works/* // @match *://comic.webnewtype.com/contents/* // @match *://comicawa.com/TitleDetail/* // @match *://comicpash.jp/* // @match *://cycomi.com/fw/cycomibrowser/chapter/* // @match *://daysneo.com/works/* // @match *://ebookjapan.yahoo.co.jp/* // @match *://gammaplus.takeshobo.co.jp/* // @match *://ganma.jp/* // @match *://hanatsubaki.shiseidogroup.jp/comic* // @match *://kawaii2ch.com/* // @match *://leedcafe.com/* // @match *://manga-park.com/title/* // @match *://manga.line.me/indies/product/detail* // @match *://mangacross.jp/comics/* // @match *://mangahack.com/comics/* // @match *://matogrosso.jp/* // @match *://news.mynavi.jp/series/* // @match *://news.mynavi.jp/article/* // @match *://note.mu/* // @match *://online.ichijinsha.co.jp/* // @match *://rookie.shonenjump.com/series/* // @match *://rookie.shonenjump.com/users/* // @match *://ruijianime.com/* // @match *://sai-zen-sen.jp/comics/twi4/* // @match *://seiga.nicovideo.jp/watch/* // @match *://seiga.nicovideo.jp/comic/* // @match *://souffle.life/author/* // @match *://souffle.life/manga/* // @match *://storia.takeshobo.co.jp/manga/* // @match *://sukupara.jp/* // @match *://to-ti.in/* // @match *://twitter.com/* // @match *://urasunday.com/* // @match *://watamote.com/* // @match *://web-ace.jp/youngaceup/* // @match *://webcomicgamma.takeshobo.co.jp/* // @match *://webcomics.jp/* // @match *://www.alphapolis.co.jp/manga/* // @match *://www.comic-earthstar.jp/* // @match *://www.comic-essay.com/episode/* // @match *://www.comic-essay.com/neko/* // @match *://www.comicbunch.com/manga/* // @match *://www.comico.jp/challenge/* // @match *://www.comico.jp/articleList* // @match *://www.comico.jp/detail* // @match *://www.ebigcomic4.jp/title/* // @match *://www.ganganonline.com/* // @match *://www.jstage.jst.go.jp/* // @match *://www.mangabox.me/reader/* // @match *://www.moae.jp/comic/* // @match *://*.moae.jp/lineup/* // @match *://www.nicovideo.jp/search/* // @match *://www.sunday-webry.com/detail* // @match *://www.tatan.jp/* // @match *://www.zenyon.jp/lib/* // @match *://yawaspi.com/* // @match *://yomitai.jp/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @require https://code.jquery.com/jquery-3.3.1.min.js // @namespace https://greasyfork.org/users/181558 // @downloadURL none // ==/UserScript== // @match *://*/* (function() { const PopupHelpMS = 4000; // ポップアップの表示時間 const GenerateMatch = 0; // 1でメタデータブロックを生成(開発用) const debug = 0; // verbose console.log const ButtonBG = "background-color:#3050f0;"; const SITEINFO = [{ // ツイ4 url: '//sai-zen-sen.jp/comics/twi4/', sibling: '//article', // header: '//body/header/div[1]', atamadashi: '//article[last()]', author: '//h3[1]/span[@class="work-author"]' }, { // 花椿 url: '//hanatsubaki.shiseidogroup.jp/comic', sibling: '//div/figure/img/../../../../../../../..', //'|//section/div', header: '//div[@class="controller"]/div[1]', author: '//div[@class="row text-center"]/div[@class="col col-8 col-sm-12 person"]/div[@class="grid"]/div[@class="row text-left"]/div[last()]/h4[1]' }, { // web漫画アンテナ url: '//webcomics.jp/', sibling: '//div[@class="entry"]', header: '//div[@id="header"]', disableSnapWhenPageIsClicked: 1, author: '' }, { // bokete url: '//bokete.jp/', sibling: '//div/div/div[@class="boke"]', header: '//div/div[@id="top-bar"]', disableSnapWhenPageIsClicked: 1, author: '' }, { // url: '//ruijianime.com/', sibling: '//div[@class="sm_one_tag_search recent_tag"]|//div[@class="sm_one"]', header: '', disableSnapWhenPageIsClicked: 1, author: '' }, { // コミックぜにょん url: '//www.zenyon.jp/lib/', sibling: '//div[@id="viewer_content"]/img', header: '', nextEpisode: '//a/img[@class="btn_next"]/..', author: '//p[@class="author"]', firstEpisode: '//div/ul[@id="sakuhin_backnumber_ul"]/li[last()]/a[text()="1"]', lastEpisode: '//p[@class="sakuhin_btn_new"]/a/img/..', pankuzuUp: '//a/img[@alt="作品ページへ" and @class="btn_sakuhin"]/..', }, { // url: '//souffle.life/manga/', sibling: '//div[@class="sf-content_img"]/img', header: '//div[@id="sf-scroll_header"]', nextEpisode: '//span[@class="sf-next_btn"]/a', prevEpisode: '//span[@class="sf-before_btn"]/a', firstEpisode: '//section[1]/div[@class="sf-content sf-authors"]/section[@class="sf-content_books_related"]/div/article[3]/div/div[@class="sf-contents_book_read"]/a', ////article[last()]/div/div[@class="sf-contents_book_read"]/a', lastEpisode: '//div[@class="alm-reveal"]/article[1]/div[@class="sf-content_book_description"]/div/a', pankuzuUp: '//p[@class="sf-content_book_name"]/a', author: '//span[@class="sf-author_name"]', }, { // url: '//souffle.life/author/', firstEpisode: '//section[1]/div[@class="sf-content sf-authors"]/section[@class="sf-content_books_related"]/div/article[3]/div/div[@class="sf-contents_book_read"]/a', ////article[last()]/div/div[@class="sf-contents_book_read"]/a', lastEpisode: '//div[@class="alm-reveal"]/article[1]/div[@class="sf-content_book_description"]/div/a', author: '//span[@class="sf-author_name"]', }, { // url: '//www.moae.jp/comic/|.moae.jp/lineup/', sibling: '//div[@class="img"]/a/img/../..', header: '', lastEpisode: '//ul[@class="detail-trial"]/li[1]/a', author: '//section/section[@class="mod-profile-block"]/dl/dt', pankuzuUp: '//li[@class="lineup"]/a/img' }, { // コミックエッセイ劇場 url: '//www.comic-essay.com/episode/', sibling: '//div[@class="manga-imgs"]/img', header: '', prevEpisode: '//ul/li[@class="prev"]/a', nextEpisode: '//li[@class="next"]/a', firstEpisode: '//div[@class="cell a_t"]/p[@class="ro_t abg_text"]', lastEpisode: '//a[@class="ro"]/p[last()]', author: '//p[@class="author"]|//a/span[@class="name"]', pankuzuUp: '//ul[@class="breadcrumb wrap c-fix"]/li[last()-1]/a' }, { // url: '//www.comic-essay.com/neko/', sibling: '//article/div[@class="scene"]/img', header: '//body/div[@id="pagetop"]/header', nextEpisode: '//div[2]/ul/li[last()]/a[text()="次の話"]', prevEpisode: '//div[@class="pagenation pc"]/ul/li/a[contains(text(),"前の話")]', disableSnapWhenPageIsClicked: 1, author: '//div[@class="txtarea"]/h4[@class="ttl-name"]', firstEpisode: '//li[1]/a[@class="btn-episode"]/p/..', lastEpisode: '//div[@class="episode-new"]/a/p|//li[last()]/a[@class="btn-episode"]/p/..', pankuzuUp: '//div[@id="pagetop"]/ul/li[last()-1]/a', }, { // 裏サンデー url: '//urasunday.com/', sibling: '//img[@class="dumimg"]/..', header: '', // nextEpisode: '//div[@id="prBanner"]/a[contains(text(),"次の話を今すぐ読む!! →")]', firstEpisode: '//div[@class="comicInner"]/ul[2]/li[1]/a', lastEpisode: '//div[@class="comicButtonDateBox"]/a', author: '//li[@class="detailComicTitle"]/h2|//div[@id="comicDetail"]/h2', pankuzuUp: '//li/a[@href="../index.html"]' }, { // やわらかスピリッツ url: '//yawaspi.com/', sibling: '//section[@class="comicContainer"]/a/img[1]/..', header: '', nextEpisode: '', firstEpisode: '//section[@class="page__detail"]/div[@class="page__detail__inner"]/div[@class="detail__image"]/span|//ul[@class="inner__content"]/li[last()]/a/dl/dt', lastEpisode: '//ul[@class="inner__content"]/li/a/dl/dt|//li[@class="-new"]/a/dl/dt', disableSnapWhenPageIsClicked: 0, author: '//li[@class="comicDetails"]/hgroup[1]/h2', pankuzuUp: '//li[@class="browserCtrlLeft"]/a' }, { // コミックバンチ url: '//www.comicbunch.com/manga/', sibling: '//div[@class="view"]/a/img/..|.//span[@class="guard_np"]/../..', header: '', nextEpisode: '//ul[@class="btn cf"]/li/a[text()="次の話"]', prevEpisode: '//ul[@class="btn cf"]/li/a[text()="前の話"]', firstEpisode: '//div[@class="backnumber cf"]/ul/li[last()]/a', lastEpisode: '//div[@class="backnumber cf"]/ul[@class="cf"]/li[1]/a', disableSnapWhenPageIsClicked: 0, author: '//div[@id="comics"]/h4', pankuzuUp: '//a[text()="作品紹介"]' }, { // コミックDAYS他 url: '//comic-days.com/episode/|//tonarinoyj.jp/episode/|//shonenjumpplus.com/episode/|//kuragebunch.com/episode/|//pocket.shonenmagazine.com/episode/|//viewer.heros-web.com/episode/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//h2[@class="series-header-author"]', //'//div/h2[@class="series-header-author"]' }, { // url: '//ganma.jp/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//h4[@class="ng-binding"]', firstEpisode: '//a[@class="detail-action-some"]', lastEpisode: '//ol[@class="story"]/li/a/div/time[not(contains(text(),"配信予定"))]/../..', pankuzuUp: '', }, { // url: '//www.sunday-webry.com/detail', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div[@class="detail-block__image--author"]', firstEpisode: '//a[last()]/div/div[@class="detail-block__item--title"]', lastEpisode: '//div[@class="detail-block__item--latest"]', }, { // url: '//rookie.shonenjump.com/series/|//rookie.shonenjump.com/users/', // sibling: '//p[@class="page-area js-page-area"]/img/..', // header: '//header[@id="header"]/div/h2', nextEpisode: '//a[contains(text(),"続きを読む")]', disableSnapWhenPageIsClicked: 0, author: '//span[@class="user-name"]/a/strong|//h2[@class="user-name"]|//p[2]/a/span[@class="user-name"]', firstEpisode: '//li[1]/a/p[1]/span/../..', lastEpisode: '//li[last()]/a/p[1]/span/../..', pankuzuUp: '//a[contains(text(),"作品ページへ")]|//a/span[@class="series-title"]', }, { // url: '//www.comico.jp/challenge/|//www.comico.jp/articleList', sibling: '', header: '', disableSnapWhenPageIsClicked: 0, author: '//p[contains(@class,"__author")]/a', firstEpisode: '//div[contains(@class,"list-episode02__body")]/p[text()="第1話"]/../..|//a[@class="list-episode02__item-inner _articleListItem" and @data-articleno="1"]/div/div[1]/div[@class="list-episode02__label-group "]|//ul/li[1]/a/div/p[contains(@class,"list-episode")]', lastEpisode: '//ul[@class="list-episode02__list _articleList"]/li[last()]/a[@data-is-sell="true"]/div/p/../..|//a[text()="続きから読む"]|//ul/li[last]/a/div/p[contains(@class,"list-episode")]', }, { // url: '//www.comico.jp/detail|//www.comico.jp/challenge/detail', sibling: '', header: '', prevEpisode: '//a/img[@alt="前の話"]/..', nextEpisode: '//a/img[@alt="次の話"]/..', disableSnapWhenPageIsClicked: 0, author: '//p[contains(@class,"__author")]/a', firstEpisode: '', lastEpisode: '', pankuzuUp: '//a/img[@alt="話一覧"]/..', }, { // url: '//daysneo.com/works/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div/p[@class="author"]/a[1]', firstEpisode: '//li[1]/div[last()]/dl/dt/strong/a', lastEpisode: '//li[last()]/div[last()]/dl/dt/strong/a', pankuzuUp: '//a[text()="作品詳細ページへ"]', }, { // url: '//ebookjapan.yahoo.co.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '//p[@class="book-main__author"]/a|//p[@class="book-main__author underline"]/a', firstEpisode: '//li[last()]/div/div[last()]/a/strong[contains(text(),"無料")]/..', lastEpisode: '//li[1]/div/div/a[@class="btn"]/strong[text()="無料"]/..', pankuzuUp: '', }, { // url: '//mangacross.jp/comics/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div[@class="comic-area__author"]', firstEpisode: '//ul[@class="episode-list"]/li[last()]/a/div[2]', lastEpisode: '//ul[@class="episode-list"]/li[1]/a/div[2]' }, { // url: '//comic.mag-garden.co.jp/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div/div[@class="inner"]/h3' }, { // url: '//www.mangabox.me/reader/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div/p[@class="episodes_author"]', lastEpisode: '//SPAN[@class="episodes_strong_text is_new"]/../..' }, { // url: '//cycomi.com/fw/cycomibrowser/chapter/', sibling: '', header: '', nextEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//p[@class="title-author"]', firstEpisode: '//div[@class="title-chapters"]/div/a[1]', lastEpisode: '//a[contains(text(),"最新話を読む")]', pankuzuUp: '//a[text()="作品TOP"]', }, { // url: '//mangahack.com/comics/', sibling: '//div[@class="comic_img"]/img/..', header: '//header[1]', nextEpisode: '//li[@class="right"]/a', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '//a[text()="はじめから読む"]', lastEpisode: '//li[last()]/a[text()="最新話を読む"]', prevEpisode: '//li[@class="left"]/a', pankuzuUp: '//div[1]/ul[@class="cf"]/li/span[1]/a', }, { // url: '//manga-park.com/title/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//p[@class="author txtColorSubject"]', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//www.alphapolis.co.jp/manga/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div/div[@class="author"]/span/a[1]|//div[@class="mangaka"]/a|//div[@class="author-label"]/div[2]/a', firstEpisode: '//div[@class="first-time-free"]/a[contains(text(),"第1回を無料で読む")]', lastEpisode: '//div[@class="episode-list"]/a[1]/div/div[1]/../..', pankuzuUp: '', }, { // url: '//web-ace.jp/youngaceup/', sibling: '//div[@class="box inner viewerImageBox"]/a/img[1]/../../..', header: '', nextEpisode: '//section/div/div/a[text()="次の話へ"]', prevEpisode: '//a[text()="前の話へ"]', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '//a[text()="作品TOPへ"]', }, { // url: '//comic.webnewtype.com/contents/', sibling: '//div[@id="viewerContainer"]/div/div[@class="box inner viewerImageBox"]/a/img[1]/../../..', header: '', nextEpisode: '//a/img[@alt="次の話"]/..', prevEpisode: '//header[@class="ViewerHeader"]/nav/a/img[@alt="前の話へ"]/..', disableSnapWhenPageIsClicked: 0, author: '//span[@class="WorkSummary-headerinfo"]', firstEpisode: '//a[contains(text(),"最初から読む")]', lastEpisode: '//section/ul/li[1]/a/div/h3[@class="ListCard-title"]/../..', pankuzuUp: '//h1[@class="ViewerHeader-title"]/a', atamadashiDelay: 600 }, { // url: '//twitter.com/', sibling: '//div[@id="timeline" and @class="content-main AdaptiveSearchTimeline"]/div/div/ol/li/div/..|//div/div/ol/li[@data-item-type="tweet"]', header: '//div[@class="ProfileCanopy-inner"]/div[last()]|//DIV[@class="AdaptiveFiltersBar"]/..', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//www.ebigcomic4.jp/title/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '', lastEpisode: '//span[@class="episodeName"]', pankuzuUp: '', }, { // url: '.5ch.net/', sibling: '//dl[@class="thread"]/dt|//span[@class="number"]/../..', header: '//nav[@class="navbar-fixed-top search-header"]/div', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//www.ganganonline.com/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '//ul[@class="past_2c"]/li[1]/a/span/strong', lastEpisode: '//li[5]/a[@class="gn_link_btn"]/img[@alt="読む"]/..', pankuzuUp: '', }, { // url: '//watamote.com/', sibling: '//span[@class="res"]/..', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//news.mynavi.jp/series/|//news.mynavi.jp/article/', sibling: '//img[@class="photo_table__img lazyload"]|//td/img[@class="lazyload" and @src="images/001.jpg"]', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//a[@class="article-author__name"]', firstEpisode: '//div/section[last()]/div[@class="tile3__link js-link"]/div[@class="tile3__thumb"]/div/img[@class="tile3__img"]', lastEpisode: '//section[1]/div/div/div[@class="tile3__img-wrap"]/img', pankuzuUp: '', }, { // url: '//matogrosso.jp/', sibling: '//div[@class="asset-body"]/div/img|//div[@class="asset-body"]/img|//div[@class="asset-body"]/div/div/img', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//h3[@class="widget-header"]/a', firstEpisode: '//div[@class="asset-content"]/div[@class="asset-body"]/dl/dd[last()]/a', lastEpisode: '//div[@class="asset-body"]/dl/dd[1]/a', pankuzuUp: '//h3[@class="widget-header"]/a[1]', }, { // url: '//sukupara.jp/', sibling: '//div[@class="magarea"]/img/..', header: '', // nextEpisode: '//li[@id="next-page-btn"]/a/img', //uAutoPagerizeを使うべき // prevEpisode: '//li[@id="prev-page-btn"]/a/img', //uAutoPagerizeを使うべき disableSnapWhenPageIsClicked: 0, author: '//div[@id="artist"]/dl/dt', firstEpisode: '//a/img[@alt="第1回はコチラから"]', lastEpisode: '//p[@class="newest-story-tit"]/a', pankuzuUp: '//ul[@class="menulist clearfix"]/li[last()-1]/a', }, { // url: '//cho-animedia.jp/comic_category/|//cho-animedia.jp/comic/', sibling: '//div[@class="contents"]/p/img', //'//section[@class="contents_area"]/div[@class="contents"]', // header: '//html/body/header[@class="fixed"]', nextEpisode: '//dl[last()]/dt/a/img[@class="attachment-full size-full wp-post-image"]/..', prevEpisode: '//dl[1]/dt/a/img[@class="attachment-full size-full wp-post-image"]/..', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '//li[last()]/a/div[@class="photo"]/img/../..', lastEpisode: '//li[1]/a/div[@class="photo"]/img/../..', pankuzuUp: '//div[@class="breadcrumbs"]/ul/li[last()-1]/a', }, { // url: '//leedcafe.com/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div[@class="creator-header clearfix"]/h2/a', firstEpisode: '', lastEpisode: '//div[1]/div/div/div/p/a[@class="btn btn-default"]', pankuzuUp: '', }, { // url: '//storia.takeshobo.co.jp/manga/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div[@class="name_intro_author"]', firstEpisode: '//div[last()]/div[@class="box_episode_text"]/a[@class="btn"]', lastEpisode: '//div[last()]/div[1]/div[@class="box_episode_text"]/a[1]', pankuzuUp: '//a[text()="作品ページへ"]', }, { // url: '//www.tatan.jp/', sibling: '//div[@id="viewer_content"]/img', header: '', nextEpisode: '//a/img[@class="btn_next"]', prevEpisode: '//a/img[@class="btn_prev"]', disableSnapWhenPageIsClicked: 0, author: '//p[@class="author"]', firstEpisode: '//ul[@id="sakuhin_backnumber_ul"]/li/a[text()="1"]', lastEpisode: '//a/img[@alt="最新話を読む"]/..', pankuzuUp: '//a/img[@class="btn_sakuhin"]/..', }, { // url: '//cakes.mu/', sibling: '//img[@class="dropshadow"]/..|.//div[5]/p/img/..', //|//div[@class="article-content"]/h1', header: '//header[@class="postHeader"]', nextEpisode: '//li[@class="navi-items next"]/a[@data-ga="post:header:next"]', prevEpisode: '//li[@class="navi-items prev"]/a[@data-ga="post:header:previous"]', disableSnapWhenPageIsClicked: 0, author: '//div/p[@class="post-author"]/span|//div[@data-cakes-amazon=""]/div[@id="container_right"]/div/h3/a', firstEpisode: '//li[last()]/h3[@class="post-title-full"]/a', lastEpisode: '//li[1]/h3[@class="post-title-full"]/a', pankuzuUp: '//h2[@class="post-title"]/a', }, { // url: '//kawaii2ch.com/', sibling: '//div[contains(@class,"t_h")]/div/..|//a[@class="related-entry-title-link"]/../../../..', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//comicpash.jp/', sibling: '//main[@class="manga row"]/img', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//p[@class="mangaMainTitle__name"]', firstEpisode: '//a[contains(text(),"第1話を読む")]', lastEpisode: '//a/em[contains(text(),"最新話")]/..', pankuzuUp: '//section[@typeof="BreadcrumbList"]/div[@class="row"]/span[2]/a/span/..', }, { // url: '//www.nicovideo.jp/search/', sibling: '//li[@class="item nrn-thumb-info-done"]', header: '', //'//div[@id="siteHeader"]', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//www.jstage.jst.go.jp/', sibling: '//ul[@class="search-resultslisting"]/li', header: '//body/span[@class="noprint"]/header/nav', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//ci.nii.ac.jp/', sibling: '//div[@class="listitem xfolkentry"]/..', header: '//div[@id="nav-content"]', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '//comic.pixiv.net/works/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div[@class="works-author"]', firstEpisode: '//a[text()="最初から読む"]', lastEpisode: '//a[1]/div/div[@class="episode-num"]/../..', pankuzuUp: '', }, { // url: '//comic-fuz.com/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '//div/div[contains(@class,"author")]/div/p/a', firstEpisode: '//li[1]/div[@class="data"]/div/div/a', lastEpisode: '', pankuzuUp: '', }, { // url: '//comicawa.com/TitleDetail/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '//div[@role="button" and text()="はじめから読む"]', lastEpisode: '//div[@role="button" and text()="最新話を読む"]', pankuzuUp: '', }, { // url: '//manga.line.me/indies/product/detail', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '//a[@class="MdBtn03Read01" and contains(text(),"最初から読む")]', lastEpisode: '//div[@class="fnAutoPagingContainer"]/div[1]/div/a/h3', pankuzuUp: '', }, { // url: '//to-ti.in/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '//div[@class="page_pager"]/p[@class="prev"]/a/span', lastEpisode: '//div[@class="page_pager"]/p[@class="next"]/a/span', pankuzuUp: '', }, { // url: '//yomitai.jp/', sibling: '//li[@class=""]/figure/img/../..', header: '', nextEpisode: '//li[@id="article-nav-next"]/a', prevEpisode: '//li[@class="series-prev"]/a', disableSnapWhenPageIsClicked: 1, author: '//figcaption[@class="author-name"]', firstEpisode: '//ul[@class="list"]/li[last()]/div/h3/a', lastEpisode: '//ul[@class="list"]/li[1]/div/h3/a', pankuzuUp: '//a/figure/figcaption[text()="連載の一覧はこちら"]', }, { // url: '//comic-trail.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '//div[@class="series-detail"]/h2', firstEpisode: '//a[contains(text(),"1話を読む")]', lastEpisode: '//a[contains(text(),"最新話を読む")]', pankuzuUp: '', }, { // url: '//gammaplus.takeshobo.co.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '//div[@class="name_intro_author"]', firstEpisode: '', lastEpisode: '//a[@class="btn" and text()="最新エピソードを読む"]|.//section[@class="episode"]/div/div[1]/div/a[1]', pankuzuUp: '', }, { // note url: '//note.mu/', sibling: '//a[@rel="noopener noreferrer" and @class="o-noteContentImage__itemLink a-link"]/img/../..', header: '//div[@id="__layout"]/div/header', nextEpisode: '//a[@class="o-sliblingNote__link o-sliblingNote__link--next a-link"]/div', prevEpisode: '//a[@class="o-sliblingNote__link o-sliblingNote__link--prev a-link"]/div', disableSnapWhenPageIsClicked: 1, author: '//div[@class="o-noteContentHeader__name"]/a', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // コミックアース・スター url: '//www.comic-earthstar.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '//section[@id="comic_info"]/span[@class="title_span"]', firstEpisode: '//li[last()]/span/a[@class="on_m readbtn2"]', lastEpisode: '//td/a[@class="new_read_btn"]', pankuzuUp: '', }, { // url: '//comic-walker.com/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '//ul[@class="acBacknumber-list first-preview clearfix"]/li[1]/a[@target="_self"]', lastEpisode: '//div[@class="container"]/div/p[@class="btn-detailLink link-p"]/a', pankuzuUp: '', }, { // url: '//webcomicgamma.takeshobo.co.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '//div[@class="name_intro_author"]', firstEpisode: '//div[@class="box_episode"]/div[last()]/div/a[contains(text(),"このエピソードを読む")]|//div[last()]/div[@class="box_episode_text"]/a[contains(text(),"このエピソードを読む")]', lastEpisode: '//a[contains(text(),"最新エピソードを読む")]|//div[1]/div[@class="box_episode_text"]/a[text()="このエピソードを読む"]', pankuzuUp: '', }, { // url: '//online.ichijinsha.co.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 1, author: '', firstEpisode: '//li[last()]/ul/li/a[@class="pc"]', lastEpisode: '//div[contains(@class,"read")]/a[@class="pc corner"]', pankuzuUp: '', }, { // url: '//comic-meteor.jp/', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '//div[@class="work_author_intro_name"]', firstEpisode: '//div[last()]/div/div[2]/a[@target="_blank" and text()="読む"]|//a[text()="第1話を読む"]', lastEpisode: '//a[text()="最新話を読む"]|//div[@class="latest_info_link_btn01"]/a', pankuzuUp: '//div[@class="topics d-none d-sm-block"]/ul/li[last()-1]/a|//div[@class="leaflet-inner"]/a[@alt="作品ページに戻る"]', }, { // url: '', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // url: '', sibling: '', header: '', nextEpisode: '', prevEpisode: '', disableSnapWhenPageIsClicked: 0, author: '', firstEpisode: '', lastEpisode: '', pankuzuUp: '', }, { // ニコニコ静画(漫画) url: '//seiga.nicovideo.jp/watch/|//seiga.nicovideo.jp/comic/', sibling: '//div[@class="pages"]/ul/li', // //ul[contains(@id,"page_")]/..',// '//div[@class="note"]/..|//div[@class="note balloon_disabled"]/..|//div[@class="pages"]/ul/li', header: '//div[@id="siteHeaderInner"]', atamadashi: '//div[@class="note"]|//div[@class="note balloon_disabled"]|//img[@class="lazyload"]|//div[@class="pages"]/ul/li', author: '//div[@class="author"]/h3/span|//span[@class="author_name"]', // Amazonを基点に~の管轄 firstEpisode: '//a[@class="first"]', lastEpisode: '//a[@class="last"]', prevEpisode: '//p[@class="prev"]/a', nextEpisode: '//span[@class="next_text"]|//a[@class="next"]', pankuzuUp: '//ul[@class="sg_pankuzu"]/li[last()-1]/a' }] var marginu = 3; var isChrome = window.navigator.userAgent.toLowerCase().indexOf("chrome") != -1; var scrollSpeed = pref("scrollSpeed") || (isChrome ? 1.5 : 1.5); var atamadashi = pref("atamadashi") || "false"; var sscrollY = 0; var sscrollDY = 0; var scrint = 0; // match文を生成 if (GenerateMatch) { let matchlist = "" for (let s of SITEINFO.slice().sort(function(a, b) { return a.url > b.url ? 1 : -1 })) { if (s.url != "") for (let s2 of s.url.split("|")) { matchlist += "// @match *:" + s2.replace(/\.\*/gm, "*").replace(/^\./, "//*.") + "*\n"; } } alert(matchlist); } var customsib = pref("wcs_siblingXPath") || ""; if (customsib) { SITEINFO.length = 0; SITEINFO.push({ "url": "//" + location.href.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1] + "/", "sibling": customsib, "disableSnapWhenPageIsClicked": 1 }) // console.log("Found in localStorage\n---\n }, { // \n url: '//"+location.href.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1]+"',\n sibling: '"+customsib+"',\n header: '',\n nextEpisode: '',\n prevEpisode: '',\n disableSnapWhenPageIsClicked: 0,\n author: '',\n firstEpisode: '',\n lastEpisode: '',\n pankuzuUp: '',\n"); } document.addEventListener('keydown', function f(e) { if (/input|textarea/i.test(e.target.tagName) == false) { if (!e.getModifierState("Alt") && !e.getModifierState("Control") && e.getModifierState("Shift") && (e.key == "\`")) { // e.preventDefault(); var copipe = customsib ? "現在の設定:\n\n }, { // \n url: '//" + location.href.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1] + "/',\n sibling: '" + customsib + "',\n header: '',\n nextEpisode: '',\n prevEpisode: '',\n disableSnapWhenPageIsClicked: 1,\n author: '',\n firstEpisode: '',\n lastEpisode: '',\n pankuzuUp: '',\n }, { // \n\n" : ""; //console.log("livedoor:" + (document.body.innerHTML.match(/\livedoor\./gmi) || [1]).length + " @class=t_H:" + elegeta('//div[contains(@class,"t_h")]').length); let defsib = ((document.body.innerHTML.match(/\livedoor\./gmi) || [1]).length >= 5 && elegeta('//div[contains(@class,"t_h")]').length > 4) ? '//div[contains(@class,"t_h")]' : ''; var sib = prompt(copipe + "Enter Sibling XPath\n空欄にすると設定を削除します", customsib || defsib); pref("wcs_siblingXPath", null); if (!sib || !eleget0test(sib)) { alert("空欄、またはXPathとして1つ以上ヒットしないので、設定を削除します"); } else { /* while(!(eleget0test(sib).tagName.match(/^BODY$/i))){ if(getNextSib(eleget0test(sib),sib) || getPrevSib(eleget0test(sib),sib)) break; sib+="/..";} alert(sib); */ pref("wcs_siblingXPath", sib); } location.reload(); return; } } }, false); var thissite = 0; // for(let si of SITEINFO){for (let pro in si){if(si[pro])console.log(pro+" : "+si[pro])}} for (var i = 0; i < SITEINFO.length; i++) { if (SITEINFO[i].url == "") continue; if (location.href.match(SITEINFO[i].url)) { thissite = i; //console.log("---\nweb漫画サイトにショートカットキーを追加: "); var j = 0; for (let pro in SITEINFO[i]) { if (SITEINFO[i][pro]) { //console.log(pro + " : " + SITEINFO[i][pro]) var str1 = ["url:", "sibling:", "sibling:", "header:", "nextEpisode:", "prevEpisode:", "disableSnapWhenPageIsClicked:", "author:", "firstEpisode:", "lastEpisode:", "pankuzuUp:"]; var str2 = ["", "←→:前次ページ", "A:頭出し", "", "Enter:次の話", "]:前の話", "", "", "→:第1話", "Enter:最新話", "Shift+↑:上階層"]; for (var k = 0; k < str1.length; k++) { if (pro + ":" == str1[k] && str2[k] && eleget0(SITEINFO[i][pro])) { if (PopupHelpMS) { let node = document.body.appendChild(document.createElement('span')); node.innerHTML = str2[k]; //+" : "+SITEINFO[i][pro]; node.setAttribute("style", "max-width:95%; right:0; bottom:" + (j * 21) + "px; z-index:2147483647; opacity:" + 1 + "; text-align:left; line-height:1.1; position:fixed; font-size:11px; font-weight:bold; margin:2px; text-decoration:none; padding:2px 5px; border-radius:15px; color:#ffffff; " + (ButtonBG)); //" box-shadow:3px 3px 3px #0004;"); $(node).hide(0); setTimeout(() => { $(node).slideDown('fast'); }, 67 * j); //fadeIn('fast') setTimeout(() => { $(node).hide(400).queue(function() { this.remove(); }) }, PopupHelpMS + 67 * j); //fadeOut('fast') } j++; } } } } addHelp(SITEINFO[i].firstEpisode, "→"); addHelp(SITEINFO[i].lastEpisode, "Enter"); addHelp(SITEINFO[i].prevEpisode, " ] "); addHelp(SITEINFO[i].nextEpisode, "Enter"); addHelp(SITEINFO[i].pankuzuUp, "Shift+↑"); function getArrowedGap() { // ヘッダのy下端を計算 var arrowedGap = marginu; if (SITEINFO[thissite].header) { var seigaheader = eleget0(SITEINFO[thissite].header); if (seigaheader) { var tmp = seigaheader.getBoundingClientRect().bottom; // - window.pageYOffset // console.log(tmp); if (seigaheader && tmp >= 0) { var arrowedGap = marginu + tmp; // console.log("ヘッダあり");//+window.pageYOffset; } } } dc("arrowedGap:" + arrowedGap); // console.log("ArrowedGap:"+arrowedGap+"\nMarginU:"+ marginu+"\nseigaH:"+seigaheader.getBoundingClientRect().bottom,"\noffset:"+window.pageYOffset); return arrowedGap; } //console.log(SITEINFO[thissite]) document.addEventListener("keydown", function(e) { if (/input|textarea/i.test(e.target.tagName)) return; var arrowedGap = getArrowedGap(); var pressed = (e.ctrlKey ? 'c' : '') + (e.altKey ? 'a' : '') + (e.shiftKey ? 's' : '') + String(e.which); { if (SITEINFO[thissite].pankuzuUp && pressed == "s38") if (moveClick(SITEINFO[thissite].pankuzuUp)) { e.preventDefault(); return; } // Shift上 if (SITEINFO[thissite].sibling && (pressed == "39" || pressed == "37")) { //左右 e.preventDefault(); // もっとも接近しているページ=今見ているページをfoundeleに入れる var ele = eleget(SITEINFO[thissite].sibling); var minGap = 9999; var foundele = null; var nh = getNowHeaderHeight(); for (var i = 0; i < ele.snapshotLength; i++) { var ele0 = ele.snapshotItem(i); var eley = ele0.getBoundingClientRect().top - nh - marginu; if (Math.abs(eley) < minGap) { minGap = Math.abs(eley); foundele = ele0; if (minGap <= (arrowedGap - nh + marginu + 2)) { dc("nearest:" + foundele.tagName + "." + foundele.className + "#" + foundele.id + "\n" + "minGap:" + minGap + " aGap:" + (arrowedGap - nh + marginu) + " break at " + i); break; } } } snap(foundele, pressed == 37 ? "prev" : "next", arrowedGap, SITEINFO[thissite].sibling); } if (SITEINFO[thissite].nextEpisode && (pressed == "s39" || pressed == "13")) // Shift右 enter if (moveClick(SITEINFO[thissite].nextEpisode)) { e.preventDefault(); return; } if (SITEINFO[thissite].prevEpisode && (pressed == "s37" || pressed == "221")) if (moveClick(SITEINFO[thissite].prevEpisode)) { e.preventDefault(); return; } //Shift左 ] if (SITEINFO[thissite].firstEpisode && pressed == "39") if (moveClick(SITEINFO[thissite].firstEpisode)) { e.preventDefault(); return; } // 右 if (SITEINFO[thissite].lastEpisode && (pressed == "s39" || pressed == "13")) if (moveClick(SITEINFO[thissite].lastEpisode)) { e.preventDefault(); return; } // Shift右 enter if (pressed == "s83") { // shift+s スクロール速度 e.preventDefault(); scrollSpeed = proInput("スクロール速度を入力してください(0:API使用、1:瞬間移動、1.01~:速度指定)", scrollSpeed, 0, 30); pref("scrollSpeed", scrollSpeed); } if (pressed == "65") { // a 頭出しオンオフ e.preventDefault(); atamadashi = atamadashi === "true" ? "false" : "true"; alert("[a] 頭出し機能を" + atamadashi + "にしました"); pref("atamadashi", atamadashi); } if (location.href.match("/seiga.nicovideo.jp/watch/|//seiga.nicovideo.jp/comic/")) { if (pressed == "67") { // c コメントオンオフ e.preventDefault(); eleget0('//li[@id="show_comment"]/span').click(); return; } if (pressed == "72") { // h ヘッダー固定追従 e.preventDefault(); eleget0('//li[@id="siteHeaderRightMenuUnfix" and @style="display: block;"]/a/span|//li[@id="siteHeaderRightMenuFix" and @style="display: block;"]/a/span').click(); return; } } if (pressed == "70" || pressed == "219") { // f [ 全画面化 e.preventDefault(); var y = window.pageYOffset; var doc = window.document; var docEl = doc.documentElement; var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen; var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen; if (!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) { requestFullScreen.call(docEl); } else { cancelFullScreen.call(doc); } setTimeout(window.scroll, 100, 0, y); } } }, false); // ページクリックでスナップ if (!SITEINFO[thissite].disableSnapWhenPageIsClicked && SITEINFO[thissite].sibling) { setTimeout(() => { var ele = eleget(SITEINFO[thissite].sibling); for (var i = ele.snapshotLength; i--;) ele.snapshotItem(i).addEventListener("click", function(e) { snap(this, "next", getArrowedGap(), SITEINFO[thissite].sibling); }, false); }, 500); } // 作者名でWeb漫画アンテナ if (SITEINFO[thissite].author) { setTimeout(() => { sakushaantenna(document) }, 500); document.body.addEventListener('AutoPagerize_DOMNodeInserted', function(evt) { sakushaantenna(evt.target) }, false); } // 頭出し if (atamadashi == "true" && SITEINFO[thissite].atamadashi) { setTimeout(() => { loadfocus(0, SITEINFO[thissite].atamadashi) }, 16) setTimeout(() => { loadfocus(0, SITEINFO[thissite].atamadashi) }, 600) } else if (atamadashi == "true" && SITEINFO[thissite].sibling) { setTimeout(() => { loadfocus(0, SITEINFO[thissite].sibling) }, 16) setTimeout(() => { loadfocus(0, SITEINFO[thissite].sibling) }, SITEINFO[thissite].atamadashiDelay || 333) } } } return; function sakushaantenna(node) { for (let ele of elegeta(SITEINFO[thissite].author, node)) { $('Web漫画アンテナ'.replace("***", ele.innerText.replace(/\/|/|\,/gmi, " OR ").replace(/ ?先生[::\//・]?|原作[::\//・]|原案[::\//・]|脚本[::\//・]|著[::\//・]|著者[::\//・]|漫画[::\//・]|作画[::\//・]|イラスト[::\//・]|キャラクター(原案)?[::\//・]|画[::\//・]|作[::\//・]|絵[::\//・]|構成[::\//・]|協力[::\//・]|[::・]|[\((][^)\)]*[)\)]|=/gmi, " ").replace(/ |・| /g, " ").replace(/^ OR | OR $/gmi, "").trim())).insertAfter(ele); } } function loadfocus(times = 0, atamadashi) { let xp = atamadashi; if (!xp || times > 10000) return false; // if (eleget0(xp)) { setTimeout(() => { loadfocus2(atamadashi); }, 200); return; } else setTimeout(() => { loadfocus(times + 200, atamadashi); }, 200) if (eleget0(xp)) { setTimeout(() => { loadfocus2(atamadashi); }, 100); return; } else setTimeout(() => { loadfocus(times + 100, atamadashi); }, 100) } function loadfocus2(atamadashi) { var xp = atamadashi; var ele = eleget0(xp); if (ele) { sscroll(ele.getBoundingClientRect().top + window.pageYOffset - marginu - getNowHeaderHeight()); } return ele; } function getNextSib(ele, xpath) { // xpathに適合する弟ノードを走査 do { if (!ele.nextElementSibling) return null; ele = ele.nextElementSibling; for (let ele2 of elegeta(xpath)) { if (ele == ele2) return ele; } } while (ele.nextElementSibling); return null; } function getPrevSib(ele, xpath) { // xpathに適合する兄ノードを走査 do { if (!ele.previousElementSibling) return null; ele = ele.previousElementSibling; for (let ele2 of elegeta(xpath)) { if (ele == ele2) return ele; } } while (ele.previousElementSibling); return null; } function snap(targetele, pn, arrowedGap, xpath) { if (!targetele) return; var headery = getNowHeaderHeight(); var nowpagey = targetele.getBoundingClientRect().top + window.pageYOffset - marginu; var nextpage = (pn == "next" ? getNextSib(targetele, xpath) : getPrevSib(targetele, xpath)); if (nextpage) dc("nextpage:" + nextpage.tagName + "." + nextpage.className + "#" + nextpage.id); if (nextpage == null) { if (SITEINFO[thissite].nextEpisode) if (eleget0(SITEINFO[thissite].nextEpisode)) { var nextpagey = eleMiddleY(SITEINFO[thissite].nextEpisode); } else return; else return; } else { var nextpagey = nextpage.getBoundingClientRect().top + window.pageYOffset - marginu; dc("nextpagey:" + nextpagey); } if (nextpage === null && pn == "prev") { nextpagey = 0; nowpagey = 0; if (window.pageYOffset < 2) { if (SITEINFO[thissite].prevEpisode) moveClick(SITEINFO[thissite].prevEpisode); } } var nowy = window.pageYOffset + headery; dc(Math.abs(nowy - nowpagey) + " present gap"); dc(arrowedGap + " allowed gap"); if (Math.abs(nowy - nowpagey) <= arrowedGap) { sscroll(nextpagey - headery); if (nextpage === null) { if (pn == "next") { if (SITEINFO[thissite].nextEpisode) moveClick(SITEINFO[thissite].nextEpisode); } } } else { targetele.focus(); sscroll(nowpagey - headery); } return; } function getNowHeaderHeight() { if (SITEINFO[thissite].header == "") { return marginu; } var header1y = 0; var seigaheader = eleget0(SITEINFO[thissite].header) if (seigaheader === null) header1y = 0; else { var seigaheaderpos = seigaheader.getBoundingClientRect(); header1y = seigaheaderpos.bottom; } var headery = Math.max(header1y, 0); return headery + marginu; } function eleMiddleY(xpath) { var el2 = eleget0(xpath); if (el2) { return (el2.getBoundingClientRect().top + window.pageYOffset + eleget0(xpath).getBoundingClientRect().height - window.innerHeight / 2); } else return 0; } function moveClick(xpath) { if (!eleget0(xpath)) return false; GM_addStyle(":focus { box-shadow: 0px 0px 10px 10px rgba(0, 250, 0, 0.5), inset 0 0 100px rgba(0, 250, 0, 0.1) !important; outline: rgba(0, 250,0,0.7) solid 4px !important; outline-offset: 1px !important; }") eleget0(xpath).focus(); eleget0(xpath).click(); sscroll(eleMiddleY(xpath)); return true; } function eleget0(xpath) { var ele = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); return ele.snapshotLength > 0 ? ele.snapshotItem(0) : null; } function eleget(xpath) { return document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); } function elegeta(xpath, node = document) { var ele = document.evaluate("." + xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var array = []; for (var i = 0; i < ele.snapshotLength; i++) array[i] = ele.snapshotItem(i); return array; } function sscroll(dy) { if (scrollSpeed < 1) { //APIでスクロール // console.log("api使用"); window.scroll({ left: 0, top: dy, behavior: "smooth" }); return; } if (scrollSpeed == 1) { window.scroll({ left: 0, top: dy, behavior: "instant" }); return; } sscrollY = window.pageYOffset; //chrome sscrollDY = dy; scrint = 0; setTimeout(sscrollInt, 16); return; } function sscrollInt() { scrint++; sscrollY = sscrollY + (sscrollDY - sscrollY) / scrollSpeed; window.scroll(0, sscrollY); // if (Math.abs(sscrollY - sscrollDY) > 2) setTimeout(sscrollInt, 16); if (Math.abs(sscrollY - sscrollDY) >= 1) { setTimeout(sscrollInt, 16); } else window.scroll(0, sscrollDY); // else console.log("スクロールに掛かった回数(最短1/60秒)…" + scrint + "回"); return; } function proInput(prom, defaultval, min, max = Number.MAX_SAFE_INTEGER) { return Math.min(Math.max( Number(window.prompt(prom, defaultval).replace(/[A-Za-z0-9.]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248); }).replace(/[^-^0-9^\.]/g, "")), min), max); } function addHelp(xpath, help) { if (!xpath) return; let ele = eleget0(xpath); if (ele) { ele.appendChild(document.createElement("span")).innerHTML = " (" + help + ")"; //console.log("Found:" + xpath); } return; } function eleget0test(xpath) { try { var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null) } catch (err) { return ""; } var ele = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); return ele.snapshotLength > 0 ? ele.snapshotItem(0) : ""; } function dc(str) { if (debug) console.log(str); } function pref(name, store = undefined) { // pref(name,data)で書き込み(数値でも文字列でも配列でもオブジェクトでも可)、pref(name)で読み出し var domain = (location.href.match(/^https?:\/{2,}(.*?)(?:\/|\?|#|$)/)[1] || location.href); if (store === undefined) { // 読み出し let data = GM_getValue(domain + " ::: " + name) if (data == undefined) return store; // 値がないなら終わり if (data.substr(0, 1) === "[") { // 配列なのでJSONで返す try { return JSON.parse(data || '[]'); } catch (e) { console.log("データベースがバグってるのでクリアします\n" + e); pref(name, []); return; } } else return data; } if (store === "" || store === [] || store === null) { // 書き込み、削除 GM_deleteValue(domain + " ::: " + name); return store; } else if (typeof store === "string") { // 書き込み、文字列 GM_setValue(domain + " ::: " + name, store); return store; } else { // 書き込み、配列 try { GM_setValue(domain + " ::: " + name, JSON.stringify(store)); } catch (e) { console.log("データベースがバグってるのでクリアします\n" + e); pref(name, ""); } return store; } } })();