[tor-commits] [snowflake/master] Feature detect with Modernizr

arlo at torproject.org arlo at torproject.org
Wed Apr 6 17:17:47 UTC 2016


commit d567e2312f45165ff41ec7c66e18f265cbae378b
Author: Arlo Breault <arlolra at gmail.com>
Date:   Tue Apr 5 10:27:41 2016 -0700

    Feature detect with Modernizr
    
     * A start on #34
---
 proxy/Cakefile                   | 19 +++++++++----------
 proxy/coffee-snowflake.html      |  1 +
 proxy/lib/modernizr.js           |  3 +++
 proxy/modernizr-config.json      | 11 +++++++++++
 proxy/package.json               | 11 ++++++-----
 proxy/shims.coffee               | 22 ++++++++++++++--------
 proxy/snowflake.coffee           | 14 +++++---------
 proxy/spec/snowflake.spec.coffee |  2 +-
 proxy/static/embed.html          |  1 +
 proxy/static/snowflake.html      |  1 +
 10 files changed, 52 insertions(+), 33 deletions(-)

diff --git a/proxy/Cakefile b/proxy/Cakefile
index 045468f..513d446 100644
--- a/proxy/Cakefile
+++ b/proxy/Cakefile
@@ -19,32 +19,31 @@ FILES_SPEC = [
   'spec/snowflake.spec.coffee'
 ]
 FILES_ALL = FILES.concat FILES_SPEC
-OUTFILE = 'build/snowflake.coffee'
+OUTFILE = 'build/snowflake.js'
 STATIC = 'static'
 
-concatCoffeeFiles = -> exec 'cat ' + FILES.join(' ') + ' | cat > ' + OUTFILE
-
-copyStaticFiles = -> exec 'cp ' + STATIC + '/* build/'
+copyStaticFiles = ->
+  exec 'cp ' + STATIC + '/* build/'
+  exec 'cp lib/modernizr.js build/'
 
 compileCoffee = ->
-  exec 'coffee -o build -cb ' + OUTFILE, (err, stdout, stderr) ->
+  exec 'cat ' + FILES.join(' ') + ' | coffee -cs > ' + OUTFILE, (err, stdout, stderr) ->
     throw err if err
 
 task 'test', 'snowflake unit tests', ->
-  exec 'mkdir -p build'
+  exec 'mkdir -p test'
   exec 'jasmine init >&-'
   # Simply concat all the files because we're not using node exports.
-  jasmineFiles = FILES.concat FILES_SPEC
-  outFile = 'build/bundle.spec.coffee'
+  jasmineFiles = FILES_ALL
+  outFile = 'test/bundle.spec.coffee'
   exec 'cat ' + jasmineFiles.join(' ') +  ' | cat > ' + outFile
   execSync 'coffee -cb ' + outFile
-  spawn 'jasmine', ['build/bundle.spec.js'], {
+  spawn 'jasmine', ['test/bundle.spec.js'], {
     stdio: 'inherit'
   }
 
 task 'build', 'build the snowflake proxy', ->
   exec 'mkdir -p build'
-  concatCoffeeFiles()
   copyStaticFiles()
   compileCoffee()
   console.log 'Snowflake prepared.'
diff --git a/proxy/coffee-snowflake.html b/proxy/coffee-snowflake.html
index f1f5f90..5f7672c 100644
--- a/proxy/coffee-snowflake.html
+++ b/proxy/coffee-snowflake.html
@@ -3,6 +3,7 @@
 <head>
   <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
   <script type="text/javascript" src="lib/coffee-script.js"></script>
+  <script type="text/javascript" src="lib/modernizr.js"></script>
   <script type="text/coffeescript" src="snowflake.coffee"></script>
   <style>
   * {
diff --git a/proxy/lib/modernizr.js b/proxy/lib/modernizr.js
new file mode 100644
index 0000000..8c77f81
--- /dev/null
+++ b/proxy/lib/modernizr.js
@@ -0,0 +1,3 @@
+/*! modernizr 3.3.1 (Custom Build) | MIT *
+ * http://modernizr.com/download/?-datachannel-peerconnection-websockets-prefixed !*/
+!function(e,n,t){function r(e,n){return typeof e===n}function o(){var e,n,t,o,i,s,a;for(var f in h)if(h.hasOwnProperty(f)){if(e=[],n=h[f],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;t<n.options.aliases.length;t++)e.push(n.options.aliases[t].toLowerCase());for(o=r(n.fn,"function")?n.fn():n.fn,i=0;i<e.length;i++)s=e[i],a=s.split("."),1===a.length?Modernizr[a[0]]=o:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=o),C.push((o?"":"no-")+a.join("-"))}}function i(e,n){return!!~(""+e).indexOf(n)}function s(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):x?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function a(){var e=n.body;return e||(e=s(x?"svg":"body"),e.fake=!0),e}function f(e,t,r,o){var i,f,u,l,d="modernizr",p=s("div"),c=a();if(parseInt(r,10))for(;r--;)u=s("div"),u.id=o?o[r
 ]:d+(r+1),p.appendChild(u);return i=s("style"),i.type="text/css",i.id="s"+d,(c.fake?c:p).appendChild(i),c.appendChild(p),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(n.createTextNode(e)),p.id=d,c.fake&&(c.style.background="",c.style.overflow="hidden",l=S.style.overflow,S.style.overflow="hidden",S.appendChild(c)),f=t(p,e),c.fake?(c.parentNode.removeChild(c),S.style.overflow=l,S.offsetHeight):p.parentNode.removeChild(p),!!f}function u(e){return e.replace(/([A-Z])/g,function(e,n){return"-"+n.toLowerCase()}).replace(/^ms-/,"-ms-")}function l(n,r){var o=n.length;if("CSS"in e&&"supports"in e.CSS){for(;o--;)if(e.CSS.supports(u(n[o]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var i=[];o--;)i.push("("+u(n[o])+":"+r+")");return i=i.join(" or "),f("@supports ("+i+") { #modernizr { position: absolute; } }",function(e){return"absolute"==getComputedStyle(e,null).position})}return t}function d(e){return e.replace(/([a-z])-([a-z])/g,function(e,n,t){return n+t.toUpperCase()}).replace(/^
 -/,"")}function p(e,n,o,a){function f(){p&&(delete T.style,delete T.modElem)}if(a=r(a,"undefined")?!1:a,!r(o,"undefined")){var u=l(e,o);if(!r(u,"undefined"))return u}for(var p,c,m,v,h,y=["modernizr","tspan"];!T.style;)p=!0,T.modElem=s(y.shift()),T.style=T.modElem.style;for(m=e.length,c=0;m>c;c++)if(v=e[c],h=T.style[v],i(v,"-")&&(v=d(v)),T.style[v]!==t){if(a||r(o,"undefined"))return f(),"pfx"==n?v:!0;try{T.style[v]=o}catch(C){}if(T.style[v]!=h)return f(),"pfx"==n?v:!0}return f(),!1}function c(e,n){return function(){return e.apply(n,arguments)}}function m(e,n,t){var o;for(var i in e)if(e[i]in n)return t===!1?e[i]:(o=n[e[i]],r(o,"function")?c(o,t||n):o);return!1}function v(e,n,t,o,i){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+w.join(s+" ")+s).split(" ");return r(n,"string")||r(n,"undefined")?p(a,n,o,i):(a=(e+" "+b.join(s+" ")+s).split(" "),m(a,n,t))}var h=[],y={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var
  t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){h.push({name:e,fn:n,options:t})},addAsyncTest:function(e){h.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=y,Modernizr=new Modernizr;var C=[],g="Moz O ms Webkit",w=y._config.usePrefixes?g.split(" "):[];y._cssomPrefixes=w;var S=n.documentElement,x="svg"===S.nodeName.toLowerCase(),_={elem:s("modernizr")};Modernizr._q.push(function(){delete _.elem});var T={style:_.elem.style};Modernizr._q.unshift(function(){delete T.style});var b=y._config.usePrefixes?g.toLowerCase().split(" "):[];y._domPrefixes=b,y.testAllProps=v;var E=function(n){var r,o=prefixes.length,i=e.CSSRule;if("undefined"==typeof i)return t;if(!n)return!1;if(n=n.replace(/^@/,""),r=n.replace(/-/g,"_").toUpperCase()+"_RULE",r in i)return"@"+n;for(var s=0;o>s;s++){var a=prefixes[s],f=a.toUpperCase()+"_"+r;if(f in i)return"@-"+a.toLowerCase()+"-"+n}return!1};y.atRule=E;var P=y.prefixed=function(e,n,t){return 0===e.indexOf("@")?E(e):(-1!=e.inde
 xOf("-")&&(e=d(e)),n?v(e,n,t):v(e,"pfx"))};Modernizr.addTest("websockets","WebSocket"in e&&2===e.WebSocket.CLOSING),Modernizr.addTest("peerconnection",!!P("RTCPeerConnection",e)),Modernizr.addTest("datachannel",function(){if(!Modernizr.peerconnection)return!1;for(var n=0,t=b.length;t>n;n++){var r=e[b[n]+"RTCPeerConnection"];if(r){var o=new r({iceServers:[{url:"stun:0"}]});return"createDataChannel"in o}}return!1}),o(),delete y.addTest,delete y.addAsyncTest;for(var k=0;k<Modernizr._q.length;k++)Modernizr._q[k]();e.Modernizr=Modernizr}(window,document);
\ No newline at end of file
diff --git a/proxy/modernizr-config.json b/proxy/modernizr-config.json
new file mode 100644
index 0000000..1cad4d3
--- /dev/null
+++ b/proxy/modernizr-config.json
@@ -0,0 +1,11 @@
+{
+  "minify": true,
+  "options": [
+    "prefixed"
+  ],
+  "feature-detects": [
+    "test/websockets",
+    "test/webrtc/datachannel",
+    "test/webrtc/peerconnection"
+  ]
+}
\ No newline at end of file
diff --git a/proxy/package.json b/proxy/package.json
index b7e44df..d276472 100644
--- a/proxy/package.json
+++ b/proxy/package.json
@@ -9,15 +9,16 @@
   "scripts": {
     "test": "cake test",
     "lint": "cake lint",
-    "build": "cake build"
+    "build": "cake build",
+    "clean": "cake clean",
+    "modern": "modernizr -c modernizr-config.json -d lib/"
   },
   "author": "Serene Han",
   "license": "BSD-3-Clause",
   "devDependencies": {
+    "coffee-script": "^1.10.0",
     "coffeelint": "^1.15.0",
-    "jasmine": "^2.4.1"
-  },
-  "dependencies": {
-    "coffee-script": "^1.10.0"
+    "jasmine": "^2.4.1",
+    "modernizr": "^3.3.1"
   }
 }
diff --git a/proxy/shims.coffee b/proxy/shims.coffee
index 9fc2fb4..ef5fbb5 100644
--- a/proxy/shims.coffee
+++ b/proxy/shims.coffee
@@ -2,13 +2,19 @@
 WebrTC shims for multiple browsers.
 ###
 
-if 'undefined' != typeof module && 'undefined' != typeof module.exports
-  console.log 'not in browser.'
+if typeof module isnt 'undefined' and module.exports
+  window = {}
 else
-  window.PeerConnection = window.RTCPeerConnection ||
-                          window.mozRTCPeerConnection ||
-                          window.webkitRTCPeerConnection
-  window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate
-  window.RTCSessionDescription = window.RTCSessionDescription ||
-                                 window.mozRTCSessionDescription
+  window = this
+  prop = Modernizr.prefixed 'RTCPeerConnection', window, false
+  if not prop
+    console.log 'webrtc feature not detected. shutting down'
+    return;
 
+  PeerConnection = window[prop]
+
+  ### FIXME: push these upstream ###
+  IceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate
+  SessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription
+
+location = if window.location then window.location.search.substr(1) else ""
diff --git a/proxy/snowflake.coffee b/proxy/snowflake.coffee
index a96dbdf..f325d90 100644
--- a/proxy/snowflake.coffee
+++ b/proxy/snowflake.coffee
@@ -15,13 +15,9 @@ COPY_PASTE_ENABLED = false
 
 DEBUG = false
 silenceNotifications = false
-query = null
-if 'undefined' != typeof window && window.location
-  query = Query.parse(window.location.search.substr(1))
-  DEBUG = Params.getBool(query, 'debug', false)
-  COPY_PASTE_ENABLED = Params.getBool(query, 'manual', false)
-else
-  window = {}
+query = Query.parse(location)
+DEBUG = Params.getBool(query, 'debug', false)
+COPY_PASTE_ENABLED = Params.getBool(query, 'manual', false)
 
 # Bytes per second. Set to undefined to disable limit.
 DEFAULT_RATE_LIMIT = DEFAULT_RATE_LIMIT || undefined
@@ -129,7 +125,7 @@ class Snowflake
     try
       offer = JSON.parse desc
       dbg 'Received:\n\n' + offer.sdp + '\n'
-      sdp = new RTCSessionDescription offer
+      sdp = new SessionDescription offer
       @sendAnswer pair if pair.receiveWebRTCOffer sdp
     catch e
       log 'ERROR: Unable to receive Offer: ' + e
@@ -230,4 +226,4 @@ window.onunload = ->
   pair.close() for pair in snowflake.proxyPairs
   null
 
-window.onload = init if window
+window.onload = init
diff --git a/proxy/spec/snowflake.spec.coffee b/proxy/spec/snowflake.spec.coffee
index 417b6e6..2865795 100644
--- a/proxy/spec/snowflake.spec.coffee
+++ b/proxy/spec/snowflake.spec.coffee
@@ -5,7 +5,7 @@ jasmine tests for Snowflake
 query = {}
 # Fake browser functionality:
 class PeerConnection
-class RTCSessionDescription
+class SessionDescription
   type: 'offer'
 class WebSocket
   OPEN: 1
diff --git a/proxy/static/embed.html b/proxy/static/embed.html
index 5d68576..2557e58 100644
--- a/proxy/static/embed.html
+++ b/proxy/static/embed.html
@@ -2,6 +2,7 @@
 <html>
 <head>
   <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
+  <script type="text/javascript" src="modernizr.js"></script>
   <script type="text/javascript" src="snowflake.js"></script>
   <style>
   * {
diff --git a/proxy/static/snowflake.html b/proxy/static/snowflake.html
index b6d984a..c2bcef5 100644
--- a/proxy/static/snowflake.html
+++ b/proxy/static/snowflake.html
@@ -2,6 +2,7 @@
 <html>
 <head>
   <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
+  <script type="text/javascript" src="modernizr.js"></script>
   <script type="text/javascript" src="snowflake.js"></script>
   <style>
   * {



More information about the tor-commits mailing list