Skip to content
This repository has been archived by the owner on Jul 19, 2018. It is now read-only.

Some minor fixes to Node port + support for device, isMobile, isSpider #56

Closed
wants to merge 9 commits into from
Closed

Conversation

shripadk
Copy link
Collaborator

Even though I have read/write access to this repo, I'll continue to send pull requests so that the changes can be reviewed before merging. :) This should fix #53 and #54.

obj.major = parseInt(majorVersionRep ? majorVersionRep : m[2]);
obj.minor = m[3] ? parseInt(m[3]) : null;
obj.patch = m[4] ? parseInt(m[4]) : null;
obj.major = ~~parseInt(majorVersionRep ? majorVersionRep : m[2]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a code comment stating how ~~ works with numbers and NaN

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added relevant information regarding the double bitwise not trick.

@tobie
Copy link
Owner

tobie commented Sep 13, 2012

Can we please split up diffs for regexes.yaml from everything else?

Fine for merging that part. The rest of the JS changes I'd like to review separately. I'm not fond of the bitwise operator trick, unless there are proven performance benefits in what's cleary a bottleneck of the code.

Furthermore, @bluesmoon mentioned in #5 that version numbers should be presented as strings (and not ints) as we're sometimes loosing info in the process of parsing these.

I welcome a proposition of how to go about changing this to ship it in a 0.3 version.

Makes sense?

@shripadk
Copy link
Collaborator Author

I agree with your points except for the bitwise operator trick which is arguably more performant. But this is moot if we are not going to be parsing out integers in the first place.

But, regarding #5, there is, I think, a problem with parsing out version numbers properly. The problem lies in regexes.yaml in which most of the regular expressions use \d+ (match 1 or more digits) for version matching. So the version number is returned as a string but stripped off the other non-digit suffixes/prefixes (a,b,pre etc). We have to first make changes to all the regexes in regexes.yaml. Its nothing to do with parseInt really.

@shripadk
Copy link
Collaborator Author

Okay there are a few regexes in regexes.yaml which include parsing out prefixes (Firefox Namoroka/Minefield etc). So what you do propose? Is there a benefit in keeping it as string, apart from comparison between versions? If it needs to be around for comparison, should this feature be added to the module itself or should be taken care of by the user at the application level?

@tobie
Copy link
Owner

tobie commented Sep 13, 2012

Not sure what's best. Would like input from @bluesmoon as he reported the issue initially.

@bluesmoon
Copy link
Collaborator

Version number comparison should be left to something like semver. I like keeping the versions as strings because that's typically what one displays in analytics software. Also, there are some user agents that only have string versions (and I forget the name of the one example that I'd reported).

@tobie
Copy link
Owner

tobie commented Sep 13, 2012

semver comparison only works reliably when the version strings are conformant to then Semver spec.

What are the ports in the other languages doing? Strings or ints?

What about providing both?

@shripadk
Copy link
Collaborator Author

My D port uses integers for versions (don't know about other ports. haven't read the code yet). Its trivial to rewrite to use strings. I vote for having both. It would facilitate simple comparisons at least (semver can be implemented at application level). If we should have both, then we need the .major, .minor and .patch to be strings and .major.toInt, .minor.toInt, and .patch.toInt to just parse out the integer. Do you have a better API in mind?

@closealert
Copy link

I'm in need of the device property in node as well and noticed this PR has been open for 2 months now. @shripadk, You haven't documented the device prop in your PR but from what I can see now it only returns a string? @tobie Wouldn't it be preferable to have a similar output format for all languages?

@tobie
Copy link
Owner

tobie commented Nov 7, 2012

There's too much different things going on in this PR for it to be pulled directly.

Happy to consider some more atomic changes.

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

@closealert True, I missed out on documenting device proprerty. Will do so. Thanks. Also, device should be returning a string because the regexes in regexes.yaml has only a device_replacement field (no major/minor/patch). So I'm pretty sure all the other ports return only a string.

@tobie Can you tell me what to include (or not include) so I can push the changes again?

@@ -6,10 +6,20 @@ var file = path.join(__dirname, '..', 'regexes.yaml');
var regexes = fs.readFileSync(file, 'utf8');
regexes = yaml.eval(regexes);

var mobile_agents = {};
var mobile_user_agent_families = regexes.mobile_user_agent_families.map(function(str) {
mobile_agents[str] = true;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you not returning anything on purpose here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! I should have just used a for-loop here. Thanks for pointing this out.

@closealert
Copy link

@shripadk The device property is returned as Object with isMobile and isSpider inside in other languages. For example, java:

  System.out.println(c.device.family);    // => "iPhone"
  System.out.println(c.device.isMobile);  // => true
  System.out.println(c.device.isSpider);  // => false

if(!!(d(ua))) {
return device = d(ua);
}
});

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I don't understand why you're operating these style changes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember now as to why this was needed. Can revert back for the time being.

@tobie
Copy link
Owner

tobie commented Nov 7, 2012

Commented in lots of places. Overall, would like to see this PR split up in 2-3 chunks taregting one thing only unless there's a compelling reason not to do so.

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

I have replied to your comments. Most of the issues you have raised relate to whether major, minor, patch need to return strings or integers. I think if we can come to a consensus on that, I can make the required changes and push it into this PR itself. The other issues you raised will be fixed immediately. Thanks for the review :)

@tobie
Copy link
Owner

tobie commented Nov 7, 2012

Sounds good. I'm wary of backwards compatibility issues, can you suggest a more elegant API which would allow us to do both?

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

@closealert Thanks will be fixed :)

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

@tobie For backwards compatibility we can continue returning major, minor, patch as strings. We can define a new property 'number' on the String object with a getter that would return an integer version of the string. Example:

Object.defineProperty(String.prototype, "number", {
   get: function() {
      return ~~parseInt(this);
   }
});

var u = ua.parse('Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3');

console.log(u.major); // returns "5"
console.log(u.major.number) // returns 5

AFAIK, returning a integer version of major, minor, patch would be mostly useful for version comparisons and not for display. So I don't suppose any other API change would be necessary (ex: toFullString/toVersionString).

@tobie
Copy link
Owner

tobie commented Nov 7, 2012

No, we can't extend the language like that in a lib. It's a Very Bad Practice(TM).

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

True. I can't think of any other way. Every other way would make it verbose. The choice is either verbosity or bad practice :)

@closealert
Copy link

I would suggest like @tobie to split this one up:

  1. Changes in regexes.yaml.
  2. Improved device property.
  3. The addition of the attributes majorInt and minorInt (or something like that) to the UserAgent object.

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

@closealert I have made changes to device property and also added attributes majorInt,minorInt,patchInt. Have also documented this. Please do review it. :)

@tobie
Copy link
Owner

tobie commented Nov 7, 2012

Can we please split this up. One feature per PR. Thanks.

@closealert
Copy link

@shripadk The changes look good but I can still see tobie's point considering the fact that there are a lot of lines in there not directly related to this fix. (for example the expansion of the UserAgent function). If you look at the original file (https://github.com/tobie/ua-parser/blob/master/js/index.js) then there are simply too many changes to merge. @tobie, close this one up and then @shripadk can create three new PR's - one for each feature.

@shripadk
Copy link
Collaborator Author

shripadk commented Nov 7, 2012

@tobie , @closealert sure will do ASAP :)

@shripadk shripadk closed this Nov 7, 2012
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update node-js implementation with device and os objects
4 participants