Skip to content

Commit

Permalink
fix(eg): improve user agent parsing logic
Browse files Browse the repository at this point in the history
merged similar browser & OS rules.
separate checking webview rules.

naver#35
  • Loading branch information
happyhj committed Oct 14, 2015
1 parent acacf7c commit 7047fa8
Showing 1 changed file with 138 additions and 150 deletions.
288 changes: 138 additions & 150 deletions src/eg.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,84 +95,77 @@ if(agent.os.name === "naver") {
}
*/
/*
* {String|RegEx} subString
* {String|RegEx} criteria
* {String|RegEx} identity
* {String|RegEx} versionSearch
* {String|RegEx} conflictOSIdentity
* {String|RegEx} webviewVersion
* {String|RegEx} webviewToken
* {String} versionSearch
* {String} versionAlias
* {String|RegEx} webviewBrowserVersion
* {String|RegEx} webviewToken
*/
var userAgentRules = {
browser: [{
subString: "PhantomJS",
criteria: "PhantomJS",
identity: "PhantomJS"
}, {
subString: "SAMSUNG",
criteria: /MSIE|Trident|Windows Phone/,
identity: "IE",
versionSearch: "IEMobile|MSIE|rv"
}, {
criteria: "SAMSUNG",
identity: "SBrowser",
versionSearch: "Chrome",
conflictOSIdentity: "Windows Phone"
versionSearch: "Chrome"
}, {
subString: "Chrome",
criteria: /Chrome|CriOS/,
identity: "Chrome"
}, {
subString: /iPhone|iPad/i,
criteria: /android/i,
identity: "default"
}, {
criteria: /iPhone|iPad/i,
identity: "Safari",
versionSearch: "Version",
conflictOSIdentity: /Android|Windows Phone/i,
webviewVersion: /-1/
versionSearch: "Version"
}, {
subString: "Apple",
criteria: "Apple",
identity: "Safari",
versionSearch: "Version",
conflictOSIdentity: /Android/i
versionSearch: "Version"
}, {
identity: "Opera",
versionSearch: "Version"
}, {
subString: "Firefox",
criteria: "Firefox",
identity: "Firefox"
}, {
subString: "MSIE",
identity: "IE",
versionSearch: "MSIE"
}, {
subString: "Trident",
identity: "IE",
versionSearch: "rv"
}],
os: [{
subString: "Windows Phone",
criteria: /Windows Phone|Windows NT/,
identity: "Window",
versionSearch: "Windows Phone"
},
{
subString: "Windows 2000",
versionSearch: "Windows Phone|Windows NT"
}, {
criteria: "Windows 2000",
identity: "Window",
versionAlias: "5.0"
},
{
subString: "Win",
identity: "Window",
versionSearch: "Windows NT"
},
{
subString: "iPhone",
identity: "iOS",
versionSearch: "iPhone OS",
webviewToken: /NAVER|DAUM/i
}, {
subString: "iPad",
criteria: /iPhone|iPad/,
identity: "iOS",
versionSearch: "CPU OS",
webviewToken: /NAVER|DAUM/i
versionSearch: "iPhone OS|CPU OS"
}, {
subString: "Mac",
criteria: "Mac",
versionSearch: "OS X",
identity: "MAC"
}, {
subString: /android/i,
identity: "Android",
criteria: /android/i,
identity: "Android"
}],

// Check Webview
// ios : In the absence of version
// Android 5.0 && chrome 40+ : when there is a keyword of "; wv" in useragent
// Under android 5.0 : when there is a keyword of "NAVER or Daum" in useragent
webview: [{
criteria: /iPhone|iPad/i,
browserVersionSearch: "Version",
webviewBrowserVersion: /-1/
}, {
criteria: /iPhone|iPad|android/i,
webviewToken: /NAVER|DAUM|; wv/i
}],
defaultString: {
Expand All @@ -187,74 +180,55 @@ if(agent.os.name === "naver") {
};

var UAParser = {
getBrowserName: function(browserRules) {
return this.getIdentityStringFromArray(
browserRules,
userAgentRules.defaultString.browser
);
},
getBrowserVersion: function(browserName) {
var ua = this.ua;
var defaultBrowserVersion =
userAgentRules.defaultString.browser.version;
var browserVersion;
var rules = [];
var rule;
var i;
var ruleCount;
var versionToken;
var versionTokenIndex;
var versionIndex;

if (!browserName) {
return;
}

for (i in userAgentRules.browser) {
if (userAgentRules.browser[i].identity === browserName) {
rules.push(userAgentRules.browser[i]);
}
}
versionToken =
this.getBrowserRule(browserName).versionSearch || browserName;

for (i = 0, ruleCount = rules.length ; i < ruleCount ; i++) {
rule = rules[i];
versionToken = rule.versionSearch || browserName;
versionTokenIndex = ua.indexOf(versionToken);
versionIndex;
if (versionTokenIndex > -1) {
versionIndex = versionTokenIndex + versionToken.length + 1;
browserVersion = ua.substring(versionIndex).split(" ")[0];
break;
}
}
browserVersion = this.extractBrowserVersion(versionToken, this.ua);

return browserVersion;
},
extractBrowserVersion: function(versionToken, ua) {
var browserVersion = userAgentRules.defaultString.browser.version;
var versionIndex;
var versionTokenIndex;
var versionRegexResult =
(new RegExp("(" + versionToken + ")", "i")).exec(ua);

if (browserVersion) {
browserVersion = browserVersion.replace(/_/g, ".")
.replace(/\;|\)/g, "");
if (!versionRegexResult) {
return browserVersion;
}

return browserVersion || defaultBrowserVersion;
},
getName: function(browserRules) {
return this.getIdentityStringFromArray(browserRules);
},
getIdentity: function(rule) {
return this.matchSubString(rule);
},
getIdentityStringFromArray: function(rules) {
var conflictOSIdentity;
var identity;
var rule;

for (var i = 0, h = rules.length; i < h; i++) {
rule = rules[i];
conflictOSIdentity = rule.conflictOSIdentity;
if (this.isMatched(this.ua, conflictOSIdentity)) {
continue;
}
identity = this.getIdentity(rule);
if (identity) {
return identity;
}
versionTokenIndex = versionRegexResult.index;
versionToken = versionRegexResult[0];
if (versionTokenIndex > -1) {
versionIndex = versionTokenIndex + versionToken.length + 1;
browserVersion = ua.substring(versionIndex)
.split(" ")[0]
.replace(/_/g, ".")
.replace(/\;|\)/g, "");
}
return userAgentRules.defaultString.browser.name;

return browserVersion;
},
getOS: function(osRules) {
return this.getIdentityStringFromArray(osRules);
getOSName: function(osRules) {
return this.getIdentityStringFromArray(
osRules,
userAgentRules.defaultString.os
);
},
getOSVersion: function(osName) {
var ua = this.ua;
Expand All @@ -263,9 +237,9 @@ if(agent.os.name === "naver") {
var osVersion;
var osVersionToken;
var osVersionRegex;
var osVersionRegResult;
var osVersionRegexResult;

if (!ua || !osName) {
if (!osName) {
return;
}

Expand All @@ -274,11 +248,15 @@ if(agent.os.name === "naver") {
}

osVersionToken = osRule.versionSearch || osName;
osVersionRegex = new RegExp(osVersionToken + " ([\\d_\\.]+)", "i");
osVersionRegResult = ua.match(osVersionRegex);

if (osVersionRegResult !== null) {
osVersion = osVersionRegResult[1].replace(/_/g, ".")
osVersionRegex =
new RegExp(
"(" + osVersionToken + ")\\s([\\d_\\.]+|\\d_0)",
"i"
);

osVersionRegexResult = osVersionRegex.exec(ua);
if (osVersionRegexResult) {
osVersion = osVersionRegex.exec(ua)[2].replace(/_/g, ".")
.replace(/\;|\)/g, "");
}

Expand All @@ -291,53 +269,67 @@ if(agent.os.name === "naver") {
return this.getRule(userAgentRules.browser, browserName);
},
getRule: function(rules, targetIdentity) {
var ua = this.ua;
var i;
var subString;
var regex;
var criteria;
var identityMatched;
var rule;

for (i in rules) {
subString = rules[i].subString;
regex = new RegExp("^" + rules[i].identity + "$", "i");
identityMatched = regex.test(targetIdentity);
if (subString ?
identityMatched && this.isMatched(ua, subString) :

for (var i in rules) {
criteria = rules[i].criteria;
identityMatched =
new RegExp(rules[i].identity, "i").test(targetIdentity);
if (criteria ?
identityMatched && this.isMatched(this.ua, criteria) :
identityMatched) {
rule = rules[i];
break;
return rules[i];
}
}

return rule;
},
matchSubString: function(rule) {
var ua = this.ua;
var token = rule.subString;
var exToken = rule.conflictOSIdentity;
if (!this.isMatched(ua, exToken) && this.isMatched(ua, token)) {
return rule.identity;
getIdentityStringFromArray: function(rules, defaultStrings) {
for (var i in rules) {
if (this.isMatched(this.ua, rules[i].criteria)) {
return rules[i].identity || defaultStrings.name;
}
}
return defaultStrings.name;
},
isMatched: function(base, target) {
return target &&
target.test ? !!target.test(base) : base.indexOf(target) > -1;
},

// Check Webview
// ios : In the absence of version
// Android 5.0 && chrome 40+ : when there is a keyword of "; wv" in useragent
// Under android 5.0 : when there is a keyword of "NAVER or Daum" in useragent
getWebview: function(osName, browserName, browserVersion) {
isWebview: function() {
var ua = this.ua;
var osRule = this.getOSRule(osName) || {};
var browserRule = this.getBrowserRule(browserName) || {};
var webviewRules = userAgentRules.webview;
var webviewRule;
var isWebview = false;
var browserVersionSearch;
var browserVersion;
var webviewToken;
var webviewBrowserVersion;

for (var i in webviewRules) {
webviewRule = webviewRules[i];
if (!this.isMatched(ua, webviewRule.criteria)) {
continue;
}

browserVersionSearch = webviewRule.browserVersionSearch;
browserVersion =
this.extractBrowserVersion(browserVersionSearch, ua);
webviewBrowserVersion = webviewRule.webviewBrowserVersion;
if (this.isMatched(browserVersion, webviewBrowserVersion)) {
isWebview = true;
}

webviewToken = webviewRule.webviewToken;
if (webviewToken && this.isMatched(ua, webviewToken)) {
isWebview = true;
}

if (isWebview === true) {
break;
}
}

return this.isMatched(ua, osRule.webviewToken) ||
this.isMatched(ua, browserRule.webviewToken) ||
this.isMatched(browserVersion, browserRule.webviewVersion) ||
false;
return isWebview;
}
};

Expand All @@ -348,15 +340,11 @@ if(agent.os.name === "naver") {
browser: {}
};

agent.browser.name = UAParser.getName(userAgentRules.browser);
agent.browser.name = UAParser.getBrowserName(userAgentRules.browser);
agent.browser.version = UAParser.getBrowserVersion(agent.browser.name);
agent.os.name = UAParser.getOS(userAgentRules.os);
agent.os.name = UAParser.getOSName(userAgentRules.os);
agent.os.version = UAParser.getOSVersion(agent.os.name);
agent.browser.webview = UAParser.getWebview(
agent.os.name,
agent.browser.name,
agent.browser.version
);
agent.browser.webview = UAParser.isWebview();

agent.browser.name = agent.browser.name.toLowerCase();
agent.os.name = agent.os.name.toLowerCase();
Expand Down

0 comments on commit 7047fa8

Please sign in to comment.