// ==UserScript==
// @name Pinterest Palooza
// @description Visit a Pin's source web site by clicking the Pin's thumbnail image. Easy peasy!
// @author Corey Meredith
// @version 1.1.4
// @include http://*pinterest.com/*
// @include https://*pinterest.com/*
// @history 1.1.4 leveraging local navigation link for faster source article access
// @history 1.1.3 fixed script ... Pinterest changed a class name
// @history 1.1.2 only writing to new window for webkit before setting location
// @history 1.1.1 fixed pin selector
// @history 1.1.0 made entire pin image clickable
// @history 1.0.3 replaced loading text with throbber
// @history 1.0.2 moved code into IIFE
// @history 1.0.1 changed button from "Visit Source" to "Visit Site" and matched icon of same button on pin details page
// @history 1.0.0 initial release
// @namespace https://greasyfork.org/users/2306
// @downloadURL https://update.greasyfork.icu/scripts/3075/Pinterest%20Palooza.user.js
// @updateURL https://update.greasyfork.icu/scripts/3075/Pinterest%20Palooza.meta.js
// ==/UserScript==
(function () {
function addVisitButton(e) {
e.preventDefault();
e.cancelBubble = true;
var pin = this,
buttonWrapperN = pin.getElementsByClassName('leftSideButtonsWrapper'),
pinLinkN = pin.querySelectorAll('A.pinImageWrapper'),
navLinkN = pin.querySelectorAll('A.NavigateButton');
if (!buttonWrapperN.length || !pinLinkN.length)
return;
var buttonWrapper = buttonWrapperN[0],
pinLink = pinLinkN[0];
if (buttonWrapper.getElementsByClassName('sourceLaunchButton').length) // already wired up this pin
return;
var href = window.location.origin + pinLink.getAttribute('href'),
btn = document.createElement('a');
btn.style.cssText = 'display: inline-block; margin-left: 4px;';
btn.className = 'rounded Button likeSmall btn hasText sourceLaunchButton';
btn.innerHTML = '...';
btn.setAttribute('title', 'View Pin Details Page');
btn.href = pinLink.getAttribute('href');
buttonWrapper.appendChild(btn);
pinLink.setAttribute('data-original-href', pinLink.getAttribute('href'));
pinLink.setAttribute('href', '#view');
if (navLinkN.length) {
var navLink = navLinkN[0],
navHref = navLink.getAttribute('href');
if (navHref && navHref.length)
pinLink.setAttribute('data-href', navHref);
}
pinLink.addEventListener('click', function (e) {
e.preventDefault();
var pinLink = this,
dataHref = pinLink.getAttribute('data-href');
if (dataHref && dataHref.length) {
if (dataHref == 'nolink')
window.location = window.location.origin + pinLink.getAttribute('data-original-href');
else
window.open(dataHref);
}
else {
var xhr = new XMLHttpRequest(),
w = window.open();
if (typeof navigator.webkitPersistentStorage === 'object' || /WebKit/.test(navigator.userAgent))
w.document.write('
');
xhr.open('GET', href);
xhr.onload = function () {
var container = document.implementation.createHTMLDocument().documentElement;
container.innerHTML = this.responseText;
var sourceLinks = container.querySelectorAll('.richPinNameLink, .paddedPinLink');
if (sourceLinks.length) {
var sourceHref = sourceLinks[0].getAttribute('href');
if (sourceHref && sourceHref.length) {
pinLink.setAttribute('data-href', sourceHref);
w.location = sourceHref;
}
else {
pinLink.setAttribute('title', 'View Pin Details Page');
pinLink.setAttribute('data-href', 'nolink');
pinLink.className += ' no-link';
}
}
}
xhr.send();
}
return false;
}, false);
}
function liveWrapper(selector, method) {
return function(e) {
var target = e.target,
ancestors = getAncestors(target),
i = 0,
l = ancestors.length,
elem;
while (i < l) {
elem = ancestors[i];
if (matches(elem, selector)) {
method.call(elem, e);
break;
}
i += 1;
}
};
}
function getAncestors(elm) {
var bucket = [];
do {
bucket[bucket.length] = elm;
elm = elm.parentNode;
} while (elm);
return bucket;
}
function matches(elm, selectors) {
var possibles = document.querySelectorAll(selectors),
i = possibles.length;
while (i) {
i -= 1;
if (elm === possibles[i])
return true;
}
}
function addStyle(style) {
var head = document.getElementsByTagName('HEAD')[0],
elementStyle = head.appendChild(document.createElement('style'));
elementStyle.innerHTML = style;
}
addStyle('.Pin.summary .pinImageWrapper { cursor: pointer !important; } .Pin.summary .pinImageWrapper.no-link { cursor: zoom-in !important; }');
document.addEventListener('mouseover', liveWrapper('.Pin', addVisitButton), false);
})();