Skip to content

Instantly share code, notes, and snippets.

@jcleveley-zz
Last active August 11, 2020 21:12
Show Gist options
  • Save jcleveley-zz/730574319504a08a59b7 to your computer and use it in GitHub Desktop.
Save jcleveley-zz/730574319504a08a59b7 to your computer and use it in GitHub Desktop.
(function(){
var o={'uk':1,
'ck':1,
'ad':0,
'ap':0,
'tb':0,
'mb':0,
'eu':0};
window.orb=window.orb||{};
window.fig=window.fig||{};
if (window.name.match(/ orb_fig_referrer=([^ ]+)$/)) {
window.orb.referrer = decodeURIComponent(RegExp.$1);
window.name = window.name.replace(/ orb_fig_referrer=([^ ]+)$/, '');
}
orb.fig=orb.fig||function(k){return (arguments.length)? o[k]:o};
window.define && define('orb/fig', o);
if (window.fig.async && typeof JSON != 'undefined') {
var jsonFig = JSON.stringify(o);
var date = new Date();
date.setTime(date.getTime()+(24*60*60*1000));
document.cookie = 'ckns_orb_cachedfig=' + jsonFig + '; expires=' + date.toGMTString() + '; path=/'
}
})();
/**
* Handle redirection due to user location provided via the fig object
* Using dependency injection for the Fig and Window object.
*
* @private
* @param {Array} f - short for fig, the configeration array passed from the fig object.
* @param {Object} [w=window] - optional, short for window, the window object, or mock thereof used for DI testing.
* @returns {Boolean} true if redirection occurs, false otherwise.
*
*/
orb._clientsideRedirect = function(f, w) {
var redirected = false,
prefCookie;
w = w || window;
prefCookie = (w.document.cookie.match(/ckps_d=(.)/)? RegExp.$1 : '');
if ( orb._redirectionIsEnabled(w) && orb._dependenciesSatisfied(f, w) ) {
var host = (w.location.hostname || '').toLowerCase(),
href = (w.location.href || ''),
page = {
isUk: /(^|\.)bbc\.co\.uk$/i.test(host),
isInt: /(^|\.)bbc\.com$/i.test(host),
isMb: /^m\./i.test(host),
isDesk: /^(www|pal)\./i.test(host)
},
user = {
isUk: f('uk'),
isMb: f('mb')
},
dest,
geoRelocatedHref,
referrer = (w.document.referrer || '').toLowerCase();
// hostname replace for location
if (w.bbcredirection.geo === true) {
if (page.isInt === true && user.isUk === 1) {
window.name += ' orb_fig_referrer=' + encodeURIComponent(document.referrer);
geoRelocatedHref = href.replace(/^(.+?bbc)\.com/i, '$1.co.uk');
}
else if (page.isUk === true && user.isUk === 0) {
window.name += ' orb_fig_referrer=' + encodeURIComponent(document.referrer);
geoRelocatedHref = href.replace(/^(.+?bbc)\.co\.uk/i, '$1.com');
}
}
dest = (geoRelocatedHref || href);
// hostname replace for device
if (w.bbcredirection.device === true) {
if (page.isDesk === true && ( prefCookie === 'm' || ( !prefCookie && user.isMb === 1 ) ) ) {
window.name += ' orb_fig_referrer=' + encodeURIComponent(document.referrer);
dest = dest.replace(/^(https?:\/\/)(www|pal)\./i, '$1m.');
}
else if (page.isMb === true && ( prefCookie === 'd' || ( !prefCookie && user.isMb === 0 ) ) ) {
window.name += ' orb_fig_referrer=' + encodeURIComponent(document.referrer);
dest = dest.replace(/^(https?:\/\/)m\./i, '$1www.');
}
}
// avoid redirecting to ourselves, or redirecting to the page we just came from, or redirecting when we came from ourself
if (dest && href.toLowerCase() !== dest.toLowerCase() && referrer !== dest.toLowerCase() && referrer !== href.toLowerCase()) {
redirected = true;
try {
w.location.replace(dest);
}
catch (e) {
redirected = false;
w.require(['istats-1'], function (istats) {
istats.log('redirection_fail', '', {});
});
}
}
}
return redirected;
};
/**
* Check public API to ensure redirection is enabled.
*
* @private
* @param {Object} w - short for window, the window object, or mock thereof.
*
*/
orb._redirectionIsEnabled = function(w) {
return (w.bbcredirection && (w.bbcredirection.geo === true || w.bbcredirection.device === true));
};
/**
* Returns true if browser supports redirection.
*
* @private
* @param {Function} f - the fig function
* @param {Object} w - short for window, the window object, or mock thereof.
*
*/
orb._dependenciesSatisfied = function(f, w) {
return (typeof f === 'function' && typeof w.location.replace !== 'undefined');
};/**
* Public API for accsessing geoip data
*
*/
orb.fig.device = {};
orb.fig.geo = {};
orb.fig.user = {};
/**
* Does BBC Demi say the user agent device is a tablet?
*
* @method isTablet
* @memberof orb.fig
* @returns {boolean|undefined} True or false to indicate a known state, or `undefined` if the
* information is not currently known.
* @example
* if ( orb.fig.isTablet() ) { alert('Tap your screen 3 times to enter!'); }
*/
orb.fig.device.isTablet = function(){
return window.orb.fig('no')? undefined : window.orb.fig('tb');
}
/**
* Does BBC Demi say the user agent device is a mobile?
*
* @method isMobile
* @memberof orb.fig
* @returns {boolean|undefined} True or false to indicate a known state, or `undefined` if the
* information is not currently known.
* @example
* if ( orb.fig.isMobile() ) { alert('Ring ring!'); }
*/
orb.fig.device.isMobile = function(){
return window.orb.fig('no')? undefined : window.orb.fig('mb');
}
/**
* Does BBC GEOIP say the user is in the UK?
*
* @method isUK
* @memberof orb.fig
* @returns {boolean|undefined} True or false to indicate a known state, or `undefined` if the
* information is not currently known.
* @example
* if ( orb.fig.isUK() ) { alert('Rule, Britannia!'); }
*/
orb.fig.geo.isUK = function(){
return window.orb.fig('no')? undefined : window.orb.fig('uk');
}
/**
* Does BBC GEOIP say the user is in the EU?
*
* @method isEU
* @memberof orb.fig
* @returns {boolean|undefined} True or false to indicate a known state, or `undefined` if the
* information is not currently known.
* @example
* if ( orb.fig.isEU() ) { alert('In varietate concordia'); }
*/
orb.fig.geo.isEU = function(){
return window.orb.fig('no')? undefined : window.orb.fig('eu');
}
orb._clientsideRedirect(window.mockFig || window.orb.fig, window.mockWindow || window);
(function() {
'use strict';
window.fig = window.fig || {};
window.fig.manager = {
/**
Defines the fig object and manages injections of test values in place of the real fig.
@param {window} [w] - Optional, used for dependecy injection.
*/
include: function(w) {
w = w || window;
var d = w.document,
c = d.cookie,
f = c.match(/(?:^|; ?)ckns_orb_fig=([^;]+)/),
cachedFig,
asyncAttr = '';
if ( !f && c.indexOf('ckns_orb_nofig=1') > -1 ) {
this.setFig(w, {no:1});
}
else {
if (f) {
f = this.deserialise( decodeURIComponent(RegExp.$1) );
this.setFig(w, f);
}
if (window.fig.async && typeof JSON != 'undefined') {
var figJson = (document.cookie.match('(^|; )ckns_orb_cachedfig=([^;]*)')||0)[2];
cachedFig = figJson ? JSON.parse(figJson) : null;
if (cachedFig) {
this.setFig(w, cachedFig);
asyncAttr = 'async';
}
}
d.write('<script src="http://pal.sandbox.dev.bbc.co.uk/frameworks/fig/1/fig.js"' + asyncAttr + '><'+'/script>');
}
},
/**
Checks if the fig is in an error state, if so it records the fact with a short-lived cookie.
@param {window} [w] - Optional, used for dependency injection.
*/
confirm: function(w) {
w = w || window;
if (w.orb && w.orb.fig && w.orb.fig('no')) {
this.setNoFigCookie(w);
}
if (w.orb === undefined || w.orb.fig === undefined) {
this.setFig(w, {no:1});
this.setNoFigCookie(w);
}
},
/**
Sets the no fig cookie, that stops the user from querying the fig endpoint
@param {window} [w] - Used for dependency injection.
*/
setNoFigCookie: function(w) {
w.document.cookie = 'ckns_orb_nofig=1; expires=' + new Date(new Date().getTime() + 1000 * 60 * 10).toGMTString() + ';';
},
/**
Sets the global ORB fig variable
@param {window} [w] - Used for dependency injection.
*/
setFig: function(w, f) {
(function(){var o=f;w.orb=w.orb||{};w.orb.fig=function(k){return (arguments.length)? o[k]:o};})();
},
/**
Parse cookie override for testing fig.
@param {string} str - The cookie value, expected to be formated as shown here https://confluence.dev.bbc.co.uk/pages/viewpage.action?pageId=64733458
*/
deserialise: function(str) {
var o = {};
str.replace(/([a-z]{2}):([0-9]+)/g, function() {
o[RegExp.$1] = +RegExp.$2;
});
return o;
}
};
})();
fig.manager.include();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment