Skip to content

Instantly share code, notes, and snippets.

@matsubo
Created February 12, 2014 07:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save matsubo/8951320 to your computer and use it in GitHub Desktop.
Save matsubo/8951320 to your computer and use it in GitHub Desktop.
function receiveMessage(a) {
if (!document.getElementById(Gumroad.activeIframeId)) return;
if (document.getElementById(Gumroad.activeIframeId).getAttribute("src").indexOf(a.origin) != "0") return;
var b = a.data.split(" ")[0];
b == "close" && Gumroad.close()
}
var Gumroad = Gumroad || {
urlBlackList: ["/signup", "/login", "/logout", "/admin", "/settings", "/library", "/filtered_customer_count", "/customers", "/customers_switch_product", "/purchases", "/users", "/demo", "/products", "/dashboard", "/analytics", "/balance", "/confirm", "/crossdomain", "/api", "/developers", "/ping", "/webhooks", "/revenue_share", "/jobs", "/team", "/press", "/terms", "/privacy", "/blog-posts", "/faq", "/about", "/about", "/how-it-works", "/overlay", "/embed", "/modal", "/button", "/next-steps", "/charge", "/charge_data", "/CHARGE", "/examplify", "/deck", "/guide"],
init: function () {
if (navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/iPhone|iPad|iPod/i) || navigator.userAgent.match(/Opera Mini/i) || navigator.userAgent.match(/IEMobile/i)) return;
var a = document.createElement("style"),
b = '.gumroad-button { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif !important; font-size: 13px !important; line-height: 17px !important; font-weight: 500 !important; text-align: left !important; color: #8e8e8e !important; text-shadow: 0 1px 2px white !important; background: url(https://gumroad.com/assets/favicon.png) 5px 49% no-repeat white !important; border-radius: 3px !important; border: 1px solid #c8c8c8 !important; padding: 4px 6px 4px 26px !important; box-shadow: inset 0 -1px 2px rgba(0, 0, 0, .02), 0 1px 2px rgba(0, 0, 0, .1) !important; text-decoration: none !important; display: inline-block; } .gumroad-button:hover { text-decoration: none !important; color: #777 !important; border-color: #bbb !important; box-shadow: inset 0 -1px 2px rgba(0, 0, 0, .02), 0 1px 2px rgba(0, 0, 0, .1), 0 0 4px rgba(0, 0, 0, .1) !important; } .gumroad-button:active { box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2), inset 0 -1px 2px rgba(0, 0, 0, .02), 0 1px 2px rgba(0, 0, 0, .1) !important; background-color: #fafafa !important; } .gumroad-button strong { color: #666 !important; font-weight: bold !important; }';
a.type = "text/css", a.styleSheet ? a.styleSheet.cssText = b : a.appendChild(document.createTextNode(b)), document.getElementsByTagName("head")[0].appendChild(a), Gumroad.body = document.body, Gumroad.development = document.getElementById("modal-p") && document.getElementById("modal-p").getAttribute("data-gumroad-development") == "true", Gumroad.staging = document.getElementById("modal-p") && document.getElementById("modal-p").getAttribute("data-gumroad-staging") == "true", Gumroad.domain = Gumroad.development ? "http://local.host:3333" : "https://gumroad.com", Gumroad.domain = Gumroad.staging ? "http://staging.gumroad.com" : Gumroad.domain, Gumroad.create('<div id="iframe_loading_indicator" style="position: fixed; z-index: 2000; color: white; top: 50%; left: 50%; margin-top: -32px; margin-left: -32px; text-align: center; height: 64px; width: 64px; background: rgba(0, 0, 0, 1); border-radius: 10px; display: none;"><img src="' + Gumroad.domain + '/overlay-loader.gif" width="32" height="32" style="position: absolute; top: 50%; margin-top: -16px; left: 50%; margin-left: -16px; width: 32px !important; height: 32px !important;"/></div>'), Gumroad.loadingIndicatorId = "iframe_loading_indicator", Gumroad.loadingIndicator = document.getElementById(Gumroad.loadingIndicatorId), Gumroad.fadeDuration = 1e3, Gumroad.links = {};
var c = document.getElementsByTagName("a"),
d = [],
e = Gumroad.development ? ["http://l.h:3333", "http://local.host:3333/l"] : ["http://gum.co/", "https://gum.co/", "https://gumroad.com/l/"],
e = Gumroad.staging ? ["http://staging.gumroad.com/l/"] : e,
f = new RegExp(Gumroad.domain + "/[^/]+$");
for (var g = 0; g < c.length; g++) {
var h = c[g],
i = h.getAttribute("href"),
j = !1;
if (i != undefined) {
for (var k = 0; k < e.length; k++) i.lastIndexOf(e[k], 0) === 0 && j != 1 && (j = !0);
if (j) new GumroadModal(h, "product");
else if (f.test(i)) {
var l = !0;
for (var m = 0; m < Gumroad.urlBlackList.length; m++)
if (i.lastIndexOf(Gumroad.domain + Gumroad.urlBlackList[m], 0) === 0) {
l = !1;
break
}
l && new GumroadModal(h, "user")
}
}
}
},
create: function (a) {
var b = document.createDocumentFragment(),
c = document.createElement("div");
c.innerHTML = "hack" + a;
while (c.firstChild) c.firstChild.nodeType === 1 ? b.appendChild(c.firstChild) : c.removeChild(c.firstChild);
Gumroad.body.insertBefore(b, Gumroad.body.childNodes[0])
},
remove: function (a) {
return (elem = document.getElementById(a)).parentNode.removeChild(elem)
},
setOpacity: function (a, b) {
if (a == null) return !1;
b == 0 ? a.style.display = "none" : a.style.display = "block", a.style.opacity = b, a.style.MozOpacity = b, a.style.KhtmlOpacity = b, a.style.filter = "alpha(opacity=" + b * 100 + ");"
},
fadeOut: function (a) {
var b = document.getElementById(a),
c = 1,
d = setInterval(function () {
c -= 100 / Gumroad.fadeDuration, Gumroad.setOpacity(b, c), c <= 0 && (Gumroad.setOpacity(b, 0), b.style.display = "none", clearInterval(d))
}, Gumroad.fadeDuration / 100)
},
fadeIn: function (a) {
var b = document.getElementById(a),
c = 0,
d = setInterval(function () {
c += 100 / Gumroad.fadeDuration, Gumroad.setOpacity(b, c), c >= 1 && (Gumroad.setOpacity(b, 1), clearInterval(d), b.contentWindow.focus())
}, Gumroad.fadeDuration / 100)
},
newEvent: function (a, b, c, d) {
var e = d ? function (a) {
c.apply(d, [a])
} : c;
document.addEventListener ? a.addEventListener(b, e, !1) : document.attachEvent && a.attachEvent("on" + b, e)
},
removeEvent: function (a, b, c) {
document.removeEventListener ? a.removeEventListener(b, c, !1) : document.detachEvent && a.detachEvent(b, c)
},
cancelEvent: function (a) {
a && a.preventDefault ? a.preventDefault() : window.event.returnValue = !1
},
showLoadingIndicator: function () {
Gumroad.setOpacity(Gumroad.loadingIndicator, .6)
},
hideLoadingIndicator: function () {
if (Gumroad.loadingIndicator === !1) return;
Gumroad.setOpacity(Gumroad.loadingIndicator, 0)
},
stopPreviews: function () {
document.getElementById(Gumroad.activeIframeId).contentWindow.postMessage("stopPreviews", "*")
},
close: function (a) {
return a !== undefined && Gumroad.cancelEvent(a), Gumroad.stopPreviews(), Gumroad.activeIframeId && (Gumroad.fadeOut(Gumroad.activeIframeId), Gumroad.hideLoadingIndicator()), Gumroad.activeIframeId = !1, !1
}
};
GumroadModal = function (a, b) {
var c = a.getAttribute("href"),
d = c.split("/"),
e = c.split("#");
this.el = a, this.id = d[d.length - 1].split("?")[0].split("#")[0], this.wanted = "", this.offerCode = "", this.locale = "", this.type = b, this.hash = e.length > 1 ? "#" + e[e.length - 1] : "";
if (d.length == 6 && c.indexOf("/l/") != -1 || d.length == 5 && (c.indexOf("gum.co") != -1 || c.indexOf("l.h:") != -1)) this.id = d[d.length - 2], this.offerCode = "/" + d[d.length - 1];
this.iframeId = "gumroad_" + this.type + "_" + this.id, c.split("?").length > 1 && c.split("?")[1].lastIndexOf("wanted=true") != -1 && (this.wanted = "&wanted=true"), c.split("?").length > 1 && c.split("?")[1].lastIndexOf("locale=") != -1 && (this.locale = "&locale=" + c.split("locale=")[1]), Gumroad.newEvent(this.el, "click", this.show, this)
}, GumroadModal.prototype = {
show: function (a) {
a && Gumroad.cancelEvent(a), Gumroad.showLoadingIndicator();
if (Gumroad.links[this.iframeId] == null) {
this.type == "product" ? Gumroad.create('<iframe class="gumroad_iframe" id="' + this.iframeId + '" src="' + Gumroad.domain + "/l/" + this.id + this.offerCode + "?as_modal=true" + this.wanted + this.locale + "&source_url=" + window.location.href + '"&referrer=' + document.referrer + "&" + window.location.search.substring(1) + '" allowtransparency="true" width="100%" height="100%" style="position: fixed !important; overflow: scroll !important; z-index: 1999 !important; top: 0 !important; bottom: 0 !important; right: 0 !important; left: 0 !important; width: 100% !important; height: 100% important; border: none !important; display: none; margin: 0 !important; padding: 0 !important;"></iframe>') : this.type == "user" && Gumroad.create('<iframe class="gumroad_iframe" id="' + this.iframeId + '" src="' + Gumroad.domain + "/" + this.id + "?as_modal=true" + this.locale + "&source_url=" + window.location.href + "&referrer=" + document.referrer + "&" + window.location.search.substring(1) + this.hash + '" allowtransparency="true" width="100%" height="100%" style="position: fixed !important; overflow: scroll !important; z-index: 1999 !important; top: 0 !important; bottom: 0 !important; right: 0 !important; left: 0 !important; width: 100% !important; height: 100% important; border: none !important; display: none; margin: 0 !important; padding: 0 !important;"></iframe>'), Gumroad.links[this.iframeId] = !0;
var b = document.getElementById(this.iframeId);
Gumroad.setOpacity(b, .001), Gumroad.newEvent(b, "load", this.reallyShowIFrame, this)
} else {
var b = document.getElementById(this.iframeId);
b.contentWindow.postMessage(this.hash, Gumroad.domain), this.reallyShowIFrame()
}
return !1
},
reallyShowIFrame: function (a) {
Gumroad.activeIframeId = this.iframeId, Gumroad.hideLoadingIndicator(), Gumroad.fadeIn(this.iframeId)
}
}, document.onkeydown = function () {
event.keyCode == 27 && Gumroad.close()
}, Gumroad.newEvent(window, "load", Gumroad.init), window.addEventListener("message", receiveMessage, !1);
@matsubo
Copy link
Author

matsubo commented Oct 29, 2019

memo
I reverse engineered the source of the cloudfront URL javascript. It's made by gumroad and obfuscated.
I tried to make the overlay purchase UI like gumroad did at that time, 5 years ago. The gist code is part of my research to create the overlay UI.

Copy link

ghost commented Feb 13, 2020

What do you do with this?

@matsubo
Copy link
Author

matsubo commented Feb 14, 2020

@Helixable I used as described above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment