As8D (Message Wall | contribs) m (Fix domain change.) |
As8D (Message Wall | contribs) m (Attempt at allowing nested tabbers for item tooltips.) |
||
Line 54: | Line 54: | ||
}); |
}); |
||
updatePosition(); |
updatePosition(); |
||
+ | } |
||
+ | |||
+ | // Measurement to avoid mess-up for our jQuery selector statement, as it's influenced by user input. |
||
+ | function escapeHtml(unsafe) { |
||
+ | return unsafe |
||
+ | .replace(/&/g, "&") |
||
+ | .replace(/</g, "<") |
||
+ | .replace(/>/g, ">") |
||
+ | .replace(/"/g, """) |
||
+ | .replace(/\\/g, "") |
||
+ | .replace(/'/g, "'"); |
||
} |
} |
||
Line 67: | Line 78: | ||
$.get("https://fantastic-frontier-roblox.fandom.com/wiki/" + article, function(domString) { |
$.get("https://fantastic-frontier-roblox.fandom.com/wiki/" + article, function(domString) { |
||
var dom = $(domString); |
var dom = $(domString); |
||
− | + | var queryParts = article.split("#"); |
|
− | + | ||
+ | // We're showing information from the first infobox in the tooltip. |
||
+ | var infobox = $(dom.find(".portable-infobox")); |
||
+ | |||
+ | if (queryParts.length > 1) { // URL has anchor, look for the right infobox. |
||
+ | var currentTabber = $("#WikiaArticle>div"); |
||
+ | var anchorParts = queryParts[1].split("-"); |
||
+ | for (var i = 0; i < anchorParts.length; i++) { |
||
+ | var newTabber = $(currentTabber.find(">.tabber>.tabbertab[title='" + escapeHtml(anchorParts[i]) + "']")); |
||
+ | if (newTabber.length > 0) { |
||
+ | currentTabber = newTabber; |
||
+ | } |
||
+ | } |
||
+ | // If our nested tabbers contains any infobox, we'll use that over the first one one the page. |
||
+ | if ($(currentTabber.find(".portable-infobox")).length > 0) { |
||
+ | infobox = $(currentTabber.find(".portable-infobox")); |
||
+ | } |
||
+ | } |
||
+ | |||
if (infobox.length > 0) { |
if (infobox.length > 0) { |
||
+ | infobox = $(infobox[0]); |
||
cache[article] = infobox; |
cache[article] = infobox; |
||
if (hovered_article == article) |
if (hovered_article == article) |
Revision as of 02:42, 25 January 2019
$(function() {
// This element is placed at the bottom of the page. It serves as a tooltip for showing article info on hover.
var tooltip = $("<div id=\"item-tooltip\"></div>");
// Cache for already-checked items, to save resources.
var cache = {};
// To properly load the tooltip when the user changes focus quickly.
var hovered_article = null;
// For positioning the tooltip.
var lastX = 0, lastY = 0;
function updatePosition() {
tooltip.css({
"left": Math.min(wind.width() - tooltip.width() - 35, lastX + 10),
"top": Math.min(wind.height() - tooltip.height() - 35, lastY + 50)
});
}
// Generates a section of key-value pairs to the tooltip.
function generateSection(sec, items) {
for (var i = 0; i < items.length; i++) {
var item = $("<div class=\"it-infoitem\"><span class=\"it-infoitem-key\"></span><span class=\"it-infoitem-val\"></span></div>");
var current = $(items[i]);
item.find(".it-infoitem-key").text(current.find(".pi-data-label").text());
item.find(".it-infoitem-val").html(current.find(".pi-data-value").html()); // To allow for listing.
sec.append(item);
}
}
// Updates the DOM for our tooltip element using the found data.
function setTooltip(data) {
tooltip.html("<div class=\"it-header\"><img/><div class=\"it-title\">-</div></div>");
tooltip.find(".it-title").text(data.find(".pi-title").text());
tooltip.find(".it-header img").attr("src", data.find(".pi-image img").attr("src"));
if (data.find(".pi-image .pi-caption").length > 0)
tooltip.append($("<div class=\"it-infobox it-desc\"></div>").text(data.find(".pi-image .pi-caption").text()));
var dsec = data.find("section, >.pi-data");
for (var i = 0; i < dsec.length; i++) {
var csec = $(dsec[i]);
var sec = $("<div class=\"it-infobox\"></div>");
if (csec.is("section")) {
var ibTitle = csec.find(".pi-header"); // Collapsible sections can have titles.
if (ibTitle.length > 0)
tooltip.append($("<div class=\"it-infobox-title\"></div>").text(ibTitle.text()));
generateSection(sec, csec.find(".pi-data"));
} else
generateSection(sec, csec);
tooltip.append(sec);
}
tooltip.show();
tooltip.find(".it-infobox").each(function() {
if (this.offsetHeight < this.scrollHeight)
sec.addClass("overflow"); // Applies some overflow-look through pseudoclasses.
});
updatePosition();
}
// Measurement to avoid mess-up for our jQuery selector statement, as it's influenced by user input.
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/\\/g, "")
.replace(/'/g, "'");
}
// Checks if we have cached data on the article, and loads/sets accordingly.
function updateTooltip(article) {
tooltip.hide();
hovered_article = article;
if (article in cache) {
if (cache[article] !== false) {
setTooltip(cache[article]); // The article data was cached, load it.
}
} else { // The article wasn't found in cache, pull it.
$.get("https://fantastic-frontier-roblox.fandom.com/wiki/" + article, function(domString) {
var dom = $(domString);
var queryParts = article.split("#");
// We're showing information from the first infobox in the tooltip.
var infobox = $(dom.find(".portable-infobox"));
if (queryParts.length > 1) { // URL has anchor, look for the right infobox.
var currentTabber = $("#WikiaArticle>div");
var anchorParts = queryParts[1].split("-");
for (var i = 0; i < anchorParts.length; i++) {
var newTabber = $(currentTabber.find(">.tabber>.tabbertab[title='" + escapeHtml(anchorParts[i]) + "']"));
if (newTabber.length > 0) {
currentTabber = newTabber;
}
}
// If our nested tabbers contains any infobox, we'll use that over the first one one the page.
if ($(currentTabber.find(".portable-infobox")).length > 0) {
infobox = $(currentTabber.find(".portable-infobox"));
}
}
if (infobox.length > 0) {
infobox = $(infobox[0]);
cache[article] = infobox;
if (hovered_article == article)
setTooltip(infobox);
} else {
// No infobox, so we'll mark this article as not having a tooltip.
cache[article] = false;
}
});
}
}
// Assigns hover-logic for an element to display tooltips.
function setupElement(elem) {
var article = elem.is("div") ? elem.attr("data-article") : elem.attr("href").substr(6); // Trim away /wiki/.
elem.hover(function() {
updateTooltip(article);
}, function() {
tooltip.hide();
hovered_article = null;
});
}
// Hook up tooltips to wiki links.
$("#WikiaArticle a[href^='/wiki/'], #WikiaArticle .tooltip-linker").each(function() {
setupElement($(this));
});
// Initialize.
tooltip.hide();
$(document.body).append(tooltip);
var wind = $(window);
// Follow the cursor.
$(document).on('mousemove', function(e){
lastX = e.clientX;
lastY = e.clientY;
updatePosition();
});
});