AuthorTodayImprover

The script allows you to select text and use the context menu when reading a book.

目前為 2022-12-25 提交的版本,檢視 最新版本

// ==UserScript==
// @name           AuthorTodayImprover
// @name:ru        AuthorTodayImprover
// @namespace      90h.yy.zz
// @version        0.1.0
// @author         Ox90
// @include        https://author.today/reader/*
// @description    The script allows you to select text and use the context menu when reading a book.
// @description:ru Скрипт возвращает возможность выделять текст и использовать контекстное меню при чтении на сайте.
// @run-at         document-start
// @license        MIT
// ==/UserScript==

(function start() {
	"use strict";

/**
 * Старт скрипта. Вызывается после загрузки DOM-дерева.
 *
 * @return void
 */
function start() {
	[ "#reader.page-content", "div.text-wrapper" ].forEach(function(selector) {
		const el = document.querySelector(selector);
		el && processElement(el);
	});
}

/**
 * Обрабатывает переданный DOM-элемент.
 * Если у элемента нет класса loading, то он обрабатывается немедленно,
 * в ином случае на него вешается наблюдатель, а обратотка откладывается.
 *
 * @param Element el Обрабатываемый DOM-элемент
 *
 * @return void
 */
function processElement(el) {
	if (!el.classList.contains("loading")) {
		fixStyles(removeEvents(el));
		return;
	}
	(new MutationObserver(function(mutations, observer) {
		observer.disconnect();
		processElement(el);
	})).observe(el, { attributes: true });
}

/**
 * Подменяет переданный элемент новым, который создается через копирование всех его детей и атрибутов,
 * при этом удаляются ненужные для пользователя атрибуты, блокирующие привычную функциональность.
 * el.cloneNode(true) здесь не используется, чтобы избежать потери обработчиков у вложенных элементов.
 *
 * @param Element el DOM-элемент для замены
 *
 * @return Element Вновь созданный элемент
 */
function removeEvents(el) {
	const evil_attributes = [
		"oncontextmenu", "onmousedown", "onselectstart", "unselectable"
	];

	const new_el = document.createElement(el.tagName);
	for (let attr of el.attributes) {
		if (!evil_attributes.includes(attr.name)) {
			new_el.setAttribute(attr.name, attr.value);
		}
	}
	while (el.childNodes[0]) {
		new_el.appendChild(el.childNodes[0]);
	}
	el.replaceWith(new_el);
	return new_el;
}

/**
 * Исправляет стили элемента таким образом, чтобы они не блокировали привычную для пользователя функциональность.
 *
 * @param Element el DOM-элемент для исравления
 *
 * @return void
 */
function fixStyles(el) {
	el.classList.remove("noselect");
	el.style.userSelect = "text";
}

//----------

if (document.readyState === "loading")
	window.addEventListener("DOMContentLoaded", start);
else
	start();

}());

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址