Last active
January 27, 2017 11:47
-
-
Save masone/a900827362712fafcaa2e3d4b9ce8f32 to your computer and use it in GitHub Desktop.
skyscanner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!function (e) { | |
function t() { | |
var t = e.skyscanner = e.skyscanner || {}, r = t.widgets = t.widgets || {}, a = r.renderCache = r.renderCache || {}, s = r.requests = r.requests || {}; | |
return {widgets: r, renderCache: a, requests: s} | |
} | |
function r(e, t, r) { | |
t = t || "", r = r || {}, r.v = "6678ba"; | |
var a = Object.keys(r).filter(function (e) { | |
return e && null !== r[e] | |
}).map(function (e) { | |
return encodeURIComponent(e) + "=" + encodeURIComponent(r[e]) | |
}).join("&"); | |
return e + t + "?" + a | |
} | |
function a(e, t) { | |
return r("https://widgets.skyscanner.net/widget-server", e, t) | |
} | |
function s(e, t) { | |
return r("https://www.skyscanner.net/g/widget-server", e, t) | |
} | |
function n(t, r) { | |
this.scope = r || o, this.xhr = e && e.XMLHttpRequest, this.element = t, this.locale = this.element.dataset.locale, this.widgetType = this.element.dataset.skyscannerWidget, this.params = {}, this.xhrParams = [], this.errors = [], this.serverUrl = "https://widgets.skyscanner.net/widget-server" | |
} | |
function i(t) { | |
if (e.document && e.document.querySelectorAll) { | |
var r = e.document.querySelectorAll(t); | |
return Array.prototype.slice.call(r) | |
} | |
} | |
var o = t(), c = ["locale", "skyscannerWidget", "skyscannerWidgetLoading", "params", "scriptParams", "locationParam", "locationName", "locationCoords", "locationPhrase", "locationIataCode"], l = /^\{(.+)\}$/, d = /^([^(]+)\(([^)]+)\)$/, h = n.prototype; | |
h.removeXhr = function (e) { | |
delete this.scope.requests[e] | |
}, h.getXhr = function (t, r, a) { | |
if (!this.scope.requests[t]) { | |
var s = new this.xhr; | |
s.addEventListener("loadend", this.removeXhr.bind(this, t)), s.open("GET", t, !0), r || s.setRequestHeader("Widget-Referrer", e.location && e.location.href), a && (s.withCredentials = !0), s.send(null), this.scope.requests[t] = s | |
} | |
return this.scope.requests[t] | |
}, h.addError = function (e, t) { | |
this.errors.push({message: e, error: t}) | |
}, h.lookupLocation = function (e) { | |
for (var t in e)if (!e[t])return; | |
return this.getXhr(a("/v1.0/" + this.element.dataset.locale + "/location", e)) | |
}, h.unregisterXhrParam = function (e) { | |
this.xhrParams = this.xhrParams.filter(function (t) { | |
return t.request !== e | |
}) | |
}, h.handleXhrParamLoad = function (e, t) { | |
this.unregisterXhrParam(t), 4 !== t.readyState || 200 !== t.status ? this.setParam(e, null) : this.setParam(e, t.responseText), this.beginRender() | |
}, h.registerXhrParam = function (e, t) { | |
this.xhrParams.push({key: e, request: t}), t.addEventListener("load", this.handleXhrParamLoad.bind(this, e, t)) | |
}, h.setSimpleParam = function (e, t) { | |
return void 0 === t ? void this.addError('Undefined parameter value for key "' + e + '"') : void(this.params[e] = t) | |
}, h.setComplexParams = function (e, t) { | |
var r = this, a = null; | |
if ("string" == typeof t)try { | |
a = JSON.parse(t) | |
} catch (e) { | |
this.addError("Error parsing JSON data: " + t) | |
} else a = t; | |
e.forEach(function (e) { | |
r.setSimpleParam(e.paramKey, a && a[e.objectKey] || null) | |
}) | |
}, h.setParam = function (e, t) { | |
if (t instanceof this.xhr) this.registerXhrParam(e, t); else { | |
var r = e.match(l); | |
if (r) { | |
var a = r[1].split(",").map(function (e) { | |
return e.trim() | |
}).map(function (e) { | |
var t = e.match(d); | |
return t ? {paramKey: t[1], objectKey: t[2]} : {paramKey: e, objectKey: e} | |
}); | |
this.setComplexParams(a, t) | |
} else this.setSimpleParam(e, t) | |
} | |
}, h.parseParamString = function (e) { | |
var t = {}; | |
return e.split(";").forEach(function (e) { | |
var r = e.split(":"); | |
e && r.length > 1 && (t[r[0]] = r[1]) | |
}), t | |
}, h.parseFixedParams = function () { | |
var e = this, t = this.parseParamString(this.element.dataset.params); | |
Object.keys(t).forEach(function (r) { | |
e.setParam(r, t[r]) | |
}) | |
}, h.parseScriptedParams = function () { | |
var e = this, t = this.element, r = t.dataset.scriptParams; | |
if (r)try { | |
var a = JSON.parse(r); | |
Object.keys(a).forEach(function (t) { | |
var r = a[t]; | |
if (t && r)try { | |
Array.isArray(r) && (r = r.join("\n")); | |
var s = function () { | |
return eval("(" + r + ")") | |
}.apply(e); | |
e.setParam(t, s) | |
} catch (r) { | |
e.addError('Error parsing scripted parameter "' + t + '"', r) | |
} | |
}) | |
} catch (e) { | |
this.addError("Error parsing data-script-parameters: " + r, e) | |
} | |
}, h.parseLocationParams = function () { | |
var e = this, t = { | |
name: this.element.dataset.locationName || this.element.dataset.locationParam, | |
latlon: this.element.dataset.locationCoords, | |
phrase: this.element.dataset.locationPhrase, | |
iataCode: this.element.dataset.locationIataCode | |
}, r = {}; | |
if (Object.keys(t).forEach(function (a) { | |
if (t[a])try { | |
var s = function () { | |
return eval("(" + t[a] + ")") | |
}.apply(e); | |
if ("undefined" == typeof s || "undefined" === s)throw"Undefined value"; | |
r[a] = s | |
} catch (e) { | |
console.warn("Failed to evaluate location " + a + " script: " + e) | |
} | |
}), Object.keys(r).length > 0) { | |
var a = "{location(name),locationId(id)}", s = this.lookupLocation(r); | |
s && this.setParam(a, s) | |
} | |
}, h.parseAffiliateParams = function () { | |
var e = this.element.dataset.affiliate; | |
if (e) { | |
var t = JSON.stringify(this.parseParamString(e)); | |
this.setParam("tracking", t) | |
} | |
}, h.beginRender = function () { | |
if (!(this.xhrParams.length > 0)) { | |
if (this.errors.length > 0)return console.log("Error(s) occured while loading widget", this), void this.errors.forEach(function (e) { | |
console.log(e.message), e.error && console.log(e.error) | |
}); | |
var e = a("/v1.0/" + this.element.dataset.locale + "/widgets/" + this.element.dataset.skyscannerWidget, this.params); | |
if ("undefined" != typeof this.scope.renderCache[e]) this.render(this.scope.renderCache[e]); else { | |
var t = this.getXhr(e); | |
t.addEventListener("load", this.handleRenderLoad.bind(this, e, t)) | |
} | |
} | |
}, h.handleRenderLoad = function (e, t) { | |
if (4 === t.readyState && 200 === t.status) { | |
var r = t.responseText; | |
this.scope.renderCache[e] = r, this.render(r) | |
} | |
}, h.render = function (e) { | |
var t = this; | |
try { | |
(function (__widget) { | |
eval(e) | |
}).call(this, this), this.replaceScriptNodes(), t.element.dataset.skyscannerWidgetLoaded = !0, this.personalise(), c.forEach(function (e) { | |
delete t.element.dataset[e] | |
}) | |
} catch (e) { | |
t.element.dataset.skyscannerWidgetError = !0, console.error("Error rendering widget:", e) | |
} | |
}, h.personalise = function () { | |
var e = this, t = {}; | |
Object.keys(e.params).forEach(function (r) { | |
t[r] = e.params[r] | |
}), t.locale = e.locale, t.widgetType = e.widgetType; | |
var r = s("/personalise", t), a = this.getXhr(r, !0, !0); | |
a.addEventListener("load", this.handlePersonalisationData.bind(this, a)) | |
}, h.handlePersonalisationData = function (e) { | |
if (4 === e.readyState && 200 === e.status) { | |
var t = JSON.parse(e.responseText); | |
t.personalise && (void 0 !== t.message && (this.element.querySelector(".skyscanner-widget-text").innerHTML = t.message), void 0 !== t.referralUrl && (this.element.querySelector("a").href = t.referralUrl)) | |
} | |
}, h.replaceScriptNodes = function () { | |
var t = this.element.querySelectorAll("script"); | |
Array.prototype.forEach.call(t, function (t) { | |
if ("SCRIPT" === t.tagName) { | |
var r = e.document.createElement("script"); | |
r.text = t.innerHTML, Array.prototype.forEach.call(t.attributes, function (e) { | |
"replace" !== e.name && r.setAttribute(e.name, e.value) | |
}), t.parentNode.replaceChild(r, t) | |
} | |
}) | |
}, o.widgets.load = function (e) { | |
console.log('widgets.load') | |
e = e || i; | |
var t = e("[data-skyscanner-widget]"); | |
console.log('widgets', t) | |
t && t.forEach(function (e) { | |
if (!(e.dataset.skyscannerWidgetLoading || e.dataset.skyscannerWidgetLoaded || e.dataset.skyscannerWidgetError)) { | |
e.dataset.skyscannerWidgetLoading = !0; | |
var t = new n(e); | |
t.parseFixedParams(), t.parseScriptedParams(), t.parseLocationParams(), t.parseAffiliateParams(), t.beginRender() | |
} | |
}) | |
}, o.widgets.load(), "undefined" != typeof module && module.exports && (module.exports = { | |
getWidgetUrl: a, | |
WidgetElement: n, | |
globals: o | |
}) | |
}("undefined" == typeof window ? global : window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment