beautifier

自定义页面背景图,布局优化

当前为 2022-08-26 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/450211/1085900/beautifier.js

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

/* eslint-disable no-multi-spaces */
/* eslint-disable no-implicit-globals */
/* eslint-disable userscripts/no-invalid-headers */
/* eslint-disable userscripts/no-invalid-grant */

// ==UserScript==
// @name               beautifier
// @displayname        页面美化
// @namespace          Wenku8++
// @version            0.1.7
// @description        自定义页面背景图,布局优化
// @author             PY-DNG
// @license            GPL-v3
// @regurl             https?://www\.wenku8\.net/.*
// @require            https://greasyfork.org/scripts/449412-basic-functions/code/Basic%20Functions.js?version=1085783
// @require            https://greasyfork.org/scripts/449583-configmanager/code/ConfigManager.js?version=1085898
// @grant              GM_getValue
// @grant              GM_setValue
// @grant              GM_listValues
// @grant              GM_deleteValue
// ==/UserScript==

(function __MAIN__() {
	const settings = require('wk-settings');
	const SettingPanel = require('SettingPanel');

	const CONST = {
		Text: {
			CommonBeautify: '通用页面美化',
			NovelBeautify: '阅读页面美化',
			ReviewBeautify: '书评页面美化',
			Enable: '启用',
			BackgroundImage: '背景图片',
			AlertTitle: '页面美化设置',
			InvalidImageUrl: '图片链接格式错误</br>仅仅接受http/https/data链接',
		},
		ClassName: {
			BgImage: 'plus_cbty_image',
			BgCover: 'plus_cbty_cover',
			CSS: 'plus_beautifier'
		},
		CSS: {
			Common: '.plus_cbty_image {position: fixed;top: 0;left: 0;z-index: -2;}.plus_cbty_cover {position: fixed;top: 0;left: calc((100vw - 960px) / 2);z-Index: -1;background-color: rgba(255,255,255,0.7);width: 960px;height: 100vh;}body {overflow: auto;}body>.main {position: relative;margin-left: 0;margin-right: 0;left: calc((100vw - 960px) / 2);}body.plus_cbty table.grid td, body.plus_cbty .odd, body.plus_cbty .even, body.plus_cbty .blockcontent {background-color: rgba(255,255,255,0) !important;}.textarea, .text {background-color: rgba(255,255,255,0.9);}#headlink{background-color: rgba(255,255,255,0.7);}',
			Novel: 'html{background-image: url({BGI});}body {width: 100vw;height: 100vh;overflow: overlay;margin: 0px;background-color: rgba(255,255,255,0.7);}#contentmain {overflow-y: auto;height: calc(100vh - {H});max-width: 100%;min-width: 0px;max-width: 100vw;}#adv1, #adtop, #headlink, #footlink, #adbottom {overflow: overlay;min-width: 0px;max-width: 100vw;}#adv900, #adv5 {max-width: 100vw;}'
		},
		Config_Ruleset: {
			'version-key': 'config-version',
			'ignores': ["LOCAL-CDN"],
			'defaultValues': {
				//'config-key': {},
				common: {
					enable: false,
					image: null
				},
				novel: {
					enable: false,
					image: null
				},
				review: {
					enable: false,
					image: null
				},
				image: null
			},
			'updaters': {
				/*'config-key': [
					function() {
						// This function contains updater for config['config-key'] from v0 to v1
					},
					function() {
						// This function contains updater for config['config-key'] from v1 to v2
					}
				]*/
			}
		}
	};

	const CM = new ConfigManager(CONST.Config_Ruleset);
	const CONFIG = CM.Config;
	CM.setDefaults();
	const API = getAPI();
	switch (API[0]) {
		case 'novel':
			[...API].pop() !== 'index.htm' && CONFIG.novel.enabled && novel();
			break;
		default:
			CONFIG.common.enabled && common();
	}
	settings.registerSettings(MODULE_IDENTIFIER, setter);

	exports = {
		//
	};

    // Beautifier for all wenku pages
	function common() {
		const src = CONFIG.common.image || CONFIG.image;

		const img = $CrE('img');
		img.src = src;
		img.classList.add(CONST.ClassName.BgImage);
		document.body.appendChild(img);

		const cover = $CrE('div');
		cover.classList.add(CONST.ClassName.BgCover);
		document.body.appendChild(cover);

		document.body.classList.add('plus_cbty');
		addStyle(CONST.CSS.Common, CONST.ClassName.CSS);
		return true;
	}

	// Novel reading page
	function novel() {
		const src = CONFIG.novel.image || CONFIG.image;
		const config = CONFIG.BeautifierCfg.getConfig();
		const usedHeight = getRestHeight();

		addStyle(CONST.CSS.Novel
				 .replaceAll('{BGI}', src)
				 .replaceAll('{H}', usedHeight), CONST.ClassName.CSS
				);

		unsafeWindow.scrolling = beautiful_scrolling;

		// Get rest height without #contentmain
		function getRestHeight() {
			let usedHeight = 0;
			['adv1', 'adtop', 'headlink', 'footlink', 'adbottom'].forEach((id) => {
				const node = $('#'+id);
				if (node instanceof Element && node.id !== 'contentmain') {
					const cs = getComputedStyle(node);
					['height', 'marginTop', 'marginBottom', 'paddingTop', 'paddingBottom', 'borderTop', 'borderBottom'].forEach((style) => {
						const reg = cs[style].match(/([\.\d]+)px/);
						reg && (usedHeight += Number(reg[1]));
					});
				};
			});
			usedHeight = usedHeight.toString() + 'px';
			return usedHeight;
		}

		// Mouse dblclick scroll with beautifier applied
		function beautiful_scrolling() {
			var contentmain = pageResource.elements.contentmain;
			var currentpos = contentmain.scrollTop || 0;
			contentmain.scrollTo(0, ++currentpos);
			var nowpos = contentmain.scrollTop || 0;
			if(currentpos != nowpos) unsafeWindow.clearInterval(timer);
		}
	}

	// Settings
	function setter() {
		const storage = {
			GM_getValue: GM_getValue,
			GM_setValue: GM_setValue,
			GM_listValues: GM_listValues,
			GM_deleteValue: GM_deleteValue
		};
		const Panel = SettingPanel.SettingPanel;
		const Option = SettingPanel.SettingOption.bind(null, storage);
		const SetPanel = new Panel({
			tables: [{
				rows: [{
					blocks: [{
						isHeader: true,
						colSpan: 2,
						innerText: CONST.Text.CommonBeautify
					}]
				},{
					blocks: [{
						innerText: CONST.Text.Enable
					},{
						options: [new Option({
							path: 'common/enable',
							type: 'boolean'
						})]
					}]
				},{
					blocks: [{
						innerText: CONST.Text.BackgroundImage
					},{
						options: [new Option({
							path: 'common/image',
							type: 'string',
							checker: imageUrlChecker,
						})]
					}]
				}]
			},{
				rows: [{
					blocks: [{
						isHeader: true,
						colSpan: 2,
						innerText: CONST.Text.NovelBeautify
					}]
				},{
					blocks: [{
						innerText: CONST.Text.Enable
					},{
						options: [new Option({
							path: 'novel/enable',
							type: 'boolean'
						})]
					}]
				},{
					blocks: [{
						innerText: CONST.Text.BackgroundImage
					},{
						options: [new Option({
							path: 'novel/image',
							type: 'string',
							checker: imageUrlChecker,
						})]
					}]
				}]
			},{
				rows: [{
					blocks: [{
						isHeader: true,
						colSpan: 2,
						innerText: CONST.Text.ReviewBeautify
					}]
				},{
					blocks: [{
						innerText: CONST.Text.Enable
					},{
						options: [new Option({
							path: 'review/enable',
							type: 'boolean'
						})]
					}]
				},{
					blocks: [{
						innerText: CONST.Text.BackgroundImage
					},{
						options: [new Option({
							path: 'review/image',
							type: 'string',
							checker: imageUrlChecker,
						})]
					}]
				}]
			}]
		});

		function imageUrlChecker(e, value) {
			if (!value.match(/.+:/)) {
				alertify.alert(CONST.Text.AlertTitle, CONST.Text.InvalidImageUrl);
				return false;
			}
			e.target.value = value || null;
			return true;
		}
	}
})();