// ==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==
/* eslint security/detect-object-injection: "off" */
(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();
}
})();