Github Image Viewer

Preview images from within the listing.

Verze ze dne 01. 02. 2024. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

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

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

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

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name            Github Image Viewer
// @id              Github_Image_Viewer@https://github.com/jerone/UserScripts
// @namespace       https://github.com/jerone/UserScripts
// @description     Preview images from within the listing.
// @author          jerone
// @copyright       2014+, jerone (https://github.com/jerone)
// @license         CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
// @license         GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// @homepage        https://github.com/jerone/UserScripts/tree/master/Github_Image_Viewer
// @homepageURL     https://github.com/jerone/UserScripts/tree/master/Github_Image_Viewer
// @supportURL      https://github.com/jerone/UserScripts/issues
// @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VCYMHWQ7ZMBKW
// @version         0.5.0
// @icon            https://github.githubassets.com/pinned-octocat.svg
// @grant           none
// @run-at          document-end
// @include         https://github.com/*
// ==/UserScript==

(function() {

	String.format = function(string) {
		var args = Array.prototype.slice.call(arguments, 1, arguments.length);
		return string.replace(/{(\d+)}/g, function(match, number) {
			return typeof args[number] !== "undefined" ? args[number] : match;
		});
	};

	function proxy(fn) {
		return function() {
			var that = this;
			return function(e) {
				var args = that.slice(0);  // clone;
				args.unshift(e);  // prepend event;
				fn.apply(this, args);
			};
		}.call([].slice.call(arguments, 1));
	}

	var GithubImageViewer = {
		_floater: null,
		_floaterTitle: null,
		_floaterImage: null,
		_floaterMeta: null,

		_imageUrl: null,
		_loaderSrc: "https://github.githubassets.com/images/spinners/octocat-spinner-32.gif",
		_imageRegex: /.+(\.jpe?g|\.png|\.gif|\.bmp|\.ico|\.tiff?)$/i,

		Initialize: function() {
			var floater = GithubImageViewer._floater = document.createElement("div");
			floater.style.position = "absolute";
			floater.style.top = "0";
			floater.style.left = "0";
			floater.style.zIndex = "999";
			document.body.appendChild(floater);

			var floaterMouseAlign = document.createElement("div");
			floaterMouseAlign.style.position = "absolute";
			floaterMouseAlign.style.bottom = "5px";
			floaterMouseAlign.style.left = "5px";
			floaterMouseAlign.style.border = "1px solid #b7c7cf";
			floaterMouseAlign.style.borderRadius = "3px";
			floaterMouseAlign.style.fontSize = "11px";
			floater.appendChild(floaterMouseAlign);

			var floaterTitle = GithubImageViewer._floaterTitle = document.createElement("div");
			floaterTitle.style.backgroundColor = "#e6f1f6";
      		floaterTitle.style.color = "black";
			floaterTitle.style.textAlign = "center";
			floaterTitle.style.borderBottom = "1px solid #d8e6ec";
			floaterTitle.style.padding = "3px 5px";
			floaterMouseAlign.appendChild(floaterTitle);

			var floaterCenter = document.createElement("div");
			floaterCenter.style.minWidth = "40px";
			floaterCenter.style.minHeight = "40px";
			floaterCenter.style.display = "flex";
			floaterCenter.style.flexDirection = "column";
			floaterCenter.style.backgroundColor = "#f8f8f8";
			floaterCenter.style.padding = "3px";
			floaterMouseAlign.appendChild(floaterCenter);

			var floaterImage = GithubImageViewer._floaterImage = document.createElement("img");
			floaterImage.setAttribute("src", GithubImageViewer._loaderSrc);
			floaterImage.style.margin = "auto";
			floaterImage.style.maxWidth = floaterImage.style.maxHeight = "200px";
			floaterCenter.appendChild(floaterImage);

			var floaterMeta = GithubImageViewer._floaterMeta = document.createElement("div");
			floaterMeta.style.backgroundColor = "#f8f8f8";
      		floaterMeta.style.color = "black";
			floaterMeta.style.padding = "3px";
			floaterMeta.style.textAlign = "center";
			floaterMeta.style.whiteSpace = "nowrap";
			floaterMouseAlign.appendChild(floaterMeta);
			GithubImageViewer.SetMeta();

			GithubImageViewer.Attach();
		},

		Attach: function() {
			document.getElementById("js-repo-pjax-container").addEventListener("mousemove", function(e) {
				var target = e.target;
				if (target.classList && target.classList.contains("js-navigation-open") &&
					GithubImageViewer._imageRegex.test(target.href)) {

					if (target.getAttribute("title")) {
						target.dataset.title = target.getAttribute("title");
						target.removeAttribute("title");
					}

					if (GithubImageViewer._visible) {
						GithubImageViewer.Show(e.pageX, e.pageY);
					} else {
						GithubImageViewer.AddTimer(proxy(function() {
							GithubImageViewer.ClearTimers();

							GithubImageViewer.Show(e.pageX, e.pageY);

							var href = target.href;
							if (GithubImageViewer._imageUrl !== href) {
								GithubImageViewer._imageUrl = href;
								GithubImageViewer.SetImage(GithubImageViewer._imageUrl);

								GithubImageViewer.SetTitle(target.dataset.title);
							}
						}));
					}
				} else {
					GithubImageViewer.Dispose();
				}
			});
			document.body.addEventListener("click", function() {
				GithubImageViewer.Dispose();
			});
			document.body.addEventListener("contextmenu", function() {
				GithubImageViewer.Dispose();
			});
			document.body.addEventListener("keydown", function(e) {
				if (e.keyCode === 27) {
					GithubImageViewer.Dispose();
				}
			});
		},

		_visible: false,
		Show: function(x, y) {
			GithubImageViewer._visible = true;
			GithubImageViewer._floater.style.left = x + "px";
			GithubImageViewer._floater.style.top = y + "px";
		},
		Hide: function() {
			GithubImageViewer._visible = false;
			GithubImageViewer._floater.style.left = "-1000px";
			GithubImageViewer._floater.style.top = "-1000px";
		},

		Dispose: function() {
			GithubImageViewer.ClearTimers();

			GithubImageViewer.Hide();

			GithubImageViewer._imageUrl = GithubImageViewer._loaderSrc;
			GithubImageViewer.SetImage(GithubImageViewer._imageUrl);

			GithubImageViewer.SetTitle("Loading...");
		},

		_timers: [],
		_timeout: 700,
		AddTimer: function(fn) {
			GithubImageViewer._timers.push(window.setTimeout(fn, GithubImageViewer._timeout));
		},
		ClearTimers: function() {
			Array.prototype.forEach.call(GithubImageViewer._timers, function(timer) {
				window.clearTimeout(timer);
			});
		},

		SetTitle: function(text) {
			GithubImageViewer._floaterTitle.textContent = text;
		},

		SetImage: function(src) {
			src = src.replace("/blob/", "/raw/");
			if (src !== GithubImageViewer._loaderSrc) {
				var temp = document.createElement("img");
				temp.style.visibility = "hidden";
				temp.addEventListener("load", function() {
					GithubImageViewer.SetMeta(this.width, this.height);
					this.parentNode.removeChild(temp);
				});
				temp.setAttribute("src", src);
				document.body.appendChild(temp);
			} else {
				GithubImageViewer.SetMeta();
			}

			GithubImageViewer._floaterImage.setAttribute("src", src);
		},

		SetMeta: function(w, h) {
			if (!w && !h) {
				GithubImageViewer._floaterMeta.style.display = "none";
			} else {
				GithubImageViewer._floaterMeta.style.display = "block";
				GithubImageViewer._floaterMeta.innerHTML = String.format("<strong>W:</strong> {0}px | <strong>H:</strong> {1}px", w, h);
			}
		}
	};

	if (document.getElementById("js-repo-pjax-container")) {
		GithubImageViewer.Initialize();
	}

})();