da-suspenders 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 1.2.2 (2012-02-07)
2
+ * Added "Aristo" theme for jQuery UI (via the jquery-rails-aristo gem).
3
+ * Added "da-js" JavaScript library.
4
+ * Updated Modernizr to v2.5.1.
5
+
1
6
  ## 1.2.1 (2012-02-03)
2
7
  * Add --with-mongoid option to create an app with Mongoid instead of ActiveRecord/MySQL.
3
8
  * Use bleeding edge versions of compass and compass-rails to make it work with Rails 3.2.
data/README.md CHANGED
@@ -13,11 +13,19 @@ Then run:
13
13
 
14
14
  da-suspenders create projectname
15
15
 
16
- This will create a Rails 3 app in `projectname'. This script creates a new git repository. It is not meant to be used against an existing repo.
16
+ This will create a Rails 3.2 app in `projectname`. This script creates a new git repository. It is not meant to be used against an existing repo.
17
+
18
+ ### Mongoid
19
+ If you want to create an app using [Mongoid](http://mongoid.org/) pass the `--with-mongoid` option:
20
+
21
+ da-suspenders create projectname --with-mongoid
22
+
23
+
24
+ ### Trout
17
25
 
18
26
  Suspenders uses [Trout](https://github.com/thoughtbot/trout) to make it easier to maintain a base version of special files (like Gemfile) in Suspenders.
19
27
 
20
- Whenever you want to get the latest and greatest Suspenders' Gemfile, run:
28
+ Whenever you want to get the latest and greatest DA-Suspenders' Gemfile, run:
21
29
 
22
30
  trout update Gemfile
23
31
 
@@ -36,10 +44,12 @@ It includes application gems like:
36
44
  * [Devise](https://github.com/plataformatec/devise) and [CanCan](https://github.com/ryanb/cancan) for authentication and authorization
37
45
  * [AppConfig](https://github.com/die-antwort/app_config) for simple application configuration
38
46
  * [Airbrake](https://github.com/thoughtbot/airbrake) for exception notification
47
+ * [jquery-rails-aristo](https://github.com/die-antwort/jquery-rails-aristo), a beautiful theme for jQuery UI
48
+ * [da-js](https://github.com/die-antwort/da-js), our collection of small, useful JavaScripts
39
49
 
40
50
  And testing gems like:
41
51
 
42
- * [Cucumber, Capybara, and Akephalos](http://robots.thoughtbot.com/post/1658763359/thoughtbot-and-the-holy-grail) for integration testing, including Javascript behavior
52
+ * [Cucumber, Capybara, and Capybara-Webkit](http://robots.thoughtbot.com/post/4583605733/capybara-webkit) for integration testing, including Javascript behavior
43
53
  * [RSpec](https://github.com/rspec/rspec) for awesome, readable isolation testing
44
54
  * [Factory Girl](https://github.com/thoughtbot/factory_girl) for easier creation of test data
45
55
  * [Timecop](https://github.com/jtrupiano/timecop) for dealing with time
@@ -1,3 +1,3 @@
1
1
  module DaSuspenders
2
- VERSION = "1.2.1"
2
+ VERSION = "1.2.2"
3
3
  end
@@ -19,6 +19,8 @@ gem "app_config", :git => "git://github.com/die-antwort/app_config.git"
19
19
  gem "formtastic", ">= 2.1.0.beta1"
20
20
  gem "airbrake"
21
21
  gem "will_paginate", "~> 3.0"
22
+ gem "jquery-rails-aristo"
23
+ gem "da-js"
22
24
 
23
25
  # Optional gems (from Rails 3.2 default Gemfile):
24
26
 
@@ -6,5 +6,6 @@
6
6
  # require jquery-ui
7
7
  # require jquery-ui-i18n
8
8
 
9
+ #= require da-js
9
10
  #= require_tree .
10
11
 
@@ -1,5 +1,12 @@
1
+ //= require "formtastic"
2
+ //
3
+ // Remove if not using jQuery UI:
4
+ //= require jqueryui-aristo/aristo
5
+ //
6
+ //= require_self
7
+ //= require_tree .
8
+
1
9
  @import 'compass/reset';
2
10
  @import 'compass/utilities';
3
11
  @import 'compass/css3';
4
12
 
5
- @import 'formtastic';
@@ -1,30 +1,1170 @@
1
+ /*!
2
+ * Modernizr v2.5.1
3
+ * www.modernizr.com
4
+ *
5
+ * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
6
+ * Available under the BSD and MIT licenses: www.modernizr.com/license/
7
+ */
8
+
1
9
  /*
2
- * Modernizr v1.6
3
- * http://www.modernizr.com
10
+ * Modernizr tests which native CSS3 and HTML5 features are available in
11
+ * the current UA and makes the results available to you in two ways:
12
+ * as properties on a global Modernizr object, and as classes on the
13
+ * <html> element. This information allows you to progressively enhance
14
+ * your pages with a granular level of control over the experience.
4
15
  *
5
- * Developed by:
6
- * - Faruk Ates http://farukat.es/
7
- * - Paul Irish http://paulirish.com/
16
+ * Modernizr has an optional (not included) conditional resource loader
17
+ * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
18
+ * To get a build that includes Modernizr.load(), as well as choosing
19
+ * which tests to include, go to www.modernizr.com/download/
8
20
  *
9
- * Copyright (c) 2009-2010
10
- * Dual-licensed under the BSD or MIT licenses.
11
- * http://www.modernizr.com/license/
21
+ * Authors Faruk Ates, Paul Irish, Alex Sexton
22
+ * Contributors Ryan Seddon, Ben Alman
12
23
  */
13
- window.Modernizr=function(i,e,u){function s(a,b){return(""+a).indexOf(b)!==-1}function D(a,b){for(var c in a)if(j[a[c]]!==u&&(!b||b(a[c],E)))return true}function n(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1);c=(a+" "+F.join(c+" ")+c).split(" ");return!!D(c,b)}function S(){f.input=function(a){for(var b=0,c=a.length;b<c;b++)L[a[b]]=!!(a[b]in h);return L}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" "));f.inputtypes=function(a){for(var b=0,c,k=a.length;b<
14
- k;b++){h.setAttribute("type",a[b]);if(c=h.type!=="text"){h.value=M;if(/^range$/.test(h.type)&&h.style.WebkitAppearance!==u){l.appendChild(h);c=e.defaultView;c=c.getComputedStyle&&c.getComputedStyle(h,null).WebkitAppearance!=="textfield"&&h.offsetHeight!==0;l.removeChild(h)}else/^(search|tel)$/.test(h.type)||(c=/^(url|email)$/.test(h.type)?h.checkValidity&&h.checkValidity()===false:h.value!=M)}N[a[b]]=!!c}return N}("search tel url email datetime date month week time datetime-local number range color".split(" "))}
15
- var f={},l=e.documentElement,E=e.createElement("modernizr"),j=E.style,h=e.createElement("input"),M=":)",O=Object.prototype.toString,q=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),F="Webkit Moz O ms Khtml".split(" "),v={svg:"http://www.w3.org/2000/svg"},d={},N={},L={},P=[],w,Q=function(a){var b=document.createElement("style"),c=e.createElement("div");b.textContent=a+"{#modernizr{height:3px}}";(e.head||e.getElementsByTagName("head")[0]).appendChild(b);c.id="modernizr";l.appendChild(c);a=c.offsetHeight===
16
- 3;b.parentNode.removeChild(b);c.parentNode.removeChild(c);return!!a},o=function(){var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return function(b,c){c=c||document.createElement(a[b]||"div");b="on"+b;var k=b in c;if(!k){c.setAttribute||(c=document.createElement("div"));if(c.setAttribute&&c.removeAttribute){c.setAttribute(b,"");k=typeof c[b]=="function";if(typeof c[b]!="undefined")c[b]=u;c.removeAttribute(b)}}return k}}(),G={}.hasOwnProperty,R;R=
17
- typeof G!=="undefined"&&typeof G.call!=="undefined"?function(a,b){return G.call(a,b)}:function(a,b){return b in a&&typeof a.constructor.prototype[b]==="undefined"};d.flexbox=function(){var a=e.createElement("div"),b=e.createElement("div");(function(k,g,r,x){g+=":";k.style.cssText=(g+q.join(r+";"+g)).slice(0,-g.length)+(x||"")})(a,"display","box","width:42px;padding:0;");b.style.cssText=q.join("box-flex:1;")+"width:10px;";a.appendChild(b);l.appendChild(a);var c=b.offsetWidth===42;a.removeChild(b);
18
- l.removeChild(a);return c};d.canvas=function(){var a=e.createElement("canvas");return!!(a.getContext&&a.getContext("2d"))};d.canvastext=function(){return!!(f.canvas&&typeof e.createElement("canvas").getContext("2d").fillText=="function")};d.webgl=function(){var a=e.createElement("canvas");try{if(a.getContext("webgl"))return true}catch(b){}try{if(a.getContext("experimental-webgl"))return true}catch(c){}return false};d.touch=function(){return"ontouchstart"in i||Q("@media ("+q.join("touch-enabled),(")+
19
- "modernizr)")};d.geolocation=function(){return!!navigator.geolocation};d.postmessage=function(){return!!i.postMessage};d.websqldatabase=function(){return!!i.openDatabase};d.indexedDB=function(){for(var a=-1,b=F.length;++a<b;){var c=F[a].toLowerCase();if(i[c+"_indexedDB"]||i[c+"IndexedDB"])return true}return false};d.hashchange=function(){return o("hashchange",i)&&(document.documentMode===u||document.documentMode>7)};d.history=function(){return!!(i.history&&history.pushState)};d.draganddrop=function(){return o("drag")&&
20
- o("dragstart")&&o("dragenter")&&o("dragover")&&o("dragleave")&&o("dragend")&&o("drop")};d.websockets=function(){return"WebSocket"in i};d.rgba=function(){j.cssText="background-color:rgba(150,255,150,.5)";return s(j.backgroundColor,"rgba")};d.hsla=function(){j.cssText="background-color:hsla(120,40%,100%,.5)";return s(j.backgroundColor,"rgba")||s(j.backgroundColor,"hsla")};d.multiplebgs=function(){j.cssText="background:url(//:),url(//:),red url(//:)";return/(url\s*\(.*?){3}/.test(j.background)};d.backgroundsize=
21
- function(){return n("backgroundSize")};d.borderimage=function(){return n("borderImage")};d.borderradius=function(){return n("borderRadius","",function(a){return s(a,"orderRadius")})};d.boxshadow=function(){return n("boxShadow")};d.textshadow=function(){return e.createElement("div").style.textShadow===""};d.opacity=function(){var a=q.join("opacity:.5;")+"";j.cssText=a;return s(j.opacity,"0.5")};d.cssanimations=function(){return n("animationName")};d.csscolumns=function(){return n("columnCount")};d.cssgradients=
22
- function(){var a=("background-image:"+q.join("gradient(linear,left top,right bottom,from(#9f9),to(white));background-image:")+q.join("linear-gradient(left top,#9f9, white);background-image:")).slice(0,-17);j.cssText=a;return s(j.backgroundImage,"gradient")};d.cssreflections=function(){return n("boxReflect")};d.csstransforms=function(){return!!D(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])};d.csstransforms3d=function(){var a=!!D(["perspectiveProperty","WebkitPerspective",
23
- "MozPerspective","OPerspective","msPerspective"]);if(a)a=Q("@media ("+q.join("transform-3d),(")+"modernizr)");return a};d.csstransitions=function(){return n("transitionProperty")};d.fontface=function(){var a,b=e.head||e.getElementsByTagName("head")[0]||l,c=e.createElement("style"),k=e.implementation||{hasFeature:function(){return false}};c.type="text/css";b.insertBefore(c,b.firstChild);a=c.sheet||c.styleSheet;b=k.hasFeature("CSS2","")?function(g){if(!(a&&g))return false;var r=false;try{a.insertRule(g,
24
- 0);r=!/unknown/i.test(a.cssRules[0].cssText);a.deleteRule(a.cssRules.length-1)}catch(x){}return r}:function(g){if(!(a&&g))return false;a.cssText=g;return a.cssText.length!==0&&!/unknown/i.test(a.cssText)&&a.cssText.replace(/\r+|\n+/g,"").indexOf(g.split(" ")[0])===0};f._fontfaceready=function(g){g(f.fontface)};return b('@font-face { font-family: "font"; src: "font.ttf"; }')};d.video=function(){var a=e.createElement("video"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('video/ogg; codecs="theora"');
25
- b.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"')||a.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');b.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return b};d.audio=function(){var a=e.createElement("audio"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('audio/ogg; codecs="vorbis"');b.mp3=a.canPlayType("audio/mpeg;");b.wav=a.canPlayType('audio/wav; codecs="1"');b.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}return b};d.localstorage=function(){try{return"localStorage"in
26
- i&&i.localStorage!==null}catch(a){return false}};d.sessionstorage=function(){try{return"sessionStorage"in i&&i.sessionStorage!==null}catch(a){return false}};d.webWorkers=function(){return!!i.Worker};d.applicationcache=function(){return!!i.applicationCache};d.svg=function(){return!!e.createElementNS&&!!e.createElementNS(v.svg,"svg").createSVGRect};d.inlinesvg=function(){var a=document.createElement("div");a.innerHTML="<svg/>";return(a.firstChild&&a.firstChild.namespaceURI)==v.svg};d.smil=function(){return!!e.createElementNS&&
27
- /SVG/.test(O.call(e.createElementNS(v.svg,"animate")))};d.svgclippaths=function(){return!!e.createElementNS&&/SVG/.test(O.call(e.createElementNS(v.svg,"clipPath")))};for(var H in d)if(R(d,H)){w=H.toLowerCase();f[w]=d[H]();P.push((f[w]?"":"no-")+w)}f.input||S();f.crosswindowmessaging=f.postmessage;f.historymanagement=f.history;f.addTest=function(a,b){a=a.toLowerCase();if(!f[a]){b=!!b();l.className+=" "+(b?"":"no-")+a;f[a]=b;return f}};j.cssText="";E=h=null;i.attachEvent&&function(){var a=e.createElement("div");
28
- a.innerHTML="<elem></elem>";return a.childNodes.length!==1}()&&function(a,b){function c(p){for(var m=-1;++m<r;)p.createElement(g[m])}function k(p,m){for(var I=p.length,t=-1,y,J=[];++t<I;){y=p[t];m=y.media||m;J.push(k(y.imports,m));J.push(y.cssText)}return J.join("")}var g="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video".split("|"),r=g.length,x=RegExp("<(/*)(abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video)",
29
- "gi"),T=RegExp("\\b(abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video)\\b(?!.*[;}])","gi"),z=b.createDocumentFragment(),A=b.documentElement,K=A.firstChild,B=b.createElement("style"),C=b.createElement("body");B.media="all";c(b);c(z);a.attachEvent("onbeforeprint",function(){for(var p=-1;++p<r;)for(var m=b.getElementsByTagName(g[p]),I=m.length,t=-1;++t<I;)if(m[t].className.indexOf("iepp_")<0)m[t].className+=" iepp_"+
30
- g[p];K.insertBefore(B,K.firstChild);B.styleSheet.cssText=k(b.styleSheets,"all").replace(T,".iepp_$1");z.appendChild(b.body);A.appendChild(C);C.innerHTML=z.firstChild.innerHTML.replace(x,"<$1bdo")});a.attachEvent("onafterprint",function(){C.innerHTML="";A.removeChild(C);K.removeChild(B);A.appendChild(z.firstChild)})}(this,document);f._enableHTML5=true;f._version="1.6";l.className=l.className.replace(/\bno-js\b/,"")+" js";l.className+=" "+P.join(" ");return f}(this,this.document);
24
+
25
+ window.Modernizr = (function( window, document, undefined ) {
26
+
27
+ var version = '2.5.1',
28
+
29
+ Modernizr = {},
30
+
31
+ // option for enabling the HTML classes to be added
32
+ enableClasses = true,
33
+
34
+ docElement = document.documentElement,
35
+
36
+ /**
37
+ * Create our "modernizr" element that we do most feature tests on.
38
+ */
39
+ mod = 'modernizr',
40
+ modElem = document.createElement(mod),
41
+ mStyle = modElem.style,
42
+
43
+ /**
44
+ * Create the input element for various Web Forms feature tests.
45
+ */
46
+ inputElem = document.createElement('input'),
47
+
48
+ smile = ':)',
49
+
50
+ toString = {}.toString,
51
+
52
+ // List of property values to set for css tests. See ticket #21
53
+ prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
54
+
55
+ // Following spec is to expose vendor-specific style properties as:
56
+ // elem.style.WebkitBorderRadius
57
+ // and the following would be incorrect:
58
+ // elem.style.webkitBorderRadius
59
+
60
+ // Webkit ghosts their properties in lowercase but Opera & Moz do not.
61
+ // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
62
+ // erik.eae.net/archives/2008/03/10/21.48.10/
63
+
64
+ // More here: github.com/Modernizr/Modernizr/issues/issue/21
65
+ omPrefixes = 'Webkit Moz O ms',
66
+
67
+ cssomPrefixes = omPrefixes.split(' '),
68
+
69
+ domPrefixes = omPrefixes.toLowerCase().split(' '),
70
+
71
+ ns = {'svg': 'http://www.w3.org/2000/svg'},
72
+
73
+ tests = {},
74
+ inputs = {},
75
+ attrs = {},
76
+
77
+ classes = [],
78
+
79
+ featureName, // used in testing loop
80
+
81
+
82
+ // Inject element with style element and some CSS rules
83
+ injectElementWithStyles = function( rule, callback, nodes, testnames ) {
84
+
85
+ var style, ret, node,
86
+ div = document.createElement('div'),
87
+ // After page load injecting a fake body doesn't work so check if body exists
88
+ body = document.body,
89
+ // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it.
90
+ fakeBody = body ? body : document.createElement('body');
91
+
92
+ if ( parseInt(nodes, 10) ) {
93
+ // In order not to give false positives we create a node for each test
94
+ // This also allows the method to scale for unspecified uses
95
+ while ( nodes-- ) {
96
+ node = document.createElement('div');
97
+ node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
98
+ div.appendChild(node);
99
+ }
100
+ }
101
+
102
+ // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
103
+ // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
104
+ // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
105
+ // msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
106
+ // Documents served as xml will throw if using &shy; so use xml friendly encoded version. See issue #277
107
+ style = ['&#173;','<style>', rule, '</style>'].join('');
108
+ div.id = mod;
109
+ // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
110
+ // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
111
+ fakeBody.innerHTML += style;
112
+ fakeBody.appendChild(div);
113
+ docElement.appendChild(fakeBody);
114
+
115
+ ret = callback(div, rule);
116
+ // If this is done after page load we don't want to remove the body so check if body exists
117
+ !body ? fakeBody.parentNode.removeChild(fakeBody) : div.parentNode.removeChild(div);
118
+
119
+ return !!ret;
120
+
121
+ },
122
+
123
+
124
+ // adapted from matchMedia polyfill
125
+ // by Scott Jehl and Paul Irish
126
+ // gist.github.com/786768
127
+ testMediaQuery = function( mq ) {
128
+
129
+ var matchMedia = window.matchMedia || window.msMatchMedia;
130
+ if ( matchMedia ) {
131
+ return matchMedia(mq).matches;
132
+ }
133
+
134
+ var bool;
135
+
136
+ injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
137
+ bool = (window.getComputedStyle ?
138
+ getComputedStyle(node, null) :
139
+ node.currentStyle)['position'] == 'absolute';
140
+ });
141
+
142
+ return bool;
143
+
144
+ },
145
+
146
+
147
+ /**
148
+ * isEventSupported determines if a given element supports the given event
149
+ * function from yura.thinkweb2.com/isEventSupported/
150
+ */
151
+ isEventSupported = (function() {
152
+
153
+ var TAGNAMES = {
154
+ 'select': 'input', 'change': 'input',
155
+ 'submit': 'form', 'reset': 'form',
156
+ 'error': 'img', 'load': 'img', 'abort': 'img'
157
+ };
158
+
159
+ function isEventSupported( eventName, element ) {
160
+
161
+ element = element || document.createElement(TAGNAMES[eventName] || 'div');
162
+ eventName = 'on' + eventName;
163
+
164
+ // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
165
+ var isSupported = eventName in element;
166
+
167
+ if ( !isSupported ) {
168
+ // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
169
+ if ( !element.setAttribute ) {
170
+ element = document.createElement('div');
171
+ }
172
+ if ( element.setAttribute && element.removeAttribute ) {
173
+ element.setAttribute(eventName, '');
174
+ isSupported = is(element[eventName], 'function');
175
+
176
+ // If property was created, "remove it" (by setting value to `undefined`)
177
+ if ( !is(element[eventName], 'undefined') ) {
178
+ element[eventName] = undefined;
179
+ }
180
+ element.removeAttribute(eventName);
181
+ }
182
+ }
183
+
184
+ element = null;
185
+ return isSupported;
186
+ }
187
+ return isEventSupported;
188
+ })();
189
+
190
+ // hasOwnProperty shim by kangax needed for Safari 2.0 support
191
+ var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
192
+ if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
193
+ hasOwnProperty = function (object, property) {
194
+ return _hasOwnProperty.call(object, property);
195
+ };
196
+ }
197
+ else {
198
+ hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
199
+ return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
200
+ };
201
+ }
202
+
203
+ // Taken from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
204
+ // ES-5 15.3.4.5
205
+ // http://es5.github.com/#x15.3.4.5
206
+
207
+ if (!Function.prototype.bind) {
208
+ Function.prototype.bind = function bind(that) {
209
+
210
+ var target = this;
211
+
212
+ if (typeof target != "function") {
213
+ throw new TypeError();
214
+ }
215
+
216
+ var args = slice.call(arguments, 1),
217
+ bound = function () {
218
+
219
+ if (this instanceof bound) {
220
+
221
+ var F = function(){};
222
+ F.prototype = target.prototype;
223
+ var self = new F;
224
+
225
+ var result = target.apply(
226
+ self,
227
+ args.concat(slice.call(arguments))
228
+ );
229
+ if (Object(result) === result) {
230
+ return result;
231
+ }
232
+ return self;
233
+
234
+ } else {
235
+
236
+ return target.apply(
237
+ that,
238
+ args.concat(slice.call(arguments))
239
+ );
240
+
241
+ }
242
+
243
+ };
244
+
245
+ return bound;
246
+ };
247
+ }
248
+
249
+ /**
250
+ * setCss applies given styles to the Modernizr DOM node.
251
+ */
252
+ function setCss( str ) {
253
+ mStyle.cssText = str;
254
+ }
255
+
256
+ /**
257
+ * setCssAll extrapolates all vendor-specific css strings.
258
+ */
259
+ function setCssAll( str1, str2 ) {
260
+ return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
261
+ }
262
+
263
+ /**
264
+ * is returns a boolean for if typeof obj is exactly type.
265
+ */
266
+ function is( obj, type ) {
267
+ return typeof obj === type;
268
+ }
269
+
270
+ /**
271
+ * contains returns a boolean for if substr is found within str.
272
+ */
273
+ function contains( str, substr ) {
274
+ return !!~('' + str).indexOf(substr);
275
+ }
276
+
277
+ /**
278
+ * testProps is a generic CSS / DOM property test; if a browser supports
279
+ * a certain property, it won't return undefined for it.
280
+ * A supported CSS property returns empty string when its not yet set.
281
+ */
282
+ function testProps( props, prefixed ) {
283
+ for ( var i in props ) {
284
+ if ( mStyle[ props[i] ] !== undefined ) {
285
+ return prefixed == 'pfx' ? props[i] : true;
286
+ }
287
+ }
288
+ return false;
289
+ }
290
+
291
+ /**
292
+ * testDOMProps is a generic DOM property test; if a browser supports
293
+ * a certain property, it won't return undefined for it.
294
+ */
295
+ function testDOMProps( props, obj, elem ) {
296
+ for ( var i in props ) {
297
+ var item = obj[props[i]];
298
+ if ( item !== undefined) {
299
+
300
+ // return the property name as a string
301
+ if (elem === false) return props[i];
302
+
303
+ // let's bind a function
304
+ if (is(item, 'function')){
305
+ // default to autobind unless override
306
+ return item.bind(elem || obj);
307
+ }
308
+
309
+ // return the unbound function or obj or value
310
+ return item;
311
+ }
312
+ }
313
+ return false;
314
+ }
315
+
316
+ /**
317
+ * testPropsAll tests a list of DOM properties we want to check against.
318
+ * We specify literally ALL possible (known and/or likely) properties on
319
+ * the element including the non-vendor prefixed one, for forward-
320
+ * compatibility.
321
+ */
322
+ function testPropsAll( prop, prefixed, elem ) {
323
+
324
+ var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
325
+ props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
326
+
327
+ // did they call .prefixed('boxSizing') or are we just testing a prop?
328
+ if(is(prefixed, "string") || is(prefixed, "undefined")) {
329
+ return testProps(props, prefixed);
330
+
331
+ // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
332
+ } else {
333
+ props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
334
+ return testDOMProps(props, prefixed, elem);
335
+ }
336
+ }
337
+
338
+ /**
339
+ * testBundle tests a list of CSS features that require element and style injection.
340
+ * By bundling them together we can reduce the need to touch the DOM multiple times.
341
+ */
342
+ /*>>testBundle*/
343
+ var testBundle = (function( styles, tests ) {
344
+ var style = styles.join(''),
345
+ len = tests.length;
346
+
347
+ injectElementWithStyles(style, function( node, rule ) {
348
+ var style = document.styleSheets[document.styleSheets.length - 1],
349
+ // IE8 will bork if you create a custom build that excludes both fontface and generatedcontent tests.
350
+ // So we check for cssRules and that there is a rule available
351
+ // More here: github.com/Modernizr/Modernizr/issues/288 & github.com/Modernizr/Modernizr/issues/293
352
+ cssText = style ? (style.cssRules && style.cssRules[0] ? style.cssRules[0].cssText : style.cssText || '') : '',
353
+ children = node.childNodes, hash = {};
354
+
355
+ while ( len-- ) {
356
+ hash[children[len].id] = children[len];
357
+ }
358
+
359
+ /*>>touch*/ Modernizr['touch'] = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch || (hash['touch'] && hash['touch'].offsetTop) === 9; /*>>touch*/
360
+ /*>>csstransforms3d*/ Modernizr['csstransforms3d'] = (hash['csstransforms3d'] && hash['csstransforms3d'].offsetLeft) === 9 && hash['csstransforms3d'].offsetHeight === 3; /*>>csstransforms3d*/
361
+ /*>>generatedcontent*/Modernizr['generatedcontent'] = (hash['generatedcontent'] && hash['generatedcontent'].offsetHeight) >= 1; /*>>generatedcontent*/
362
+ /*>>fontface*/ Modernizr['fontface'] = /src/i.test(cssText) &&
363
+ cssText.indexOf(rule.split(' ')[0]) === 0; /*>>fontface*/
364
+ }, len, tests);
365
+
366
+ })([
367
+ // Pass in styles to be injected into document
368
+ /*>>fontface*/ '@font-face {font-family:"font";src:url("https://")}' /*>>fontface*/
369
+
370
+ /*>>touch*/ ,['@media (',prefixes.join('touch-enabled),('),mod,')',
371
+ '{#touch{top:9px;position:absolute}}'].join('') /*>>touch*/
372
+
373
+ /*>>csstransforms3d*/ ,['@media (',prefixes.join('transform-3d),('),mod,')',
374
+ '{#csstransforms3d{left:9px;position:absolute;height:3px;}}'].join('')/*>>csstransforms3d*/
375
+
376
+ /*>>generatedcontent*/,['#generatedcontent:after{content:"',smile,'";visibility:hidden}'].join('') /*>>generatedcontent*/
377
+ ],
378
+ [
379
+ /*>>fontface*/ 'fontface' /*>>fontface*/
380
+ /*>>touch*/ ,'touch' /*>>touch*/
381
+ /*>>csstransforms3d*/ ,'csstransforms3d' /*>>csstransforms3d*/
382
+ /*>>generatedcontent*/,'generatedcontent' /*>>generatedcontent*/
383
+
384
+ ]);/*>>testBundle*/
385
+
386
+
387
+ /**
388
+ * Tests
389
+ * -----
390
+ */
391
+
392
+ // The *new* flexbox
393
+ // dev.w3.org/csswg/css3-flexbox
394
+
395
+ tests['flexbox'] = function() {
396
+ return testPropsAll('flexOrder');
397
+ };
398
+
399
+ // The *old* flexbox
400
+ // www.w3.org/TR/2009/WD-css3-flexbox-20090723/
401
+
402
+ tests['flexbox-legacy'] = function() {
403
+ return testPropsAll('boxDirection');
404
+ };
405
+
406
+ // On the S60 and BB Storm, getContext exists, but always returns undefined
407
+ // so we actually have to call getContext() to verify
408
+ // github.com/Modernizr/Modernizr/issues/issue/97/
409
+
410
+ tests['canvas'] = function() {
411
+ var elem = document.createElement('canvas');
412
+ return !!(elem.getContext && elem.getContext('2d'));
413
+ };
414
+
415
+ tests['canvastext'] = function() {
416
+ return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
417
+ };
418
+
419
+ // this test initiates a new webgl context.
420
+ // webk.it/70117 is tracking a legit feature detect proposal
421
+
422
+ tests['webgl'] = function() {
423
+ try {
424
+ var canvas = document.createElement('canvas'),
425
+ ret;
426
+ ret = !!(window.WebGLRenderingContext && (canvas.getContext('experimental-webgl') || canvas.getContext('webgl')));
427
+ canvas = undefined;
428
+ } catch (e){
429
+ ret = false;
430
+ }
431
+ return ret;
432
+ };
433
+
434
+ /*
435
+ * The Modernizr.touch test only indicates if the browser supports
436
+ * touch events, which does not necessarily reflect a touchscreen
437
+ * device, as evidenced by tablets running Windows 7 or, alas,
438
+ * the Palm Pre / WebOS (touch) phones.
439
+ *
440
+ * Additionally, Chrome (desktop) used to lie about its support on this,
441
+ * but that has since been rectified: crbug.com/36415
442
+ *
443
+ * We also test for Firefox 4 Multitouch Support.
444
+ *
445
+ * For more info, see: modernizr.github.com/Modernizr/touch.html
446
+ */
447
+
448
+ tests['touch'] = function() {
449
+ return Modernizr['touch'];
450
+ };
451
+
452
+ /**
453
+ * geolocation tests for the new Geolocation API specification.
454
+ * This test is a standards compliant-only test; for more complete
455
+ * testing, including a Google Gears fallback, please see:
456
+ * code.google.com/p/geo-location-javascript/
457
+ * or view a fallback solution using google's geo API:
458
+ * gist.github.com/366184
459
+ */
460
+ tests['geolocation'] = function() {
461
+ return !!navigator.geolocation;
462
+ };
463
+
464
+ // Per 1.6:
465
+ // This used to be Modernizr.crosswindowmessaging but the longer
466
+ // name has been deprecated in favor of a shorter and property-matching one.
467
+ // The old API is still available in 1.6, but as of 2.0 will throw a warning,
468
+ // and in the first release thereafter disappear entirely.
469
+ tests['postmessage'] = function() {
470
+ return !!window.postMessage;
471
+ };
472
+
473
+
474
+ // Chrome incognito mode used to throw an exception when using openDatabase
475
+ // It doesn't anymore.
476
+ tests['websqldatabase'] = function() {
477
+ return !!window.openDatabase;
478
+ };
479
+
480
+ // Vendors had inconsistent prefixing with the experimental Indexed DB:
481
+ // - Webkit's implementation is accessible through webkitIndexedDB
482
+ // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
483
+ // For speed, we don't test the legacy (and beta-only) indexedDB
484
+ tests['indexedDB'] = function() {
485
+ return !!testPropsAll("indexedDB",window);
486
+ };
487
+
488
+ // documentMode logic from YUI to filter out IE8 Compat Mode
489
+ // which false positives.
490
+ tests['hashchange'] = function() {
491
+ return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
492
+ };
493
+
494
+ // Per 1.6:
495
+ // This used to be Modernizr.historymanagement but the longer
496
+ // name has been deprecated in favor of a shorter and property-matching one.
497
+ // The old API is still available in 1.6, but as of 2.0 will throw a warning,
498
+ // and in the first release thereafter disappear entirely.
499
+ tests['history'] = function() {
500
+ return !!(window.history && history.pushState);
501
+ };
502
+
503
+ tests['draganddrop'] = function() {
504
+ var div = document.createElement('div');
505
+ return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);
506
+ };
507
+
508
+ // FIXME: Once FF10 is sunsetted, we can drop prefixed MozWebSocket
509
+ // bugzil.la/695635
510
+ tests['websockets'] = function() {
511
+ for ( var i = -1, len = cssomPrefixes.length; ++i < len; ){
512
+ if ( window[cssomPrefixes[i] + 'WebSocket'] ){
513
+ return true;
514
+ }
515
+ }
516
+ return 'WebSocket' in window;
517
+ };
518
+
519
+
520
+ // css-tricks.com/rgba-browser-support/
521
+ tests['rgba'] = function() {
522
+ // Set an rgba() color and check the returned value
523
+
524
+ setCss('background-color:rgba(150,255,150,.5)');
525
+
526
+ return contains(mStyle.backgroundColor, 'rgba');
527
+ };
528
+
529
+ tests['hsla'] = function() {
530
+ // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
531
+ // except IE9 who retains it as hsla
532
+
533
+ setCss('background-color:hsla(120,40%,100%,.5)');
534
+
535
+ return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
536
+ };
537
+
538
+ tests['multiplebgs'] = function() {
539
+ // Setting multiple images AND a color on the background shorthand property
540
+ // and then querying the style.background property value for the number of
541
+ // occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
542
+
543
+ setCss('background:url(https://),url(https://),red url(https://)');
544
+
545
+ // If the UA supports multiple backgrounds, there should be three occurrences
546
+ // of the string "url(" in the return value for elemStyle.background
547
+
548
+ return /(url\s*\(.*?){3}/.test(mStyle.background);
549
+ };
550
+
551
+
552
+ // In testing support for a given CSS property, it's legit to test:
553
+ // `elem.style[styleName] !== undefined`
554
+ // If the property is supported it will return an empty string,
555
+ // if unsupported it will return undefined.
556
+
557
+ // We'll take advantage of this quick test and skip setting a style
558
+ // on our modernizr element, but instead just testing undefined vs
559
+ // empty string.
560
+
561
+
562
+ tests['backgroundsize'] = function() {
563
+ return testPropsAll('backgroundSize');
564
+ };
565
+
566
+ tests['borderimage'] = function() {
567
+ return testPropsAll('borderImage');
568
+ };
569
+
570
+
571
+ // Super comprehensive table about all the unique implementations of
572
+ // border-radius: muddledramblings.com/table-of-css3-border-radius-compliance
573
+
574
+ tests['borderradius'] = function() {
575
+ return testPropsAll('borderRadius');
576
+ };
577
+
578
+ // WebOS unfortunately false positives on this test.
579
+ tests['boxshadow'] = function() {
580
+ return testPropsAll('boxShadow');
581
+ };
582
+
583
+ // FF3.0 will false positive on this test
584
+ tests['textshadow'] = function() {
585
+ return document.createElement('div').style.textShadow === '';
586
+ };
587
+
588
+
589
+ tests['opacity'] = function() {
590
+ // Browsers that actually have CSS Opacity implemented have done so
591
+ // according to spec, which means their return values are within the
592
+ // range of [0.0,1.0] - including the leading zero.
593
+
594
+ setCssAll('opacity:.55');
595
+
596
+ // The non-literal . in this regex is intentional:
597
+ // German Chrome returns this value as 0,55
598
+ // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
599
+ return /^0.55$/.test(mStyle.opacity);
600
+ };
601
+
602
+
603
+ // Note, Android < 4 will pass this test, but can only animate
604
+ // a single property at a time
605
+ // daneden.me/2011/12/putting-up-with-androids-bullshit/
606
+ tests['cssanimations'] = function() {
607
+ return testPropsAll('animationName');
608
+ };
609
+
610
+
611
+ tests['csscolumns'] = function() {
612
+ return testPropsAll('columnCount');
613
+ };
614
+
615
+
616
+ tests['cssgradients'] = function() {
617
+ /**
618
+ * For CSS Gradients syntax, please see:
619
+ * webkit.org/blog/175/introducing-css-gradients/
620
+ * developer.mozilla.org/en/CSS/-moz-linear-gradient
621
+ * developer.mozilla.org/en/CSS/-moz-radial-gradient
622
+ * dev.w3.org/csswg/css3-images/#gradients-
623
+ */
624
+
625
+ var str1 = 'background-image:',
626
+ str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
627
+ str3 = 'linear-gradient(left top,#9f9, white);';
628
+
629
+ setCss(
630
+ // legacy webkit syntax (FIXME: remove when syntax not in use anymore)
631
+ (str1 + '-webkit- '.split(' ').join(str2 + str1)
632
+ // standard syntax // trailing 'background-image:'
633
+ + prefixes.join(str3 + str1)).slice(0, -str1.length)
634
+ );
635
+
636
+ return contains(mStyle.backgroundImage, 'gradient');
637
+ };
638
+
639
+
640
+ tests['cssreflections'] = function() {
641
+ return testPropsAll('boxReflect');
642
+ };
643
+
644
+
645
+ tests['csstransforms'] = function() {
646
+ return !!testPropsAll('transform');
647
+ };
648
+
649
+
650
+ tests['csstransforms3d'] = function() {
651
+
652
+ var ret = !!testPropsAll('perspective');
653
+
654
+ // Webkit's 3D transforms are passed off to the browser's own graphics renderer.
655
+ // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
656
+ // some conditions. As a result, Webkit typically recognizes the syntax but
657
+ // will sometimes throw a false positive, thus we must do a more thorough check:
658
+ if ( ret && 'webkitPerspective' in docElement.style ) {
659
+
660
+ // Webkit allows this media query to succeed only if the feature is enabled.
661
+ // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }`
662
+ ret = Modernizr['csstransforms3d'];
663
+ }
664
+ return ret;
665
+ };
666
+
667
+
668
+ tests['csstransitions'] = function() {
669
+ return testPropsAll('transition');
670
+ };
671
+
672
+
673
+ /*>>fontface*/
674
+ // @font-face detection routine by Diego Perini
675
+ // javascript.nwbox.com/CSSSupport/
676
+
677
+ // false positives in WebOS: github.com/Modernizr/Modernizr/issues/342
678
+ tests['fontface'] = function() {
679
+ return Modernizr['fontface'];
680
+ };
681
+ /*>>fontface*/
682
+
683
+ // CSS generated content detection
684
+ tests['generatedcontent'] = function() {
685
+ return Modernizr['generatedcontent'];
686
+ };
687
+
688
+
689
+
690
+ // These tests evaluate support of the video/audio elements, as well as
691
+ // testing what types of content they support.
692
+ //
693
+ // We're using the Boolean constructor here, so that we can extend the value
694
+ // e.g. Modernizr.video // true
695
+ // Modernizr.video.ogg // 'probably'
696
+ //
697
+ // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
698
+ // thx to NielsLeenheer and zcorpan
699
+
700
+ // Note: in some older browsers, "no" was a return value instead of empty string.
701
+ // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
702
+ // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
703
+
704
+ tests['video'] = function() {
705
+ var elem = document.createElement('video'),
706
+ bool = false;
707
+
708
+ // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
709
+ try {
710
+ if ( bool = !!elem.canPlayType ) {
711
+ bool = new Boolean(bool);
712
+ bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
713
+
714
+ bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
715
+
716
+ bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
717
+ }
718
+
719
+ } catch(e) { }
720
+
721
+ return bool;
722
+ };
723
+
724
+ tests['audio'] = function() {
725
+ var elem = document.createElement('audio'),
726
+ bool = false;
727
+
728
+ try {
729
+ if ( bool = !!elem.canPlayType ) {
730
+ bool = new Boolean(bool);
731
+ bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
732
+ bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
733
+
734
+ // Mimetypes accepted:
735
+ // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
736
+ // bit.ly/iphoneoscodecs
737
+ bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
738
+ bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
739
+ elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
740
+ }
741
+ } catch(e) { }
742
+
743
+ return bool;
744
+ };
745
+
746
+
747
+ // In FF4, if disabled, window.localStorage should === null.
748
+
749
+ // Normally, we could not test that directly and need to do a
750
+ // `('localStorage' in window) && ` test first because otherwise Firefox will
751
+ // throw bugzil.la/365772 if cookies are disabled
752
+
753
+ // Also in iOS5 Private Browsing mode, attepting to use localStorage.setItem
754
+ // will throw the exception:
755
+ // QUOTA_EXCEEDED_ERRROR DOM Exception 22.
756
+ // Peculiarly, getItem and removeItem calls do not throw.
757
+
758
+ // Because we are forced to try/catch this, we'll go aggressive.
759
+
760
+ // Just FWIW: IE8 Compat mode supports these features completely:
761
+ // www.quirksmode.org/dom/html5.html
762
+ // But IE8 doesn't support either with local files
763
+
764
+ tests['localstorage'] = function() {
765
+ try {
766
+ localStorage.setItem(mod, mod);
767
+ localStorage.removeItem(mod);
768
+ return true;
769
+ } catch(e) {
770
+ return false;
771
+ }
772
+ };
773
+
774
+ tests['sessionstorage'] = function() {
775
+ try {
776
+ sessionStorage.setItem(mod, mod);
777
+ sessionStorage.removeItem(mod);
778
+ return true;
779
+ } catch(e) {
780
+ return false;
781
+ }
782
+ };
783
+
784
+
785
+ tests['webworkers'] = function() {
786
+ return !!window.Worker;
787
+ };
788
+
789
+
790
+ tests['applicationcache'] = function() {
791
+ return !!window.applicationCache;
792
+ };
793
+
794
+
795
+ // Thanks to Erik Dahlstrom
796
+ tests['svg'] = function() {
797
+ return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
798
+ };
799
+
800
+ // specifically for SVG inline in HTML, not within XHTML
801
+ // test page: paulirish.com/demo/inline-svg
802
+ tests['inlinesvg'] = function() {
803
+ var div = document.createElement('div');
804
+ div.innerHTML = '<svg/>';
805
+ return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
806
+ };
807
+
808
+ // SVG SMIL animation
809
+ tests['smil'] = function() {
810
+ return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
811
+ };
812
+
813
+ // This test is only for clip paths in SVG proper, not clip paths on HTML content
814
+ // demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg
815
+
816
+ // However read the comments to dig into applying SVG clippaths to HTML content here:
817
+ // github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491
818
+ tests['svgclippaths'] = function() {
819
+ return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
820
+ };
821
+
822
+ // input features and input types go directly onto the ret object, bypassing the tests loop.
823
+ // Hold this guy to execute in a moment.
824
+ function webforms() {
825
+ // Run through HTML5's new input attributes to see if the UA understands any.
826
+ // We're using f which is the <input> element created early on
827
+ // Mike Taylr has created a comprehensive resource for testing these attributes
828
+ // when applied to all input types:
829
+ // miketaylr.com/code/input-type-attr.html
830
+ // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
831
+
832
+ // Only input placeholder is tested while textarea's placeholder is not.
833
+ // Currently Safari 4 and Opera 11 have support only for the input placeholder
834
+ // Both tests are available in feature-detects/forms-placeholder.js
835
+ Modernizr['input'] = (function( props ) {
836
+ for ( var i = 0, len = props.length; i < len; i++ ) {
837
+ attrs[ props[i] ] = !!(props[i] in inputElem);
838
+ }
839
+ if (attrs.list){
840
+ // safari false positive's on datalist: webk.it/74252
841
+ // see also github.com/Modernizr/Modernizr/issues/146
842
+ attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement);
843
+ }
844
+ return attrs;
845
+ })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
846
+
847
+ // Run through HTML5's new input types to see if the UA understands any.
848
+ // This is put behind the tests runloop because it doesn't return a
849
+ // true/false like all the other tests; instead, it returns an object
850
+ // containing each input type with its corresponding true/false value
851
+
852
+ // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
853
+ Modernizr['inputtypes'] = (function(props) {
854
+
855
+ for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
856
+
857
+ inputElem.setAttribute('type', inputElemType = props[i]);
858
+ bool = inputElem.type !== 'text';
859
+
860
+ // We first check to see if the type we give it sticks..
861
+ // If the type does, we feed it a textual value, which shouldn't be valid.
862
+ // If the value doesn't stick, we know there's input sanitization which infers a custom UI
863
+ if ( bool ) {
864
+
865
+ inputElem.value = smile;
866
+ inputElem.style.cssText = 'position:absolute;visibility:hidden;';
867
+
868
+ if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
869
+
870
+ docElement.appendChild(inputElem);
871
+ defaultView = document.defaultView;
872
+
873
+ // Safari 2-4 allows the smiley as a value, despite making a slider
874
+ bool = defaultView.getComputedStyle &&
875
+ defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
876
+ // Mobile android web browser has false positive, so must
877
+ // check the height to see if the widget is actually there.
878
+ (inputElem.offsetHeight !== 0);
879
+
880
+ docElement.removeChild(inputElem);
881
+
882
+ } else if ( /^(search|tel)$/.test(inputElemType) ){
883
+ // Spec doesnt define any special parsing or detectable UI
884
+ // behaviors so we pass these through as true
885
+
886
+ // Interestingly, opera fails the earlier test, so it doesn't
887
+ // even make it here.
888
+
889
+ } else if ( /^(url|email)$/.test(inputElemType) ) {
890
+ // Real url and email support comes with prebaked validation.
891
+ bool = inputElem.checkValidity && inputElem.checkValidity() === false;
892
+
893
+ } else if ( /^color$/.test(inputElemType) ) {
894
+ // chuck into DOM and force reflow for Opera bug in 11.00
895
+ // github.com/Modernizr/Modernizr/issues#issue/159
896
+ docElement.appendChild(inputElem);
897
+ docElement.offsetWidth;
898
+ bool = inputElem.value != smile;
899
+ docElement.removeChild(inputElem);
900
+
901
+ } else {
902
+ // If the upgraded input compontent rejects the :) text, we got a winner
903
+ bool = inputElem.value != smile;
904
+ }
905
+ }
906
+
907
+ inputs[ props[i] ] = !!bool;
908
+ }
909
+ return inputs;
910
+ })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
911
+ }
912
+
913
+
914
+ // End of test definitions
915
+ // -----------------------
916
+
917
+
918
+
919
+ // Run through all tests and detect their support in the current UA.
920
+ // todo: hypothetically we could be doing an array of tests and use a basic loop here.
921
+ for ( var feature in tests ) {
922
+ if ( hasOwnProperty(tests, feature) ) {
923
+ // run the test, throw the return value into the Modernizr,
924
+ // then based on that boolean, define an appropriate className
925
+ // and push it into an array of classes we'll join later.
926
+ featureName = feature.toLowerCase();
927
+ Modernizr[featureName] = tests[feature]();
928
+
929
+ classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
930
+ }
931
+ }
932
+
933
+ // input tests need to run.
934
+ Modernizr.input || webforms();
935
+
936
+
937
+ /**
938
+ * addTest allows the user to define their own feature tests
939
+ * the result will be added onto the Modernizr object,
940
+ * as well as an appropriate className set on the html element
941
+ *
942
+ * @param feature - String naming the feature
943
+ * @param test - Function returning true if feature is supported, false if not
944
+ */
945
+ Modernizr.addTest = function ( feature, test ) {
946
+ if ( typeof feature == 'object' ) {
947
+ for ( var key in feature ) {
948
+ if ( hasOwnProperty( feature, key ) ) {
949
+ Modernizr.addTest( key, feature[ key ] );
950
+ }
951
+ }
952
+ } else {
953
+
954
+ feature = feature.toLowerCase();
955
+
956
+ if ( Modernizr[feature] !== undefined ) {
957
+ // we're going to quit if you're trying to overwrite an existing test
958
+ // if we were to allow it, we'd do this:
959
+ // var re = new RegExp("\\b(no-)?" + feature + "\\b");
960
+ // docElement.className = docElement.className.replace( re, '' );
961
+ // but, no rly, stuff 'em.
962
+ return Modernizr;
963
+ }
964
+
965
+ test = typeof test == 'function' ? test() : test;
966
+
967
+ docElement.className += ' ' + (test ? '' : 'no-') + feature;
968
+ Modernizr[feature] = test;
969
+
970
+ }
971
+
972
+ return Modernizr; // allow chaining.
973
+ };
974
+
975
+
976
+ // Reset modElem.cssText to nothing to reduce memory footprint.
977
+ setCss('');
978
+ modElem = inputElem = null;
979
+
980
+ //>>BEGIN IEPP
981
+ // Enable HTML 5 elements for styling in IE & add HTML5 css
982
+
983
+ /*! HTML5 Shiv v3.2 | @jon_neal @afarkas @rem | MIT/GPL2 Licensed */
984
+ (function (win, doc) {
985
+ // feature detection: whether the browser supports default html5 styles
986
+ var supportsHtml5Styles = (function(a, docEl, compStyle) {
987
+ var fake, supported, root = doc.body || (fake = docEl.insertBefore(doc.createElement('body'), docEl.firstChild));
988
+
989
+ root.insertBefore(a, root.firstChild);
990
+
991
+ a.hidden = true;
992
+
993
+ supported = (compStyle ? compStyle(a, null) : a.currentStyle).display === 'none';
994
+
995
+ root.removeChild(a);
996
+
997
+ fake && docEl.removeChild(fake);
998
+
999
+ return supported;
1000
+ })(doc.createElement('a'), doc.documentElement, win.getComputedStyle);
1001
+
1002
+ // feature detection: whether the browser supports unknown elements
1003
+ var supportsUnknownElements = (function (a) {
1004
+ a.innerHTML = '<x-element></x-element>';
1005
+
1006
+ return a.childNodes.length === 1;
1007
+ })(doc.createElement('a'));
1008
+
1009
+ var call = Date.call;
1010
+
1011
+ var defaultHtml5Elements = 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video';
1012
+
1013
+ var html5 = win.html5 || {};
1014
+
1015
+ // html5 global so that more elements can be shived and also so that existing shiving can be detected on iframes
1016
+ // more elements can be added and shived: html5.elements.push('element-name'); html5.shivDocument(document);
1017
+ // defaults can be changed before the script is included: html5 = { shivMethods: false, shivCSS: false, elements: 'foo bar' };
1018
+ html5 = {
1019
+ // a list of html5 elements
1020
+ 'elements': (typeof html5.elements === 'object') ? html5.elements : (html5.elements || defaultHtml5Elements).split(' '),
1021
+ 'shivCSS': !(html5.shivCSS === false),
1022
+ 'shivMethods': !(html5.shivMethods === false),
1023
+ 'shivDocument': function (scopeDocument) {
1024
+ if (!supportsUnknownElements && !scopeDocument.documentShived) {
1025
+ var documentCreateElement = scopeDocument.createElement, documentCreateDocumentFragment = scopeDocument.createDocumentFragment;
1026
+
1027
+ // shiv the document
1028
+ for (var i = 0, elements = html5.elements, l = elements.length; i < l; ++i) {
1029
+ call.call(documentCreateElement, scopeDocument, elements[i]);
1030
+ }
1031
+
1032
+ // shiv the document create element method
1033
+ scopeDocument.createElement = function (nodeName) {
1034
+ var element = call.call(documentCreateElement, scopeDocument, nodeName);
1035
+
1036
+ // shiv only supported elements (supporting children, not namespaced)
1037
+ if (html5.shivMethods && element.canHaveChildren && !(element.xmlns || element.tagUrn)) {
1038
+ html5.shivDocument(element.document);
1039
+ }
1040
+
1041
+ return element;
1042
+ };
1043
+
1044
+ // shiv the document create document fragment method
1045
+ scopeDocument.createDocumentFragment = function () {
1046
+ var frag = call.call(documentCreateDocumentFragment, scopeDocument);
1047
+
1048
+ return (html5.shivMethods) ? html5.shivDocument(frag) : frag;
1049
+ };
1050
+ }
1051
+
1052
+ // set the document head variable
1053
+ var documentHead = scopeDocument.getElementsByTagName('head')[0];
1054
+
1055
+ // shiv the default html5 styles
1056
+ if (html5.shivCSS && !supportsHtml5Styles && documentHead) {
1057
+ var p = scopeDocument.createElement('p');
1058
+
1059
+ p.innerHTML = 'x<style>' +
1060
+ 'article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}' + // Corrects block display not defined in IE6/7/8/9
1061
+ 'audio{display:none}' + // Corrects audio display not defined in IE6/7/8/9
1062
+ 'canvas,video{display:inline-block;*display:inline;*zoom:1}' + // Corrects canvas and video display not defined in IE6/7/8/9
1063
+ '[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}' + // Corrects 'hidden' attribute and audio[controls] display not present in IE7/8/9
1064
+ 'mark{background:#FF0;color:#000}' + // Addresses styling not present in IE6/7/8/9
1065
+ '</style>';
1066
+
1067
+ documentHead.insertBefore(p.lastChild, documentHead.firstChild);
1068
+ }
1069
+
1070
+ // set the document as shivved
1071
+ scopeDocument.documentShived = true;
1072
+
1073
+ // return the document
1074
+ return scopeDocument;
1075
+ }
1076
+ };
1077
+
1078
+ // expose shiv type
1079
+ html5.type = 'default';
1080
+
1081
+ // expose html5
1082
+ win.html5 = html5;
1083
+
1084
+ // shiv the document
1085
+ html5.shivDocument(doc);
1086
+ })(this, document);
1087
+
1088
+ //>>END IEPP
1089
+
1090
+ // Assign private properties to the return object with prefix
1091
+ Modernizr._version = version;
1092
+
1093
+ // expose these for the plugin API. Look in the source for how to join() them against your input
1094
+ Modernizr._prefixes = prefixes;
1095
+ Modernizr._domPrefixes = domPrefixes;
1096
+ Modernizr._cssomPrefixes = cssomPrefixes;
1097
+
1098
+ // Modernizr.mq tests a given media query, live against the current state of the window
1099
+ // A few important notes:
1100
+ // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
1101
+ // * A max-width or orientation query will be evaluated against the current state, which may change later.
1102
+ // * You must specify values. Eg. If you are testing support for the min-width media query use:
1103
+ // Modernizr.mq('(min-width:0)')
1104
+ // usage:
1105
+ // Modernizr.mq('only screen and (max-width:768)')
1106
+ Modernizr.mq = testMediaQuery;
1107
+
1108
+ // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
1109
+ // Modernizr.hasEvent('gesturestart', elem)
1110
+ Modernizr.hasEvent = isEventSupported;
1111
+
1112
+ // Modernizr.testProp() investigates whether a given style property is recognized
1113
+ // Note that the property names must be provided in the camelCase variant.
1114
+ // Modernizr.testProp('pointerEvents')
1115
+ Modernizr.testProp = function(prop){
1116
+ return testProps([prop]);
1117
+ };
1118
+
1119
+ // Modernizr.testAllProps() investigates whether a given style property,
1120
+ // or any of its vendor-prefixed variants, is recognized
1121
+ // Note that the property names must be provided in the camelCase variant.
1122
+ // Modernizr.testAllProps('boxSizing')
1123
+ Modernizr.testAllProps = testPropsAll;
1124
+
1125
+
1126
+
1127
+ // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
1128
+ // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
1129
+ Modernizr.testStyles = injectElementWithStyles;
1130
+
1131
+
1132
+ // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
1133
+ // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
1134
+
1135
+ // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
1136
+ // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
1137
+ //
1138
+ // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
1139
+
1140
+ // If you're trying to ascertain which transition end event to bind to, you might do something like...
1141
+ //
1142
+ // var transEndEventNames = {
1143
+ // 'WebkitTransition' : 'webkitTransitionEnd',
1144
+ // 'MozTransition' : 'transitionend',
1145
+ // 'OTransition' : 'oTransitionEnd',
1146
+ // 'msTransition' : 'MsTransitionEnd',
1147
+ // 'transition' : 'transitionend'
1148
+ // },
1149
+ // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
1150
+
1151
+ Modernizr.prefixed = function(prop, obj, elem){
1152
+ if(!obj) {
1153
+ return testPropsAll(prop, 'pfx');
1154
+ } else {
1155
+ // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
1156
+ return testPropsAll(prop, obj, elem);
1157
+ }
1158
+ };
1159
+
1160
+
1161
+
1162
+ // Remove "no-js" class from <html> element, if it exists:
1163
+ docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') +
1164
+
1165
+ // Add the new classes to the <html> element.
1166
+ (enableClasses ? ' js ' + classes.join(' ') : '');
1167
+
1168
+ return Modernizr;
1169
+
1170
+ })(this, this.document);
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: da-suspenders
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 1
10
- version: 1.2.1
9
+ - 2
10
+ version: 1.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - thoughtbot
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-02-03 00:00:00 Z
19
+ date: 2012-02-07 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rails