Greasy Fork is available in English.

Scrolling Hinatazaka46's blog

Scrolling Hinatazaka46's Blog Display

// ==UserScript==
// @name           Scrolling Hinatazaka46's blog
// @name:ja        日向坂46 ブログ スクロール
// @namespace      naoqv.hinatazaka
// @description    Scrolling Hinatazaka46's Blog Display
// @description:ja 日向坂46 ブログの諸々スクロール表示
// @version        1.38
// @match          https://www.hinatazaka46.com/s/official/diary/detail/*
// @match          https://www.hinatazaka46.com/s/official/diary/member/*
// @require        https://update.greasyfork.org/scripts/510022/1509450/HinatazakaStyleSetting.js
// @require        https://update.greasyfork.org/scripts/509934/1480445/HinatazakaExceptionHandlingWrapper.js
// @icon           https://cdn.hinatazaka46.com/files/14/hinata/img/favicons/favicon-32x32.png
// @compatible     chrome
// @compatible     firefox
// @license        MIT
// ==/UserScript==

const SCRIPT_NAME = "日向坂46 ブログ スクロール";

const NAME_ICON_MAP = {
"井口 眞緒" : "🍷",
"潮紗 理菜" : "🍀",
"柿崎 芽実" : "🐱",
"影山 優佳" : "⚽",
"加藤 史帆" : "🐻",
"齊藤 京子" : "🍜",
"佐々木 久美" : "🦒",
"佐々木 美玲" : "🍞",
"高瀬 愛奈" : "🐶",
"高本 彩花" : "🍒",
"東村 芽依" : "🍓",
"金村 美玖" : "🍣",
"河田 陽菜" : "🐼",
"小坂 菜緒" : "🦕",
"富田 鈴花" : "🛣️",
"丹生 明里" : "🐸",
"濱岸 ひより" : "🐣",
"松田 好花" : "🐙",
"宮田 愛萌" : "⛩️",
"渡邉 美穂" : "🏀",
"上村 ひなの" : "●🔻●",
"髙橋 未来虹" : "🌈",
"森本 茉莉" : "🐨",
"山口 陽世" : "⚾",
"石塚 瑶季" : "🏟",
"岸 帆夏" : "⛵",
"小西 夏菜実" : "☎",
"清水 理央" : "🫶", 
"正源司 陽子" : "🍫",
"竹内 希来里" : "✨",
"平尾 帆夏" : "🎮",
"平岡 海月" : "🪼",
"藤嶌 果歩" : "🐏",
"宮地 すみれ" : "🦥", 
"山下 葉留花" : "🌱",
"渡辺 莉奈" : "🎀",
"ポカ" : "🐦️"		
};

/** yyyy → 'yy */
const shortenYear = (x) => {
	Array.prototype.forEach.call(document.querySelectorAll(x), (y) => {
		const text = y.innerText;
		y.innerText = "'" + text.replace(/\d{2}(\d{2}\.)/, '$1');
	});
};

/** ブログ */
const detailPage = () => {

	const defaultStyle = `height: 50px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis "… 🔽"; margin-bottom: 0px;`;
	
	const articleTitleDiv = document.querySelector('.c-blog-article__title');
		
	articleTitleDiv.setAttribute("style", defaultStyle);
	
	if (articleTitleDiv.offsetWidth < articleTitleDiv.scrollWidth) {
		
		const articleTitle = articleTitleDiv.innerText;
		articleTitleDiv.innerText = articleTitle + "🔼";
		articleTitleDiv.classList.add("flow_text");
	}

	articleTitleDiv.addEventListener('click', function() {

		if (! this.classList.contains("flow_text")) {
			return;
		}

		if (window.getComputedStyle(this).overflow === "hidden") {
			this.setAttribute("style", "overflow: visible; margin-bottom: 0px;");
		} else {
			this.setAttribute("style", defaultStyle);
		}
	});

  const pBlogArticleHead = document.querySelector('.p-blog-article__head');
	const articleHeight = document.documentElement.clientHeight - pBlogArticleHead.getBoundingClientRect().bottom - 40;

	const styleElem = document.createElement("style");
	styleElem.setAttribute("rel", "stylesheet");
	styleElem.textContent = `
    .flow_text {
      cursor:pointer;
    }
    .c-blog-article__text {
      height: ${articleHeight}px; width: 640px; overflow: scroll; border: none;
    }
    .p-pager {
      margin-top: 10px;
    }
    .p-button--center {
      padding-top: 0;
      margin-top: -20px;
    }
    .c-button-grad.c-button-grad--big {
      min-width: 280px;
    }`;
	
	document.head.appendChild(styleElem);
};

/** 記事一覧 */
const memberPage = () => {

	const blogGroupHeight = document.documentElement.clientHeight;
	
	const styleElem = document.createElement("style");
	styleElem.setAttribute("rel", "stylesheet");
	styleElem.textContent = `
	html {
		scroll-behavior: smooth;
	}
	.c-blog-member__icon--all {
		height: 60px;
	}
	.p-button {
		padding-top: 0;
	}
	.d-article {
		line-height: 20px;
		margin-bottom: 8px;
	}
	.s-member-icon {
		font-size: larger
	}
	.s-article-title {
		font-size: smaller;
	}
	.s-datetime {
		font-size: smaller;
	}
	.l-maincontents--blog {
		height: ${blogGroupHeight}px;
		overflow: scroll;
		border: none;
	}
	.c-blog-article__title {
		margin-bottom: 0px;
	}`;

	document.head.appendChild(styleElem);
	
	shortenYear('.c-blog-article__date');

	const titleList = document.createElement('div');
	titleList.setAttribute("class", "s-blog__index");
	
	const profileButton = document.querySelector('.p-button');
	profileButton.after(titleList);

	const createAnchor = (idx, datetime, icon, articleTitle) => `<div class="d-article"><a href="#article${idx}">
		<span class="s-member-icon">${icon}</span>
		<span class="s-article-title">${articleTitle}</span><br/><span class="s-datetime">${datetime}</span>
	</a></div>`;
	
	const lMainContentsBlogTop = document.querySelector('.l-maincontents--blog').getBoundingClientRect().top;
	
	Array.prototype.forEach.call(document.querySelectorAll('.p-blog-article'), (x, i) => {
		
		x.setAttribute('id', "article" + i);
		const datetimeDiv = x.childNodes[1].childNodes[3].childNodes[1];
		const datetime = datetimeDiv.firstChild.textContent.trim();
		const articleTitleDiv = x.childNodes[1].childNodes[1];
		const articleTitle = articleTitleDiv.firstChild.textContent.trim();
		// メンバー混合リストの場合があるので名前を取得
		const memberName = x.childNodes[1].childNodes[3].childNodes[3].innerText;
		const icon = NAME_ICON_MAP[memberName];
		
		titleList.insertAdjacentHTML('beforeend', createAnchor(i, datetime, icon, articleTitle));
	});
};

handleException(()=> {

  const body = document.querySelector('body');

	// 内容が空のページ(卒業メンバーのブログなど)
	if (body.getElementsByTagName('*').length === 0) {
    console.log("* ");
		body.innerHTML = 'This page is no longer available';
		return;
	}

  // ひなたフェス/握手会 は非メンバーブログ
	const isNotMemberBlog = (location.search).match(/(cd=hinafes_blog|cd=event)/g);

	if (isNotMemberBlog) {
		return;
	}

  const matched = (location.href).match(new RegExp('\/(detail|member)\/'));

  if (! matched) {
	  return;
  }

  darkMode();
 
 	const styleElem = document.createElement("style");
	
	styleElem.setAttribute("rel", "stylesheet");
	
	let styleText = `
    .l-maincontents--blog, .l-other-contents--blog, .l-other-contents--blog::after, .p-blog-entry__group, .p-blog-entry__list {
        color: ${DEFAULT_CL};
        background-color: #202050;
    }
    .s-blog__index, .l-maincontents--blog,.p-blog-group, .p-blog-entry__list, .p-blog-entry__list {
        background-color: #202030;
    }`;
  
  if (isMobile()) {

    styleText = styleText + `.c-blog-article__title {color: ${DEFAULT_CL};}`;
  } else {

    const blogEntryItem = document.querySelector('.p-blog-entry__item');
    if (!blogEntryItem) {
      return;  
    }
    const blogEntryItemStyles = window.getComputedStyle(blogEntryItem, null);
    const blogEntryItemHeight = parseInt(blogEntryItemStyles["height"].replace('px', ''));
    const blogEntryItemMarginBottom = parseInt(blogEntryItemStyles["margin-bottom"].replace('px', ''));
    const blogEntryItemHeightWithMargin = blogEntryItemHeight + blogEntryItemMarginBottom;
 
    styleText = styleText + `.l-other-contents--blog {
      padding-top: 20px;
    }
    .p-blog-head-container {
      height: 200px;
    }
    .p-blog-head {
      padding-top: 0;
    }
    .c-blog-page__title {
      margin-bottom: 0;
    }
    .c-blog-member__icon {
      margin-bottom: 10px;
    }
    .p-blog-member__head {
      margin-bottom: 5px;
    }
    .c-blog-member__info-td__name {
      padding-bottom: 5px;
    }
    .s-blog__index {
      position: relative;
      z-index: 50;
      margin: 0 0 0 -50px;
      height: 160px;
      width: 290px;
      overflow: scroll;
    }
    .cale_table {
      margin-top: 0px;
    }
    .p-blog-article__head {
      background-color: #f6ffff;
      border: 1px solid #a0d8ef ;
      border-radius: 10px;
    }
    .c-blog-article__title {
      font-size: 2.5rem;
      line-height: 58px;
      color: #636767;
      background-color: #e0ffff;
      border-radius: 10px;
    }
    .c-blog-article__title, .c-blog-article__date {
      text-indent: 5px;
    }
    .l-maincontents--blog {
      padding-top: 20px;
    }
    .l-contents--blog-list {
      padding-bottom: 0;
    }
    .c-blog-entry_area__title {
      margin-bottom: 2px;
    }
    .p-blog-article {
      padding-bottom: 0;
      margin-bottom: 20px;
    }
    .p-blog-article__info {
      margin-bottom: 10px;
    }
    .c-pager__item__text time {
      font-size: 1.4rem;
    }
    .p-blog-face__title {
      margin-bottom: 10px;
    }
    .p-blog-face__group {
      padding-top: 20px;
      height: 460px;
      width: 1100px;
      overflow: scroll;
    }
    .p-blog-face__list {
      width: 122px;
      height: 162px;
    }
    .c-blog-face__item:hover {
      margin-top: -6px;
      margin-left: -6px;
      width: 134px;
      height: 134px;
    }
    .p-blog-entry__group {
      padding-bottom: 0;
    }
    .p-blog-entry__list {
      height: ${blogEntryItemHeightWithMargin * 3}px;
      width: 230px;
      overflow: scroll;
      border: none;
      margin-bottom: 20px;
    }
    .c-blog-entry__name {
      font-size: 1.3rem;
    }`;
  }

  styleElem.textContent = styleText;

  document.head.appendChild(styleElem);
  
  if (isMobile()) {
    return;
  }
  
  menuBarSetting();

  const pageType = matched[1];

	shortenYear('.c-blog-article__date time');
	shortenYear('.c-blog-entry__name');
	shortenYear('.c-pager__item__text time');
 
	
	const PAGE_TYPE_ERROR_MSG = "Processing of out-of-scope pages. Check the settings @match.";

	if (pageType === "detail") {
		
		detailPage();
	} else if (pageType === "member") {
		
		memberPage();
	} else {
		throw new Error(PAGE_TYPE_ERROR_MSG);
	}

  Array.prototype.forEach.call(document.querySelectorAll(".c-blog-article__text div *, .c-blog-article__text p span"), (x) => {
    x.style.color = DEFAULT_CL;
  });
	
	// 半透明ヘッダーメニュー 高さ
	const headerHeight = document.querySelector(".p-header-wrap").offsetHeight;

	// スクロール位置リセット リロード時のズレ対応
	scrollTo(0, 0);

	// 文頭までスクロール
	scrollTo({
		top: document.querySelector(".p-blog-article__head").getBoundingClientRect().top - headerHeight,
		behavior: "smooth"
	});

}, SCRIPT_NAME);