Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // pinmarketl-special.js
- //
- // Special handling for pinmarklet.
- //
- // The pinmarklet was
- // (a) kludgy. It defined an anonymous script, and a page would need to
- // re-request the JS every time it needed to popup the pinterest
- // interaction form.
- // (b) broken. There were several bugs, including a race condition
- // in the code that tries to determine the natural size of an image.
- // Because of that bug, the pinmarklet form would not show, sometimes.
- // Lame!
- //
- // To fix these things, I modified the code and use it instead. This
- // modified code works for img tags. It does not work with these tags:
- // video embed object.
- //
- // ========================================================
- // Usage:
- //
- // in the html, include the script just once:
- // <script type="text/javascript" src="js/pinmarklet-special.js"></script>
- //
- // also in html, include a pin button:
- // <div id='pagePin'>
- // <img src='http://assets.pinterest.com/images/PinExt.png'/>
- // </div>
- //
- // attach a click event handler to the button, and use this as the handler logic:
- //
- // function pinClick(ev, ix) {
- // PinterestSpecial.popupPinItForm();
- // return false;
- // }
- //
- // ========================================================
- //
- // Dino Chiesa
- //
- // This code is in the Public Domain.
- //
- // Thu, 22 Mar 2012 22:06
- //
- (function(){
- var pinmarkletConfig = {
- idroot: "PIN_" + (new Date()).getTime(),
- checkpoint: {
- url: "//api.pinterest.com/v2/domains/info/"
- },
- pin: "//pinterest.com/pin/create/bookmarklet/",
- minImgSize: 80,
- thumbCellSize: 200,
- check: ["meta", "img"],
- //check: ["meta", "iframe", "embed", "object", "img", "video"],
- urlRegexi: {
- vimeo: /^https?:\/\/.*?\.?vimeo\.com\//,
- facebook: /^https?:\/\/.*?\.?facebook\.com\//,
- googleReader: /^https?:\/\/.*?\.?google\.com\/reader\//,
- pinterest: /^https?:\/\/.*?\.?pinterest\.com\//,
- stumbleUpon: /^https?:\/\/.*?\.?stumbleupon\.com\//
- },
- stumbleFrame: ["tb-stumble-frame", "stumbleFrame"],
- tag: {
- video: {
- youtube: {
- att: "src",
- match: [/videoplayback/]
- }
- },
- embed: {
- youtube: {
- att: "src",
- match: [/^http:\/\/s\.ytimg\.com\/yt/, /^http:\/\/.*?\.?youtube-nocookie\.com\/v/]
- }
- },
- iframe: {
- youtube: {
- att: "src",
- match: [/^http:\/\/www\.youtube\.com\/embed\/([a-zA-Z0-9\-_]+)/]
- },
- vimeo: {
- att: "src",
- match: [/^http?s:\/\/vimeo.com\/(\d+)/, /^http:\/\/player\.vimeo\.com\/video\/(\d+)/]
- }
- },
- object: {
- youtube: {
- att: "data",
- match: [/^http:\/\/.*?\.?youtube-nocookie\.com\/v/]
- }
- }
- },
- msg: {
- check: "",
- cancelTitle: "Cancel Pin",
- bustFrame: "We need to remove the StumbleUpon toolbar before you can pin anything. Click OK to do this or Cancel to stay here.",
- noPin: "This site doesn't allow pinning to Pinterest. Please contact the owner with any questions. Thanks for visiting!",
- privateDomain: "Sorry, can't pin directly from %privateDomain%.",
- notFound: "Sorry, couldn't find any large images or video on this page.",
- installed: "The bookmarklet is installed! Now you can click your Pin It button to pin images as you browse sites around the web."
- },
- pop: "status=no,resizable=no,scrollbars=yes,personalbar=no,directories=no,location=no,toolbar=no,menubar=no,width=632,height=270,left=0,top=0",
- rules: ["#_bg {position:fixed;z-index:8675309; top:0; right:0; bottom:0; left:0; background-color:#f2f2f2; opacity:.95; }", "#_shim {position:fixed; background: transparent; z-index:8675308; top:0; right:0; bottom:0; left:0; }", "#_bd {position: absolute; text-align: left; padding-top: 36px; top: 0; left: 0; right: 0; z-index:8675320; font:16px hevetica neue,arial,san-serif; }", "#_bd span { zoom:1; display: inline-block; background: #fff; height:200px; width:200px; border: 1px solid #ddd; border-top: none; border-left:none; text-decoration: none; text-shadow: 0 1px #fff; position: relative; cursor: pointer; vertical-align:middle; }", "#_bd span#_logo {background: #FCF9F9 url(http://d3io1k5o0zdpqr.cloudfront.net/images/about/LogoAbout.png) 50% 50% no-repeat; box-shadow: none; }", '#_bd a#_x {height: 36px; line-height: 36px; position: fixed; font-size: 14px; font-weight: bold; display: block; width:auto; top: 0; left: 0; right: 0; margin: 0; background: url("http://d3io1k5o0zdpqr.cloudfront.net/images/fullGradient07Normal.png") repeat-x scroll 0 0 #FFFFFF; border-bottom: 1px solid #CCCCCC; color: #211922; text-align: center; z-index:8675321; }', '#_bd a#_x:active {background-color: #211922; background-image: url("http://d3io1k5o0zdpqr.cloudfront.net/images/fullGradient07Inverted.png"); border-color: #211922; text-shadow: 0 -1px #211922; }', "#_bd a#_x:hover {color: #fff; text-decoration: none; background-color: #1389e5; border-color: #1389e5; text-shadow: 0 -1px #46A0E6;}", "#_bd a img {max-height:200px; max-width:200px; top: 50%; left: 50%; position: absolute; z-index:8675312; }", "#_bd a b { z-index: 8675315; position: absolute; top: 50%; left: 50%; height: 50px; width: 50px; background: transparent url(http://d3io1k5o0zdpqr.cloudfront.net/images/VideoIndicator.png) 0 0 no-repeat; margin-top: -25px; margin-left: -25px; }", "#_bd a cite {z-index: 8675316; position: absolute; font-size: 10px; font-style: normal; bottom: 5px; width: 100px; left: 50%; margin-left: -50px; text-align: center; color: #000; background: #fff; padding: 3px;}", "#_bd span._pinContainer {z-index: 8675320; height: 200px; width: 200px; background: #fff; }", "#_bd span._pinButton {z-index: 8675320; height: 200px; width: 200px; background: transparent; }", "#_bd span._pinButton:hover {height: 200px; width: 200px; background: transparent url(http://d3io1k5o0zdpqr.cloudfront.net/images/PinThis.png) 50% 50% no-repeat; }"]
- };
- function pinmarkletPrep(win, doc, nav, config) {
- var scriptTagIndex = 0,
- a = win[config.idroot] = {
- win: win,
- doc: doc,
- nav: nav,
- config: config,
- structure: {},
- fns: {
- callback: [],
- removeNode: function(nodeId) {
- var node = a.doc.getElementById(nodeId);
- node && node.parentNode && node.parentNode.removeChild(node);
- },
- get: function(node, attrName) {
- var a = node[attrName];
- a = a || node.getAttribute(attrName);
- return a;
- },
- make: function(b) {
- var c = false, e, d;
- for (e in b) {
- if (b[e].hasOwnProperty) {
- c = a.doc.createElement(e);
- for (d in b[e]) {
- if (b[e][d].hasOwnProperty)
- if (typeof b[e][d] === "string")
- c[d] = b[e][d];
- }
- break;
- }
- }
- return c;
- },
- listen: function(b, c, e) {
- if (typeof a.win.addEventListener !== "undefined") b.addEventListener(c, e, false);
- else typeof a.win.attachEvent !== "undefined" && b.attachEvent("on" + c, e)
- },
- getSelection: function() {
- return ("" + (a.win.getSelection ? a.win.getSelection() : a.doc.getSelection ? a.doc.getSelection() : a.doc.selection.createRange().text)).replace(/(^\s+|\s+$)/g, "")
- },
- pin: function(b) {
- var c = b.getElementsByTagName("IMG")[0],
- e = "false",
- d = a.config.pin + "?",
- f = (new Date).getTime();
- if (b.rel === "video") e = "true";
- d = d + "media=" + encodeURIComponent(c.src);
- d = d + "&url=" + encodeURIComponent(c.getAttribute("url") || a.doc.URL);
- d = d + "&title=" + encodeURIComponent(a.doc.title);
- d = d + "&is_video=" + e;
- d = d + "&description=" + encodeURIComponent(a.values.selectedText || c.title || c.alt);
- a.values.hazIOS && a.win.setTimeout(function() {
- a.win.location = "pinit12:" + d
- }, 25);
- a.win.open(d, "pin" + f, a.config.pop)
- },
- close: function(b) {
- if (a.structure.bg) {
- a.doc.body.removeChild(a.structure.shim);
- a.doc.body.removeChild(a.structure.bg);
- a.doc.body.removeChild(a.structure.bd)
- }
- win.hazPinningNow = false;
- b && a.win.alert(b);
- a.values.hazGoodUrl = false;
- a.win.scroll(0, a.values.saveScrollTop)
- },
- click: function(b) {
- b = b || a.win.event;
- var c = null;
- if (c = b.target ? b.target.nodeType === 3 ? b.target.parentNode : b.target : b.srcElement) if (c === a.structure.x) a.fns.close();
- else if (c.parentNode.className === a.config.idroot + "_pinContainer" || c.className === a.config.idroot + "_pinButton") {
- a.fns.pin(c.parentNode.getElementsByTagName("A")[0]);
- a.win.setTimeout(function() {
- a.fns.close()
- }, 10)
- }
- },
- behavior: function() {
- a.fns.listen(a.structure.bd, "click", a.fns.click)
- },
- presentation: function() {
- var b = a.fns.make({
- STYLE: {
- type: "text/css"
- }
- }),
- c = a.config.rules.join("\n").replace(/#_/g, "#" + config.idroot + "_").replace(/\._/g, "." + config.idroot + "_");
- if (b.styleSheet) b.styleSheet.cssText = c;
- else b.appendChild(a.doc.createTextNode(c));
- a.doc.head.appendChild(b)
- },
- thumb: function(b, c, e, d, f, g) {
- if (a.values.hazSrc[b] !== true) a.values.hazSrc[b] = true;
- else if (!a.values.hazIE) return;
- a.values.hazAtLeastOneGoodThumb = true;
- d || (d = "image");
- var h = a.fns.make({
- SPAN: {
- className: a.config.idroot + "_pinContainer"
- }
- }),
- j = a.fns.make({
- A: {
- rel: d
- }
- }),
- i = new Image,
- m, n;
- i.setAttribute("nopin", "nopin");
- i.style.visibility = "hidden";
- if (f) i.title = f;
- g && i.setAttribute("url", g);
- i.onload = function() {
- m = this.width;
- n = this.height;
- this.style.marginTop = n < a.config.thumbCellSize ? -n / 2 + "px" : "-" + a.config.thumbCellSize / 2 + "px";
- this.style.marginLeft = m < a.config.thumbCellSize ? -m / 2 + "px" : "-" + a.config.thumbCellSize / 2 + "px";
- this.style.visibility = ""
- };
- i.src = b;
- j.appendChild(i);
- if (d !== "image") {
- b = a.fns.make({
- B: {}
- });
- j.appendChild(b);
- }
- c = a.fns.make({
- CITE: {
- innerHTML: c + " x " + e
- }
- });
- j.appendChild(c);
- h.appendChild(j);
- h.appendChild(a.fns.make({
- SPAN: {
- className: a.config.idroot + "_pinButton"
- }
- }));
- if (d !== "image")(d = a.structure.bd.getElementsByTagName("SPAN")[1]) ? d.parentNode.insertBefore(h, d) : a.structure.bd.appendChild(h);
- else a.structure.bd.appendChild(h)
- },
- invokeJsonp: function(urlStub, callback) {
- var scriptId = 'pint-jsonp-script-' + (new Date()).valueOf() + '-' + scriptTagIndex++,
- cbName = "window['" + a.config.idroot + "'].fns.callback[" + a.fns.callback.length + "]",
- scriptElt = a.doc.createElement("SCRIPT");
- a.fns.callback.push(function(f) {
- callback(f);
- a.fns.removeNode(id);
- });
- scriptElt.id = scriptId;
- scriptElt.src = urlStub + cbName;
- scriptElt.type = "text/javascript";
- scriptElt.charset = "utf-8";
- a.values.firstScript.parentNode.insertBefore(scriptElt, a.values.firstScript);
- },
- ping: {
- vimeo: function(b) {
- var c;
- if (b[0] && b[0].thumbnail_large && b[0].embed_privacy === "anywhere") {
- c = "";
- if (b[0].title) c += b[0].title;
- if (b[0].user_name) c = c + ". Video by " + b[0].user_name;
- if (b[0].user_description) c = c + ". " + b[0].user_description;
- c += ".";
- a.fns.thumb(b[0].thumbnail_large, 150, 200, "video", c, b[0].url)
- }
- }
- },
- hazSite: {
- youtube: {
- iframe: function(b) {
- b = b.src.split("?")[0].split("&")[0].split("/");
- a.fns.thumb("http://img.youtube.com/vi/" + b.pop() + "/0.jpg", 360, 480, "video")
- },
- video: function(b) {
- b.getAttribute("data-youtube-id") && a.fns.thumb("http://img.youtube.com/vi/" + b.getAttribute("data-youtube-id") + "/0.jpg", 360, 480, "video")
- },
- embed: function(b) {
- var c = b.getAttribute("flashvars"),
- e = "";
- (e = c ? c.split("video_id=")[1].split("&")[0] : b.src.split("?")[0].split("&")[0].split("/").pop()) && a.fns.thumb("http://img.youtube.com/vi/" + e + "/0.jpg", 360, 480, "video")
- },
- object: function(b) {
- b = b.getAttribute("data");
- var c = "";
- if (b) c = b.split("?")[0].split("&")[0].split("/").pop();
- c && a.fns.thumb("http://img.youtube.com/vi/" + c + "/0.jpg", 360, 480, "video")
- }
- },
- vimeo: {
- iframe: function(b) {
- a.fns.invokeJsonp("http://vimeo.com/api/v2/video/" + b.src.split("/").pop() + ".json?callback=", a.fns.ping.vimeo)
- }
- }
- },
- insureNoPinterestBlock:function(b) {
- if (b.name && b.name.toUpperCase() === "PINTEREST") {
- if (b.content && b.content.toUpperCase() === "NOPIN") {
- //a.fns.close(a.config.msg.noPin);
- a.values.noPin = true;
- }
- }
- },
- validateNaturalImgSize: function(b, callback) {
- var c;
- if (!b.src.match(/^data/)) {
- // get the natural dimensions of the image
- c = new Image();
- c.onload = function() {
- if (c.height > a.config.minImgSize && c.width > a.config.minImgSize) {
- a.fns.thumb(c.src, c.height, c.width);
- }
- callback();
- };
- c.src = b.src;
- }
- else {
- callback(); // done
- }
- },
- checkTags: function(callback) {
- var b, c, e, d, f, g, h, j, i,
- imgChecksComplete = 0,
- imgChecksRequested = 0,
- oneImageCheckComplete = function() {
- imgChecksComplete++;
- if (imgChecksComplete == imgChecksRequested) {
- callback();
- }
- };
- a.values.tag = [];
- b = 0;
- for (c = a.config.check.length; b < c; b += 1) {
- f = a.doc.getElementsByTagName(a.config.check[b]);
- e = 0;
- for (d = f.length; e < d; e += 1) {
- g = f[e];
- if (!g.getAttribute("nopin") &&
- g.style.display !== "none" &&
- g.style.visibility !== "hidden") {
- a.values.tag.push(g);
- }
- }
- }
- // pass 1: count the img checks, and do the meta checks
- b = 0;
- for (c = a.values.tag.length; b < c; b += 1) {
- f = a.values.tag[b]; // an element
- g = f.tagName.toLowerCase();
- if (g == 'img') {
- imgChecksRequested++;
- }
- else if (g == "meta") {
- a.fns.insureNoPinterestBlock(f);
- }
- }
- // pass 2: do the img checks
- for (b = 0; b < c; b += 1) {
- f = a.values.tag[b]; // an element
- g = f.tagName.toLowerCase();
- if (g == 'img') {
- a.fns.validateNaturalImgSize(f, oneImageCheckComplete);
- }
- }
- // edge case: nothing to check, so exhibit synchronous behavior
- if (imgChecksRequested === 0) {
- callback();
- }
- },
- structure: function() {
- a.structure.shim = a.fns.make({
- IFRAME: {
- height: "100%",
- width: "100%",
- allowTransparency: true,
- id: a.config.idroot + "_shim"
- }
- });
- a.structure.shim.setAttribute("nopin", "nopin");
- a.doc.body.appendChild(a.structure.shim);
- a.structure.bg = a.fns.make({
- DIV: {
- id: a.config.idroot + "_bg"
- }
- });
- a.doc.body.appendChild(a.structure.bg);
- a.structure.bd = a.fns.make({
- DIV: {
- id: a.config.idroot + "_bd"
- }
- });
- a.structure.x = a.fns.make({
- A: {
- id: a.config.idroot + "_x",
- innerHTML: a.config.msg.cancelTitle
- }
- });
- a.structure.bd.appendChild(a.structure.x);
- a.structure.bd.appendChild(a.fns.make({
- SPAN: {
- id: a.config.idroot + "_logo"
- }
- }));
- a.doc.body.appendChild(a.structure.bd);
- a.win.scroll(0, 0);
- },
- checkPage: function(callback) {
- a.fns.checkTags(callback);
- },
- init: function() {
- a.doc.body = a.doc.getElementsByTagName("BODY")[0];
- a.doc.head = a.doc.getElementsByTagName("HEAD")[0];
- if (!(!a.doc.body || !a.doc.head || win.hazPinningNow === true)) {
- var b, c = a.nav.userAgent;
- a.values = {
- saveScrollTop: a.win.pageYOffset,
- hazAtLeastOneGoodThumb: false,
- hazSrc: {},
- hazCalledForThumb: {},
- hazIE: function() {
- return /msie/i.test(c) && !/opera/i.test(c);
- }(),
- hazIOS: function() {
- return c.match(/iP/) !== null;
- }(),
- firstScript: a.doc.getElementsByTagName("SCRIPT")[0],
- selectedText: a.fns.getSelection()
- };
- b = a.config.checkpoint.url + "?url=" + encodeURIComponent(a.doc.URL) + "&callback=";
- a.fns.invokeJsonp(b, function(b) {
- if (b && b.ok === false) {
- a.fns.close(a.config.msg.noPin);
- return;
- }
- a.fns.structure();
- a.fns.presentation();
- a.fns.checkPage(function() {
- if (a.values.noPin) {
- a.fns.close(a.config.msg.noPin);
- return;
- }
- if ( ! a.values.hazAtLeastOneGoodThumb || a.values.tag.length === 0) {
- a.fns.close(a.config.msg.notFound);
- return;
- }
- a.fns.behavior();
- win.hazPinningNow = true;
- });
- });
- }
- }
- }
- };
- // export one function. It pops up the pinterest form.
- win.PinterestSpecial = {popupPinItForm: a.fns.init};
- }
- // this is a one-time thing
- pinmarkletPrep(window, document, navigator, pinmarkletConfig);
- }());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement