您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Makes cards' heights to be dynamic depending on image height
当前为
- // ==UserScript==
- // @name InoReader dynamic height of tiles in the card view
- // @namespace http://tampermonkey.net/
- // @version 0.1.0
- // @description Makes cards' heights to be dynamic depending on image height
- // @author Kenya-West
- // @match https://*.inoreader.com/*
- // @icon https://inoreader.com/favicon.ico?v=8
- // @license MIT
- // ==/UserScript==
- // @ts-check
- (function () {
- "use strict";
- document.addEventListener('tm_inoreader-viewing-api-for-userscripts_articleAdded', (e) => {
- const { element } = e.detail?.details;
- setTimeout(() => {
- start(element);
- }, 3500);
- // the second attempt is needed because some images or videos are loaded after the first attempt
- setTimeout(() => {
- start(element);
- }, 10000);
- });
- const querySelectorPathArticleRoot =
- ".article_full_contents .article_content";
- const querySelectorArticleContentWrapper = ".article_tile_content_wraper";
- const querySelectorArticleFooter = ".article_tile_footer";
- document.head.insertAdjacentHTML("beforeend", `
- <style>
- .tm_dynamic_height {
- height: auto !important;
- }
- .tm_remove_position_setting {
- position: unset !important;
- }
- </style>`);
- /**
- *
- * @param {Node} node
- */
- function start(node) {
- /**
- * @type {Node & HTMLDivElement}
- */
- // @ts-ignore
- const element = node;
- if (
- element?.hasChildNodes() &&
- element?.id?.includes("article_") &&
- element?.classList.contains("ar") &&
- !element?.classList.contains("tm_dynamic_height")
- ) {
- // @ts-ignore
- const cardWidth = element.clientWidth ?? element.offsetWidth ?? element.scrollWidth;
- // @ts-ignore
- const cardHeight = element.clientHeight ?? element.offsetHeight ?? element.scrollHeight;
- // 1. Set card height dynamic
- setDynamicHeight(element);
- // 2. Set cotnent wrapper height dynamic
- const articleContentWrapperElement = element.querySelector(
- querySelectorArticleContentWrapper
- );
- if (articleContentWrapperElement) {
- setDynamicHeight(articleContentWrapperElement);
- }
- // 3. Remove position setting from article footer
- const articleFooter = element.querySelector(
- querySelectorArticleFooter
- );
- if (articleFooter) {
- removePositionSetting(articleFooter);
- }
- // 4. Find image height
- /**
- * @type {HTMLDivElement | null}
- */
- const divImageElement = element.querySelector(
- "a[href] > .article_tile_picture[style*='background-image']"
- );
- if (!divImageElement) {
- return;
- }
- const imageUrl = getImageLink(divImageElement);
- if (!imageUrl) {
- return;
- }
- const dimensions = getImageDimensions(imageUrl);
- // 5. Set image height (and - automatically - the card height)
- dimensions.then(([width, height]) => {
- if (height > 0) {
- const calculatedHeight = Math.round(
- (cardWidth / width) * height
- );
- const pictureOldHeight =
- (divImageElement.clientHeight ??
- divImageElement.offsetHeight ??
- divImageElement.scrollHeight) ||
- cardHeight;
- /**
- * @type {HTMLDivElement}
- */
- // @ts-ignore
- const div = divImageElement;
- if (calculatedHeight > pictureOldHeight) {
- div.style.height = `${calculatedHeight}px`;
- }
- // 5.1. Set card class to `.tm_dynamic_height` to not process it again next time
- element.classList?.add("tm_dynamic_height");
- }
- });
- }
- }
- /**
- *
- * @param {Element} element
- * @returns {void}
- */
- function setDynamicHeight(element) {
- element.classList?.add("tm_dynamic_height");
- }
- /**
- *
- * @param {Element} element
- * @returns {void}
- */
- function removeDynamicHeight(element) {
- const div = element.querySelector("img");
- if (!div) {
- return;
- }
- div.classList?.remove("tm_dynamic_height");
- }
- /**
- *
- * @param {Element} element
- * @returns {void}
- */
- function removePositionSetting(element) {
- element.classList?.add("tm_remove_position_setting");
- }
- /**
- *
- * @param {Element} element
- * @returns {void}
- */
- function restorePositionSetting(element) {
- element.classList?.remove("tm_remove_position_setting");
- }
- /**
- *
- * @param {HTMLDivElement} div
- * @returns {string | null}
- */
- function getImageLink(div) {
- const backgroundImageUrl = div?.style.backgroundImage;
- /**
- * @type {string | undefined}
- */
- let imageUrl;
- try {
- imageUrl = backgroundImageUrl?.match(/url\("(.*)"\)/)?.[1];
- } catch (error) {
- imageUrl = backgroundImageUrl?.slice(5, -2);
- }
- if (!imageUrl || imageUrl == "undefined") {
- return null;
- }
- if (!imageUrl?.startsWith("http")) {
- console.error(
- `The image could not be parsed. Image URL: ${imageUrl}`
- );
- return null;
- }
- return imageUrl;
- }
- /**
- *
- * @param {string} url
- * @returns {Promise<[number, number]>}
- */
- async function getImageDimensions(url) {
- const img = new Image();
- img.src = url;
- try {
- await img.decode();
- } catch (error) {
- return Promise.reject(error);
- }
- return Promise.resolve([img.width, img.height]);
- };
- })();