Skip to content

Instantly share code, notes, and snippets.

@dergachev
Last active December 11, 2015 04:58
Show Gist options
  • Save dergachev/4548565 to your computer and use it in GitHub Desktop.
Save dergachev/4548565 to your computer and use it in GitHub Desktop.
pin-screenshot.bookmarklet.js

Pin Screenshot bookmarklet

The Pin Screenshot bookmarklet allows you to post a screenshot of the current page to Pinterest. Requires own screenshot tool, such as github.com/dergachev/copy-public-url.

Placeholder screenshot:

Screenshot

Installation

To install, visit http://bl.ocks.org/d/4548565

Developing

# consider forking this gist
git clone https://gist.github.com/4548565.git pin-screenshot
cd pin-screenshot
python -m SimpleHTTPServer 9092 # serves http://localhost:9092/index.html

Dev Notes

pinterest blocks dl-web.dropbox.com

I noticed that pinterest blocks pinning any images on the domain dl-web.dropbox.com, which is a problem as copy-public-url tool uploads them to dl-web.dropbox.com.

https://support.pinterest.com/entries/21436306-why-is-my-pin-or-site-blocked-for-spam-or-inappropriate-content/

Possible workarounds:

  • in the JS, run s/dl-web.dropbox.com/107.20.134.231/
  • This is what is currently implemented.
  • hardcodes the IP address (currently 107.20.134.231) that dl-web.dropbox.com resolves to.
  • Will break when/if dropbox changes AWS servers (might do so very soon)
  • requires that dl-web.dropbox.com servers dont care about HOST http header (true for now)
  • Unfortunately there's no JS method for DNS resolution, but can use webservice
  • create a proxy service (dl-web-dropbox-com-proxy.appengine.com) that proxies to dl-web.dropbox.com.
  • robust but expensive on bandwidth; free might run over quota
  • create DNS subdomain as follows: dl-web-dropbox-com-cname.freedns.org
  • jsonp to a URL shortener with jsonp API

Other Resources

Pretty webpages to screenshot

Just in case you need some inspiration:

.button-wrapper {
margin: 2em 0;
}
.inline-button,
.button {
/* base64 encoder: http://www.greywyvern.com/code/php/binary2base64 */
/* Source image: http://tiny.cc/public/images/default-favicon.ico */
background-image: url(data:image/vnd.microsoft.icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAA+/v8APn3+QCeTWQAcmh+APj5+gBVKksA9/X3APb29gD08vMA9/j5APT09gD7/PwA8/HyAPPz9QD6+/sA9fP1AGcwWQDy8vQAOB07APn6+gD49vcA2eryAPX19gCckqgA8/HzAPb19gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMTExMTExMTExMTExMAAAAGDQ0NDQ0NDQ0NDQ0GAAAAERkZGRkZGRkZGRkZEQAAAAMJCQkJCQkJCQkJCQMAAAADEg4SDhISEg4ODg4DAAAAAxAQEBAQEBAQEBAQAwAAAAMaGhoaGhoLFxcXGgMAAAADBwcHBwcHBwcHBwcDAAAAAxUVFRUVFRUVFRUVAwAAAAMCAgICAgICAgICAgMAAAAECgUKBQoKCgUWFhYEAAAABAUUBRQFBQUYGBgYBAAAAAQUDxQPFBQUGAgIFhgAAAAEDwEPAQ8PDxgIFhgAAAAABAEMAQwBAQEYFhgAAAAAABgYGBgYGBgYGBgAAAAAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACABwAAgA8AAIAfAAA=);
background-repeat: no-repeat;
background-color: #65a9d7;
background-position: 10px center;
padding: 10px 20px 10px 32px;
border-radius: 8px;
color: white;
font-size: 18px;
font-family: 'Lucida Grande', Helvetica, Arial, Sans-Serif;
text-decoration: none;
}
.inline-button {
display: inline;
background-color: transparent;
padding-right: 3px;
padding-left: 28px;
font-size: 1em;
background-size: 13px 13px;
}
.inline-button a {
text-decoration: none;
color: #65a9d7;
}
body {
padding: 20px;
font-family: Helvetica, Arial, sans-serif;
font-size: .9em;
color: #444;
}
p {
line-height: 1.5em;
margin: .5em 0 1em 0;
}
ul {
line-height: 1.2em;
padding-left: 1.5em;
}
<html>
<head>
<title>Pin Screenshot bookmarklet</title>
<link rel="stylesheet" href="demo.css" type="text/css" />
</head>
<body>
<section data-markdown>
# Pinterest Screenshot bookmarklet
The __Pinterest Screenshot__ bookmarklet allows you to post a screenshot of the current page to Pinterest.
It requires own screenshot tool, such as github.com/dergachev/copy-public-url.
To install the bookmarklet, drag this link to your bookmark toolbar:
<div class="button-wrapper"> <a class="button" href="javascript:(function(){var s = document.createElement('script');s.src='https://gist.github.com/raw/4548565/pin-screenshot.bookmarklet.js';document.body.appendChild(s);})();">Pin Screenshot</a> </div>
For development purposes, the following bookmarklet is localhost-only: <span class="inline-button"><a href="javascript:(function(){var s = document.createElement('script');s.src='http://localhost:9092/pin-screenshot.bookmarklet.js';document.body.appendChild(s);})();">Pin Screenshot Localhost</a></span>
## How to use it
* Go to a page you'd whose screenshot you want to pin
* Take screenshot and upload online (perhaps using my github.com/dergachev/copy-public-url)
* Click on the "Pin Screenshot" bookmarklet
* Paste in the screenshot image URL
* Press enter
* Create pin in popup window
![Screenshot for pin-screenshot.bookmarklet.js](http://dl-web.dropbox.com/u/8325927/screenshots/NJTPYR-2013.1.14-14.36.png)
## Get the source code
To get the source code, visit <a href="https://gist.github.com/4548565#pin-screenshot.bookmarklet.js">https://gist.github.com/4548565#pin-screenshot.bookmarklet.js</a>
<a href="https://gist.github.com/4548565#pin-screenshot.bookmarklet.js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub"></a>
</section>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
<script>
// adapted from http://blog.harakys.com/blog/2012/02/21/embed-markdown-into-your-html/
// see also https://gist.github.com/1343518
[].forEach.call( document.querySelectorAll('[data-markdown]'), function fn(elem){
var html = (new Showdown.converter()).makeHtml(elem.innerHTML);
elem.innerHTML = html;
});
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-37659053-1']);
_gaq.push(['_setDomainName', 'ocks.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
function initMyBookmarklet() {
createSimpleDialog("Enter the URL of the screenshot to pin:", function(imageURL) {
if (imageURL) {
imageURL = fixDropboxBlock( imageURL);
createWebsitePin(window.location.href, imageURL);
}
});
}
function createSimpleDialog(question, successHandler) {
var label = jQuery('<label />')
.text(question)
.css({
'padding-top': '30px'
});
var input = jQuery('<input type="text" class="simpleDialogQuestion" />')
.css({
width: '90%',
display: 'block',
padding: '2px',
margin: '10px 0px',
})
.appendTo(label);
var removeDialog = function() {
jQuery('.simpleDialog').remove();
}
var submitButton = jQuery('<input type="image" src="http://passets-cdn.pinterest.com/images/bm/button.png" />')
.css({
border: 'none'
})
.click(function() {
var answer = input.val();
successHandler(answer);
removeDialog();
});
var cancelButton = jQuery('<button type="button">&times;</button>')
.css({
background: 'transparent',
margin: '0',
padding: '0',
cursor: 'pointer',
'font-size': '20px',
color: 'black',
opacity: '.2',
border: 'none',
'text-shadow': '0 1px 0 white',
float: 'right'
})
.click(function() {
removeDialog();
});
var overlay = jQuery('<div class="simpleDialog simpleDialogOverlay" />')
.css({
width: '100%',
height: '100%',
opacity: '.5',
'background-color': 'black',
'z-index': '10000000',
position: 'absolute'
})
.click(removeDialog)
.prependTo('body');
var dialog = jQuery('<div class="simpleDialog"/>')
.append(cancelButton)
.append(label)
.append(submitButton);
// wrap in iframe to protect from page CSS
var iframe = jQuery('<iframe class="simpleDialog" />')
.load(function() {
//populate iframe with dialog
jQuery(this).contents().find('body').append(dialog);
// position cursor on text box;
label.focus(); // note jQuery('.simpleDialogQuestion') fails in iframe
// dismiss on ESC keypress; adapted from http://stackoverflow.com/a/3581056/9621
jQuery(document)
.add( jQuery(this).contents()) // bind to top-level and frame document
.bind('keydown', function(e) {
if (e.which == 27) { removeDialog(); } // escape key
});
})
.css( {
width: '400px',
height: '200px',
left: '50%',
position: 'absolute',
top: '100px',
left: '50%',
'margin-left': '-200px',
border: '1px solid grey',
padding: '10px',
opacity: '1',
'z-index': '10000000',
background: 'white'
})
.insertAfter(overlay);
}
function createWebsitePin(linkURL, imageURL) {
//TODO: optimize title/description
var url = "http://pinterest.com/pin/create/button/"
+ "?url=" + encodeURIComponent(linkURL)
+ "&media=" + encodeURIComponent(imageURL)
+ "&is_video=false"
+ "&title=" + encodeURIComponent("Screenshot of " + linkURL)
+ "&description=" + encodeURIComponent("Screenshot of " + linkURL);
var newWindow = window.open(url, "", "scrollbars=yes,menubar=yes,height=1024,width=1024,resizable=yes,toolbar=yes,location=yes,status=yes");
}
// pinterest blocks images on the dl-web.dropbox.com domain, so workaround
function fixDropboxBlock(imageURL) {
var dropboxHostname = 'http://dl-web.dropbox.com';
var dropboxIp = 'http://107.20.134.231';
// TODO: implement something much more robust than hardcoding the IP
return imageURL.replace(dropboxHostname, dropboxIp);
}
(function(){
var done = false;
var script = document.createElement("script");
script.src = "//cdnjs.cloudflare.com/ajax/libs/yepnope/1.5.4/yepnope.min.js";
script.onload = script.onreadystatechange = function(){
if (!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {
done = true;
requireDeps();
}
};
document.getElementsByTagName("head")[0].appendChild(script);
})();
function requireDeps() {
yepnope([{
test: typeof(window.jQuery) === 'undefined' || jQuery.fn.jquery.match(/^1\.[0-9]+/) <= 1.4,
yep: '//cdnjs.cloudflare.com/ajax/libs/jquery/1.4.4/jquery.min.js',
complete: function (url, result, key) {
initMyBookmarklet();
// TODO: makes our jQuery version not clobber pre-existing one (eg for pinterest)
// jQuery.noConflict(true) doesn't seem to work properly
}
}
]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment