# lib/goog/labs/useragent/util.js

    1// Copyright 2013 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.1415/**16 * @fileoverview Utilities used by goog.labs.userAgent tools. These functions17 * should not be used outside of goog.labs.userAgent.*.18 *19 * @visibility {//closure/goog/bin/sizetests:__pkg__}20 * @visibility {//closure/goog/dom:__subpackages__}21 * @visibility {//closure/goog/style:__pkg__}22 * @visibility {//closure/goog/testing:__pkg__}23 * @visibility {//closure/goog/useragent:__subpackages__}24 * @visibility {//testing/puppet/modules:__pkg__} *25 *26 * @author nnaze@google.com (Nathan Naze)27 */2829goog.provide('goog.labs.userAgent.util');3031goog.require('goog.string');323334/**35 * Gets the native userAgent string from navigator if it exists.36 * If navigator or navigator.userAgent string is missing, returns an empty37 * string.38 * @return {string}39 * @private40 */41goog.labs.userAgent.util.getNativeUserAgentString_ = function() {42  var navigator = goog.labs.userAgent.util.getNavigator_();43  if (navigator) {44    var userAgent = navigator.userAgent;45    if (userAgent) {46      return userAgent;47    }48  }49  return '';50};515253/**54 * Getter for the native navigator.55 * This is a separate function so it can be stubbed out in testing.56 * @return {Navigator}57 * @private58 */59goog.labs.userAgent.util.getNavigator_ = function() {60  return goog.global.navigator;61};626364/**65 * A possible override for applications which wish to not check66 * navigator.userAgent but use a specified value for detection instead.67 * @private {string}68 */69goog.labs.userAgent.util.userAgent_ =70    goog.labs.userAgent.util.getNativeUserAgentString_();717273/**74 * Applications may override browser detection on the built in75 * navigator.userAgent object by setting this string. Set to null to use the76 * browser object instead.77 * @param {?string=} opt_userAgent The User-Agent override.78 */79goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {80  goog.labs.userAgent.util.userAgent_ = opt_userAgent ||81      goog.labs.userAgent.util.getNativeUserAgentString_();82};838485/**86 * @return {string} The user agent string.87 */88goog.labs.userAgent.util.getUserAgent = function() {89  return goog.labs.userAgent.util.userAgent_;90};919293/**94 * @param {string} str95 * @return {boolean} Whether the user agent contains the given string, ignoring96 *     case.97 */98goog.labs.userAgent.util.matchUserAgent = function(str) {99  var userAgent = goog.labs.userAgent.util.getUserAgent();100  return goog.string.contains(userAgent, str);101};102103104/**105 * @param {string} str106 * @return {boolean} Whether the user agent contains the given string.107 */108goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {109  var userAgent = goog.labs.userAgent.util.getUserAgent();110  return goog.string.caseInsensitiveContains(userAgent, str);111};112113114/**115 * Parses the user agent into tuples for each section.116 * @param {string} userAgent117 * @return {!Array.<!Array.<string>>} Tuples of key, version, and the contents118 *     of the parenthetical.119 */120goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {121  // Matches each section of a user agent string.122  // Example UA:123  // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)124  // AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405125  // This has three version tuples: Mozilla, AppleWebKit, and Mobile.126127  var versionRegExp = new RegExp(128      // Key. Note that a key may have a space.129      // (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')130      '(\\w[\\w ]+)' +131132      '/' +                // slash133      '([^\\s]+)' +        // version (i.e. '5.0b')134      '\\s*' +             // whitespace135      '(?:\\((.*?)\\))?',  // parenthetical info. parentheses not matched.136      'g');137138  var data = [];139  var match;140141  // Iterate and collect the version tuples.  Each iteration will be the142  // next regex match.143  while (match = versionRegExp.exec(userAgent)) {144    data.push([145      match[1],  // key146      match[2],  // value147      // || undefined as this is not undefined in IE7 and IE8148      match[3] || undefined  // info149    ]);150  }151152  return data;153};154