Skip to content

Instantly share code, notes, and snippets.

@klodoma
Created October 11, 2019 07:21
Show Gist options
  • Save klodoma/f5b5413415f78f86ced0df179c83ac4a to your computer and use it in GitHub Desktop.
Save klodoma/f5b5413415f78f86ced0df179c83ac4a to your computer and use it in GitHub Desktop.
Javascript UserAgent Manipulator
class UserAgents
{
constructor(targetWindow) {
this.window = targetWindow || window;
}
/**
* Creates a read/writable property which returns a function set for write/set (assignment)
* and read/get access on a variable
*
* @param {Any} value initial value of the property
*/
createProperty (value) {
var _value = value;
/**
* Overwrite getter.
*
* @returns {Any} The Value.
* @private
*/
function _get () {
return _value;
}
/**
* Overwrite setter.
*
* @param {Any} v Sets the value.
* @private
*/
function _set (v) {
_value = v;
}
return {
'get': _get,
'set': _set
};
}
/**
* Creates or replaces a read-write-property in a given scope object, especially for non-writable properties.
* This also works for built-in host objects (non-DOM objects), e.g. navigator.
* Optional an initial value can be passed, otherwise the current value of the object-property will be set.
*
* @param {Object} objBase e.g. window
* @param {String} objScopeName e.g. "navigator"
* @param {String} propName e.g. "userAgent"
* @param {Any} [initValue] (optional) e.g. window.navigator.userAgent
*/
makePropertyWritable (objBase, objScopeName, propName, initValue) {
var newProp,
initObj;
if (objBase && objScopeName in objBase && propName in objBase[objScopeName]) {
if (typeof initValue === 'undefined') {
initValue = objBase[objScopeName][propName];
}
newProp = this.createProperty(initValue);
try {
Object.defineProperty(objBase[objScopeName], propName, newProp);
} catch (e) {
initObj = {};
initObj[propName] = newProp;
try {
objBase[objScopeName] = Object.create(objBase[objScopeName], initObj);
} catch (e) {
// Workaround, but necessary to overwrite native host objects
}
}
}
}
/**
* @see https://deviceatlas.com/blog/list-of-user-agent-strings
*/
getAgents () {
return {
//phones
'GalaxyS9': {
x: 360,
y: 740,
agent: 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36'
},
'GalaxyS8': {
x: 360,
y: 740,
agent: 'Mozilla/5.0 (Linux; Android 7.0; SM-G892A Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Mobile Safari/537.36'
},
'iPhoneX': {
x: 375,
y: 812,
agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
},
'iPhone8': {
x: 375,
y: 667,
agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1'
},
//tablets
'GalaxyTabS3': {
x: 375,
y: 667,
agent: 'Mozilla/5.0 (Linux; Android 7.0; SM-T827R4 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.116 Safari/537.36'
},
'GalaxyTabA': {
x: 375,
y: 667,
agent: 'Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-T550 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.3 Chrome/38.0.2125.102 Safari/537.36'
},
'iPadPro9.7': {
x: 768,
y: 1024,
agent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1'
},
'iPadPro12.9': {
x: 1024,
y: 1366,
agent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1'
}
};
}
setAgent (platform) {
let agents = this.getAgents();
if (!agents[platform]) {
console.error('Invalid platform', platform);
return;
}
this.makePropertyWritable(this.window, 'navigator', 'userAgent');
this.window.navigator.userAgent = agents[platform].agent;
this.window.userAgentX = agents[platform].x;
this.window.userAgentY = agents[platform].y;
console.log(this.window.navigator.userAgent);
}
set (platform, landscape) {
if (platform === 'phone') {
this.setAgent('GalaxyS9');
}
if (platform === 'tablet') {
this.setAgent('iPadPro9.7');
}
if (landscape) {
this.window.userAgentLandscape = true;
}
}
discover () {
let s = this.window.location.search;
if (s.match(/\bphone\b/)) {
this.setAgent('GalaxyS9');
} else {
if (s.match(/\btablet\b/)) {
this.setAgent('iPadPro9.7');
} else {
}
}
if (s.match(/\blandscape\b/)) {
this.window.userAgentLandscape = true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment