Draggable Reference Line

Designed for reading long articles, it helps remember the current reading progress.

Verzia zo dňa 13.09.2021. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Draggable Reference Line
// @description  Designed for reading long articles, it helps remember the current reading progress.
// @version      1.0
// @author       Rui LIU (@liurui39660)
// @match        *://*/*
// @icon         https://icons.duckduckgo.com/ip2/example.com.ico
// @run-at       document-body
// @namespace https://greasyfork.org/users/193469
// ==/UserScript==

(function () {
	'use strict';

	const height = 2; // px, height of the visible line
	const padding = 2; // px, additional draggable area above and below the line, not the sum of them
	const color = 'red'; // or #-string

	const initPos = -padding - height / 2;
	const body = document.getElementsByTagName('body')[0];
	const line = document.createElement('div');
	line.textContent = '#DraggableReferenceLine';
	line.style = `margin: 0; padding: ${padding}px 0; cursor: n-resize; font-size: 0; color: #fff0; background: ${color}; background-clip: content-box; width: 100vw; height: ${height}px; position: absolute; top: ${localStorage[`DraggableLine_${window.location.pathname}${window.location.search}`] || initPos}px; z-index: 10;`;

	const reset = () => {
		line.style.top = `${initPos}px`;
		localStorage.removeItem(`DraggableLine_${window.location.pathname}${window.location.search}`);
	}
	const set = top => {
		line.style.top = `${top}px`;
		localStorage[`DraggableLine_${window.location.pathname}${window.location.search}`] = top;
	}
	let callbackMouseMove = ev => {
		line.style.top = `${ev.pageY + initPos}px`; // initPos is also the offset to line center
	};
	let callbackMouseUp = ev => {
		if (ev.detail === 1) { // Don't overwrite dblclick
			body.releasePointerCapture(ev.pointerId);
			body.style.cursor = null;
			const top = parseFloat(line.style.top);
			top > initPos ? set(top) : reset();
			[onmouseup, onmousemove, callbackMouseUp, callbackMouseMove] = [callbackMouseUp, callbackMouseMove, onmouseup, onmousemove];
		}
	};
	line.addEventListener('mousedown', ev => {
		if (ev.detail === 1) {
			ev.preventDefault(); // Don't select text
			body.setPointerCapture(ev.pointerId); // The cursor won't change back to pointer when out of browser
			body.style.cursor = 'n-resize';
			[onmouseup, onmousemove, callbackMouseUp, callbackMouseMove] = [callbackMouseUp, callbackMouseMove, onmouseup, onmousemove];
		}
	});
	line.addEventListener('dblclick', reset);
	body.appendChild(line);
})();