da-suspenders 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
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