incubator-devicemap-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r1302881 - in /incubator/devicemap/trunk/prototypes/logcapture: index.html lib/ lib/platform.js/ lib/platform.js/LICENSE.txt lib/platform.js/platform.js logcapture.js
Date Tue, 20 Mar 2012 13:34:51 GMT
Author: bdelacretaz
Date: Tue Mar 20 13:34:51 2012
New Revision: 1302881

URL: http://svn.apache.org/viewvc?rev=1302881&view=rev
Log:
add crude plugin support + platform.js values (from https://github.com/bestiejs/platform.js)

Added:
    incubator/devicemap/trunk/prototypes/logcapture/lib/
    incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/
    incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/LICENSE.txt
    incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/platform.js
Modified:
    incubator/devicemap/trunk/prototypes/logcapture/index.html
    incubator/devicemap/trunk/prototypes/logcapture/logcapture.js

Modified: incubator/devicemap/trunk/prototypes/logcapture/index.html
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/prototypes/logcapture/index.html?rev=1302881&r1=1302880&r2=1302881&view=diff
==============================================================================
--- incubator/devicemap/trunk/prototypes/logcapture/index.html (original)
+++ incubator/devicemap/trunk/prototypes/logcapture/index.html Tue Mar 20 13:34:51 2012
@@ -13,7 +13,33 @@
 </script>
 
 <!-- 
-    To setup devicemap detection, add this script in head
+    Example devicemap detection plugin setup.
+    A plugin returns an object that will be
+    encoded in the devicemap image request 
+-->
+<script src="lib/platform.js/platform.js" language="javascript"></script>
+<script language="javascript">
+  function platformDetection() {
+    var platformKeys = [ "name", "version", "product", "manufacturer", "layout", "os", "description"
];
+    var result = {};
+    for(i in platformKeys) {
+      var key = platformKeys[i];
+      result["platform." + key] = platform[key];
+    }
+    return result;
+  }
+  
+  if(!window._DMAP_) {
+    window._DMAP_ = {};
+  }
+  if(!window._DMAP_.plugins) {
+    window._DMAP_.plugins = new Array();
+  }
+  window._DMAP_.plugins.push(platformDetection);
+</script>
+
+<!-- 
+    To setup devicemap detection, add these scripts in head
     and add a div id="devicemap" element somewhere in the
     document. The devicemap img and debug output elements 
     will be added as children of that element.

Added: incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/LICENSE.txt
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/LICENSE.txt?rev=1302881&view=auto
==============================================================================
--- incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/LICENSE.txt (added)
+++ incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/LICENSE.txt Tue Mar 20
13:34:51 2012
@@ -0,0 +1,20 @@
+Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file

Added: incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/platform.js
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/platform.js?rev=1302881&view=auto
==============================================================================
--- incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/platform.js (added)
+++ incubator/devicemap/trunk/prototypes/logcapture/lib/platform.js/platform.js Tue Mar 20
13:34:51 2012
@@ -0,0 +1,878 @@
+/*!
+ * Platform.js v1.0.0-pre <http://mths.be/platform>
+ * Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
+ * Available under MIT license <http://mths.be/mit>
+ */
+;(function(window) {
+
+  /** Backup possible window/global object */
+  var oldWin = window;
+
+  /** Detect free variable `exports` */
+  var freeExports = typeof exports == 'object' && exports;
+
+  /** Detect free variable `global` */
+  var freeGlobal = typeof global == 'object' && global &&
+    (global == global.global ? (window = global) : global);
+
+  /** Opera regexp */
+  var reOpera = /Opera/;
+
+  /** Used to resolve a value's internal [[Class]] */
+  var toString = {}.toString;
+
+  /** Detect Java environment */
+  var java = /Java/.test(getClassOf(window.java)) && window.java;
+
+  /** A character to represent alpha */
+  var alpha = java ? 'a' : '\u03b1';
+
+  /** A character to represent beta */
+  var beta = java ? 'b' : '\u03b2';
+
+  /** Browser document object */
+  var doc = window.document || {};
+
+  /** Used to check for own properties of an object */
+  var hasOwnProperty = {}.hasOwnProperty;
+
+  /** Browser navigator object */
+  var nav = window.navigator || {};
+
+  /**
+   * Detect Opera browser
+   * http://www.howtocreate.co.uk/operaStuff/operaObject.html
+   * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
+   */
+  var opera = window.operamini || window.opera;
+
+  /** Opera [[Class]] */
+  var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null);
+
+  /** Possible global object */
+  var thisBinding = this;
+
+  /** Browser user agent string */
+  var userAgent = nav.userAgent || '';
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Capitalizes a string value.
+   * @private
+   * @param {String} string The string to capitalize.
+   * @returns {String} The capitalized string.
+   */
+  function capitalize(string) {
+    string = String(string);
+    return string.charAt(0).toUpperCase() + string.slice(1);
+  }
+
+  /**
+   * An iteration utility for arrays and objects.
+   * @private
+   * @param {Array|Object} object The object to iterate over.
+   * @param {Function} callback The function called per iteration.
+   */
+  function each(object, callback) {
+    var index = -1,
+        length = object.length;
+
+    if (length == length >>> 0) {
+      while (++index < length) {
+        callback(object[index], index, object);
+      }
+    } else {
+      forOwn(object, callback);
+    }
+  }
+
+  /**
+   * Trim and conditionally capitalize string values.
+   * @private
+   * @param {String} string The string to format.
+   * @returns {String} The formatted string.
+   */
+  function format(string) {
+    string = trim(string);
+    return /^(?:webOS|i(?:OS|P))/.test(string)
+      ? string
+      : capitalize(string);
+  }
+
+  /**
+   * Iterates over an object's own properties, executing the `callback` for each.
+   * @private
+   * @param {Object} object The object to iterate over.
+   * @param {Function} callback The function executed per own property.
+   */
+  function forOwn(object, callback) {
+    for (var key in object) {
+      hasKey(object, key) && callback(object[key], key, object);
+    }
+  }
+
+  /**
+   * Gets the internal [[Class]] of a value.
+   * @private
+   * @param {Mixed} value The value.
+   * @returns {String} The [[Class]].
+   */
+  function getClassOf(value) {
+    return value == null
+      ? capitalize(value)
+      : toString.call(value).slice(8, -1);
+  }
+
+  /**
+   * Checks if an object has the specified key as a direct property.
+   * @private
+   * @param {Object} object The object to check.
+   * @param {String} key The key to check for.
+   * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
+   */
+  function hasKey() {
+    // lazy define for others (not as accurate)
+    hasKey = function(object, key) {
+      var parent = object != null && (object.constructor || Object).prototype;
+      return !!parent && key in Object(object) && !(key in parent &&
object[key] === parent[key]);
+    };
+    // for modern browsers
+    if (getClassOf(hasOwnProperty) == 'Function') {
+      hasKey = function(object, key) {
+        return object != null && hasOwnProperty.call(object, key);
+      };
+    }
+    // for Safari 2
+    else if ({}.__proto__ == Object.prototype) {
+      hasKey = function(object, key) {
+        var result = false;
+        if (object != null) {
+          object = Object(object);
+          object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in
object][0];
+        }
+        return result;
+      };
+    }
+    return hasKey.apply(this, arguments);
+  }
+
+  /**
+   * Host objects can return type values that are different from their actual
+   * data type. The objects we are concerned with usually return non-primitive
+   * types of object, function, or unknown.
+   * @private
+   * @param {Mixed} object The owner of the property.
+   * @param {String} property The property to check.
+   * @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
+   */
+  function isHostType(object, property) {
+    var type = object != null ? typeof object[property] : 'number';
+    return !/^(?:boolean|number|string|undefined)$/.test(type) &&
+      (type == 'object' ? !!object[property] : true);
+  }
+
+  /**
+   * Prepares a string for use in a RegExp constructor by making hyphens and spaces optional.
+   * @private
+   * @param {String} string The string to qualify.
+   * @returns {String} The qualified string.
+   */
+  function qualify(string) {
+    return String(string).replace(/([ -])(?!$)/g, '$1?');
+  }
+
+  /**
+   * A bare-bones` Array#reduce` like utility function.
+   * @private
+   * @param {Array} array The array to iterate over.
+   * @param {Function} callback The function called per iteration.
+   * @param {Mixed} accumulator Initial value of the accumulator.
+   * @returns {Mixed} The accumulator.
+   */
+  function reduce(array, callback) {
+    var accumulator = null;
+    each(array, function(value, index) {
+      accumulator = callback(accumulator, value, index, array);
+    });
+    return accumulator;
+  }
+
+  /**
+   * Removes leading and trailing whitespace from a string.
+   * @private
+   * @param {String} string The string to trim.
+   * @returns {String} The trimmed string.
+   */
+  function trim(string) {
+    return String(string).replace(/^ +| +$/g, '');
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Creates a new platform object.
+   * @memberOf platform
+   * @param {String} [ua = navigator.userAgent] The user agent string.
+   * @returns {Object} A platform object.
+   */
+  function parse(ua) {
+
+    ua || (ua = userAgent);
+
+    /** Temporary variable used over the script's lifetime */
+    var data;
+
+    /** The CPU architecture */
+    var arch = ua;
+
+    /** Platform description array */
+    var description = [];
+
+    /** Platform alpha/beta indicator */
+    var prerelease = null;
+
+    /** A flag to indicate that environment features should be used to resolve the platform
*/
+    var useFeatures = ua == userAgent;
+
+    /** The browser/environment version */
+    var version = useFeatures && opera && typeof opera.version == 'function'
&& opera.version();
+
+    /* Detectable layout engines (order is important) */
+    var layout = getLayout([
+      { 'label': 'WebKit', 'pattern': 'AppleWebKit' },
+      'iCab',
+      'Presto',
+      'NetFront',
+      'Tasman',
+      'Trident',
+      'KHTML',
+      'Gecko'
+    ]);
+
+    /* Detectable browser names (order is important) */
+    var name = getName([
+      'Adobe AIR',
+      'Arora',
+      'Avant Browser',
+      'Camino',
+      'Epiphany',
+      'Fennec',
+      'Flock',
+      'Galeon',
+      'GreenBrowser',
+      'iCab',
+      'Iceweasel',
+      'Iron',
+      'K-Meleon',
+      'Konqueror',
+      'Lunascape',
+      'Maxthon',
+      'Midori',
+      'Nook Browser',
+      'PhantomJS',
+      'Raven',
+      'Rekonq',
+      'RockMelt',
+      'SeaMonkey',
+      { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk)' },
+      'Sleipnir',
+      'SlimBrowser',
+      'Sunrise',
+      'Swiftfox',
+      'WebPositive',
+      'Opera Mini',
+      'Opera',
+      'Chrome',
+      { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
+      { 'label': 'IE', 'pattern': 'MSIE' },
+      'Safari'
+    ]);
+
+    /* Detectable products (order is important) */
+    var product = getProduct([
+      'BlackBerry',
+      { 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
+      { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
+      'iPad',
+      'iPod',
+      'iPhone',
+      'Kindle',
+      { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk)' },
+      'Nook',
+      'PlayBook',
+      'TouchPad',
+      'Transformer',
+      'Xoom'
+    ]);
+
+    /* Detectable manufacturers */
+    var manufacturer = getManufacturer({
+      'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
+      'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
+      'Asus': { 'Transformer': 1 },
+      'Barnes & Noble': { 'Nook': 1 },
+      'BlackBerry': { 'PlayBook': 1 },
+      'HP': { 'TouchPad': 1 },
+      'LG': { },
+      'Motorola': { 'Xoom': 1 },
+      'Nokia': { },
+      'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 }
+    });
+
+    /* Detectable OSes (order is important) */
+    var os = getOS([
+      'Android',
+      'CentOS',
+      'Debian',
+      'Fedora',
+      'FreeBSD',
+      'Gentoo',
+      'Haiku',
+      'Kubuntu',
+      'Linux Mint',
+      'Red Hat',
+      'SuSE',
+      'Ubuntu',
+      'Xubuntu',
+      'Cygwin',
+      'Symbian OS',
+      'hpwOS',
+      'webOS ',
+      'webOS',
+      'Tablet OS',
+      'Linux',
+      'Mac OS X',
+      'Macintosh',
+      'Mac',
+      'Windows 98;',
+      'Windows '
+    ]);
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Picks the layout engine from an array of guesses.
+     * @private
+     * @param {Array} guesses An array of guesses.
+     * @returns {String|Null} The detected layout engine.
+     */
+    function getLayout(guesses) {
+      return reduce(guesses, function(result, guess) {
+        return result || RegExp('\\b' + (
+          guess.pattern || qualify(guess)
+        ) + '\\b', 'i').exec(ua) && (guess.label || guess);
+      });
+    }
+
+    /**
+     * Picks the manufacturer from an array of guesses.
+     * @private
+     * @param {Array} guesses An array of guesses.
+     * @returns {String|Null} The detected manufacturer.
+     */
+    function getManufacturer(guesses) {
+      return reduce(guesses, function(result, value, key) {
+        // lookup the manufacturer by product or scan the UA for the manufacturer
+        return result || (
+          value[product] ||
+          value[0/*Opera 9.25 fix*/, /^[a-z]+/i.exec(product)] ||
+          RegExp('\\b' + (key.pattern || qualify(key)) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
+        ) && (key.label || key);
+      });
+    }
+
+    /**
+     * Picks the browser name from an array of guesses.
+     * @private
+     * @param {Array} guesses An array of guesses.
+     * @returns {String|Null} The detected browser name.
+     */
+    function getName(guesses) {
+      return reduce(guesses, function(result, guess) {
+        return result || RegExp('\\b' + (
+          guess.pattern || qualify(guess)
+        ) + '\\b', 'i').exec(ua) && (guess.label || guess);
+      });
+    }
+
+    /**
+     * Picks the OS name from an array of guesses.
+     * @private
+     * @param {Array} guesses An array of guesses.
+     * @returns {String|Null} The detected OS name.
+     */
+    function getOS(guesses) {
+      return reduce(guesses, function(result, guess) {
+        var pattern = guess.pattern || qualify(guess);
+        if (!result && (result =
+            RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) {
+          // platform tokens defined at
+          // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
+          // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
+          data = {
+            '6.2':  '8',
+            '6.1':  'Server 2008 R2 / 7',
+            '6.0':  'Server 2008 / Vista',
+            '5.2':  'Server 2003 / XP 64-bit',
+            '5.1':  'XP',
+            '5.01': '2000 SP1',
+            '5.0':  '2000',
+            '4.0':  'NT',
+            '4.90': 'ME'
+          };
+          // detect Windows version from platform tokens
+          if (/^Win/i.test(result) &&
+              (data = data[0/*Opera 9.25 fix*/, /[\d.]+$/.exec(result)])) {
+            result = 'Windows ' + data;
+          }
+          // correct character case and cleanup
+          result = format(String(result)
+            .replace(RegExp(pattern, 'i'), guess.label || guess)
+            .replace(/ ce$/i, ' CE')
+            .replace(/hpw/i, 'web')
+            .replace(/Macintosh/, 'Mac OS')
+            .replace(/_PowerPC/i, ' OS')
+            .replace(/(OS X) [^ \d]+/i, '$1')
+            .replace(/\/(\d)/, ' $1')
+            .replace(/_/g, '.')
+            .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
+            .replace(/x86\.64/gi, 'x86_64')
+            .split(' on ')[0]);
+        }
+        return result;
+      });
+    }
+
+    /**
+     * Picks the product name from an array of guesses.
+     * @private
+     * @param {Array} guesses An array of guesses.
+     * @returns {String|Null} The detected product name.
+     */
+    function getProduct(guesses) {
+      return reduce(guesses, function(result, guess) {
+        var pattern = guess.pattern || qualify(guess);
+        if (!result && (result =
+              RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
+              RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
+            )) {
+          // split by forward slash and append product version if needed
+          if ((result = String(guess.label || result).split('/'))[1] && !/[\d.]+/.test(result[0]))
{
+            result[0] += ' ' + result[1];
+          }
+          // correct character case and cleanup
+          guess = guess.label || guess;
+          result = format(result[0]
+            .replace(RegExp(pattern, 'i'), guess)
+            .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
+            .replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2'));
+        }
+        return result;
+      });
+    }
+
+    /**
+     * Resolves the version using an array of UA patterns.
+     * @private
+     * @param {Array} patterns An array of UA patterns.
+     * @returns {String|Null} The detected version.
+     */
+    function getVersion(patterns) {
+      return reduce(patterns, function(result, pattern) {
+        return result || (RegExp(pattern +
+          '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/-]*)', 'i').exec(ua) || 0)[1]
|| null;
+      });
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Return platform description when the platform object is coerced to a string.
+     * @name toString
+     * @memberOf platform
+     * @type Function
+     * @returns {String} The platform description.
+     */
+    function toStringPlatform() {
+      return this.description || '';
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    // convert layout to an array so we can add extra details
+    layout && (layout = [layout]);
+
+    // detect product names that contain their manufacturer's name
+    if (manufacturer && !product) {
+      product = getProduct([manufacturer]);
+    }
+    // detect simulators
+    if (/\bSimulator\b/i.test(ua)) {
+      product = (product ? product + ' ' : '') + 'Simulator';
+    }
+    // detect iOS
+    if (/^iP/.test(product)) {
+      name || (name = 'Safari');
+      os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
+        ? ' ' + data[1].replace(/_/g, '.')
+        : '');
+    }
+    // detect Kubuntu
+    else if (name == 'Konqueror' && !/buntu/i.test(os)) {
+      os = 'Kubuntu';
+    }
+    // detect Android browsers
+    else if (name == 'Chrome' && manufacturer) {
+      name = 'Android Browser';
+      os = /Android/.test(os) ? os : 'Android';
+    }
+    // detect false positives for Firefox/Safari
+    else if (!name || (data = !/\bMinefield\b/i.test(ua) && /Firefox|Safari/.exec(name)))
{
+      // escape the `/` for Firefox 1
+      if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data
+ '/') + 8))) {
+        // clear name of false positives
+        name = null;
+      }
+      // reassign a generic name
+      if ((data = product || manufacturer || os) &&
+          (product || manufacturer || /Android|Symbian OS|Tablet OS|webOS/.test(os))) {
+        name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser';
+      }
+    }
+    // detect non-Opera versions (order is important)
+    if (!version) {
+      version = getVersion([
+        '(?:Cloud9|Opera ?Mini|Raven|Silk)',
+        'Version',
+        qualify(name),
+        '(?:Firefox|Minefield|NetFront)'
+      ]);
+    }
+    // detect stubborn layout engines
+    if (layout == 'iCab' && parseFloat(version) > 3) {
+      layout = ['WebKit'];
+    } else if (name == 'Konqueror' && /\bKHTML\b/i.test(ua)) {
+      layout = ['KHTML'];
+    } else if (data =
+        /Opera/.test(name) && 'Presto' ||
+        /\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' ||
+        !layout && /\bMSIE\b/i.test(ua) && (/^Mac/.test(os) ? 'Tasman' :
'Trident')) {
+      layout = [data];
+    }
+    // leverage environment features
+    if (useFeatures) {
+      // detect server-side environments
+      // Rhino has a global function while others have a global object
+      if (isHostType(thisBinding, 'global')) {
+        if (java) {
+          data = java.lang.System;
+          arch = data.getProperty('os.arch');
+          os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
+        }
+        if (typeof exports == 'object' && exports) {
+          // if `thisBinding` is the [ModuleScope]
+          if (thisBinding == oldWin && typeof system == 'object' && (data
= [system])[0]) {
+            os || (os = data[0].os || null);
+            try {
+              data[1] = require('ringo/engine').version;
+              version = data[1].join('.');
+              name = 'RingoJS';
+            } catch(e) {
+              if (data[0].global == freeGlobal) {
+                name = 'Narwhal';
+              }
+            }
+          } else if (typeof process == 'object' && (data = process)) {
+            name = 'Node.js';
+            arch = data.arch;
+            os = data.platform;
+            version = /[\d.]+/.exec(data.version)[0];
+          }
+        } else if (getClassOf(window.environment) == 'Environment') {
+          name = 'Rhino';
+        }
+      }
+      // detect Adobe AIR
+      else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') {
+        name = 'Adobe AIR';
+        os = data.flash.system.Capabilities.os;
+      }
+      // detect PhantomJS
+      else if (getClassOf(data = window.phantom) == 'RuntimeObject') {
+        name = 'PhantomJS';
+        version = (data = data.version || null) && (data.major + '.' + data.minor
+ '.' + data.patch);
+      }
+      // detect IE compatibility modes
+      else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua)))
{
+        // we're in compatibility mode when the Trident version + 4 doesn't
+        // equal the document mode
+        version = [version, doc.documentMode];
+        if ((data = +data[1] + 4) != version[1]) {
+          description.push('IE ' + version[1] + ' mode');
+          layout[1] = '';
+          version[1] = data;
+        }
+        version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
+      }
+      os = os && format(os);
+    }
+    // detect prerelease phases
+    if (version && (data =
+        /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
+        /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion))
||
+        /\bMinefield\b/i.test(ua) && 'a')) {
+      prerelease = /b/i.test(data) ? 'beta' : 'alpha';
+      version = version.replace(RegExp(data + '\\+?$'), '') +
+        (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
+    }
+    // obscure Maxthon's unreliable version
+    if (name == 'Maxthon' && version) {
+      version = version.replace(/\.[\d.]+/, '.x');
+    }
+    // detect Silk desktop/accelerated modes
+    else if (name == 'Silk') {
+      if (!/Mobi/i.test(ua)) {
+        os = 'Android';
+        description.unshift('desktop mode');
+      }
+      if (/Accelerated *= *true/i.test(ua)) {
+        description.unshift('accelerated');
+      }
+    }
+    // detect Windows Phone desktop mode
+    else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1]))
{
+      name += ' Mobile';
+      os = 'Windows Phone OS ' + data + '.x';
+      description.unshift('desktop mode');
+    }
+    // add mobile postfix
+    else if ((name == 'IE' || name && !product && !/Browser/.test(name))
&&
+        (os == 'Windows CE' || /Mobi/i.test(ua))) {
+      name += ' Mobile';
+    }
+    // detect IE platform preview
+    else if (name == 'IE' && useFeatures && typeof external == 'object' &&
!external) {
+      description.unshift('platform preview');
+    }
+    // detect BlackBerry OS version
+    // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
+    else if (/BlackBerry/.test(product) && (data =
+        (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
+        version)) {
+      os = 'Device Software ' + data;
+      version = null;
+    }
+    // detect Opera identifying/masking itself as another browser
+    // http://www.opera.com/support/kb/view/843/
+    else if (this != forOwn && (
+          (useFeatures && opera) ||
+          (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
+          (name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
+          (name == 'IE' && (
+            (os && !/^Win/.test(os) && version > 5.5) ||
+            /Windows XP/.test(os) && version > 8 ||
+            version == 8 && !/Trident/.test(ua)
+          ))
+        ) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))
&& data.name) {
+
+      // when "indentifying" the UA contains both Opera and the other browser's name
+      data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
+      if (reOpera.test(name)) {
+        if (/IE/.test(data) && os == 'Mac OS') {
+          os = null;
+        }
+        data = 'identify' + data;
+      }
+      // when "masking" the UA contains only the other browser's name
+      else {
+        data = 'mask' + data;
+        if (operaClass) {
+          name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
+        } else {
+          name = 'Opera';
+        }
+        if (/IE/.test(data)) {
+          os = null;
+        }
+        if (!useFeatures) {
+          version = null;
+        }
+      }
+      layout = ['Presto'];
+      description.push(data);
+    }
+    // detect WebKit Nightly and approximate Chrome/Safari versions
+    if ((data = (/AppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
+      // correct build for numeric comparison
+      // (e.g. "532.5" becomes "532.05")
+      data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
+      // nightly builds are postfixed with a `+`
+      if (name == 'Safari' && data[1].slice(-1) == '+') {
+        name = 'WebKit Nightly';
+        prerelease = 'alpha';
+        version = data[1].slice(0, -1);
+      }
+      // clear incorrect browser versions
+      else if (version == data[1] ||
+          version == (/Safari\/([\d.]+\+?)/i.exec(ua) || 0)[1]) {
+        version = null;
+      }
+      // use the full Chrome version when available
+      data = [data[0], (/Chrome\/([\d.]+)/i.exec(ua) || 0)[1]];
+
+      // detect JavaScriptCore
+      // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
+      if (!useFeatures || (/internal|\n/i.test(toString.toString()) && !data[1]))
{
+        layout[1] = 'like Safari';
+        data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3
: data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5');
+      } else {
+        layout[1] = 'like Chrome';
+        data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data <
532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10
? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30
? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data <
535.11 ? 16 : data < 535.19 ? 17 : data < 535.21 ? 18 : '19');
+      }
+      // add the postfix of ".x" or "+" for approximate versions
+      layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? ''
: '+');
+      // obscure version for some Safari 1-2 releases
+      if (name == 'Safari' && (!version || parseInt(version) > 45)) {
+        version = data;
+      }
+    }
+    // strip incorrect OS versions
+    if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
+        ua.indexOf('/' + data + '-') > -1) {
+      os = trim(os.replace(data, ''));
+    }
+    // add layout engine
+    if (layout && !/Avant|Nook/.test(name) && (
+        /Browser|Lunascape|Maxthon/.test(name) ||
+        /^(?:Adobe|Arora|Midori|Phantom|Rekonq|Rock|Sleipnir|Web)/.test(name) &&
layout[1])) {
+      // don't add layout details to description if they are falsey
+      (data = layout[layout.length - 1]) && description.push(data);
+    }
+    // combine contextual information
+    if (description.length) {
+      description = ['(' + description.join('; ') + ')'];
+    }
+    // append manufacturer
+    if (manufacturer && product && product.indexOf(manufacturer) < 0)
{
+      description.push('on ' + manufacturer);
+    }
+    // append product
+    if (product) {
+      description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product);
+    }
+    // add browser/OS architecture
+    if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i).test(arch) && !/\bi686\b/i.test(arch))
{
+      os = os && os + (data.test(os) ? '' : ' 64-bit');
+      if (name && (/WOW64/i.test(ua) ||
+          (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform)))) {
+        description.unshift('32-bit');
+      }
+    }
+
+    ua || (ua = null);
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * The platform object.
+     * @name platform
+     * @type Object
+     */
+    return {
+
+      /**
+       * The browser/environment version.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'version': name && version && (description.unshift(version), version),
+
+      /**
+       * The name of the browser/environment.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'name': name && (description.unshift(name), name),
+
+      /**
+       * The name of the operating system.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'os': os && (name &&
+        !(os == os.split(' ')[0] && (os == name.split(' ')[0] || product)) &&
+          description.push(product ? '(' + os + ')' : 'on ' + os), os),
+
+      /**
+       * The platform description.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'description': description.length ? description.join(' ') : ua,
+
+      /**
+       * The name of the browser layout engine.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'layout': layout && layout[0],
+
+      /**
+       * The name of the product's manufacturer.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'manufacturer': manufacturer,
+
+      /**
+       * The alpha/beta release indicator.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'prerelease': prerelease,
+
+      /**
+       * The name of the product hosting the browser.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'product': product,
+
+      /**
+       * The browser's user agent string.
+       * @memberOf platform
+       * @type String|Null
+       */
+      'ua': ua,
+
+      // parses a user agent string into a platform object
+      'parse': parse,
+
+      // returns the platform description
+      'toString': toStringPlatform
+    };
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // expose platform
+  // in Narwhal, Node.js, or RingoJS
+  if (freeExports) {
+    forOwn(parse(), function(value, key) {
+      freeExports[key] = value;
+    });
+  }
+  // via an AMD loader
+  else if (typeof define == 'function' && typeof define.amd == 'object' &&
define.amd) {
+    define('platform', function() {
+      return parse();
+    });
+  }
+  // in a browser or Rhino
+  else {
+    // use square bracket notation so Closure Compiler won't munge `platform`
+    // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
+    window['platform'] = parse();
+  }
+}(this));
\ No newline at end of file

Modified: incubator/devicemap/trunk/prototypes/logcapture/logcapture.js
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/prototypes/logcapture/logcapture.js?rev=1302881&r1=1302880&r2=1302881&view=diff
==============================================================================
--- incubator/devicemap/trunk/prototypes/logcapture/logcapture.js (original)
+++ incubator/devicemap/trunk/prototypes/logcapture/logcapture.js Tue Mar 20 13:34:51 2012
@@ -26,6 +26,11 @@
 // start devicemap code scope
 (function() {
 
+// encode a name/value pair for us in our image URL
+function encodeValue(name, value) {
+  return "&" + name + "=" + escape(value);
+}
+
 // return expr, suitably formatted as an URL parameter,
 // invalid expr outputs NOVALUE.
 function getExpr(expr) {
@@ -34,7 +39,7 @@ function getExpr(expr) {
         result = eval(expr);
     } catch(e) {
     }
-    return "&" + expr + "=" + escape(result);
+    return encodeValue(expr, result);
 }
 
 // return prefix.name.propertyName=true if creating an element
@@ -69,6 +74,17 @@ img += getElementSupport("html5","audio"
 img += getElementSupport("html5","video", "play");
 img += getElementSupport("dummy","video", "foo");
 
+// call plugins
+if(window._DMAP_ && window._DMAP_.plugins) {
+  for(i in window._DMAP_.plugins) {
+    var f = window._DMAP_.plugins[i];
+    var data = f.call();
+    for(d in data) {
+      img += encodeValue(d, data[d]);
+    }
+  }
+}
+
 // add img element with computed path + parameters, so
 // that server log provides device information
 function writeDeviceMapInfo(container) {



Mime
View raw message