Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

327 linhas
9.3 KiB

  1. /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
  2. /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */
  3. window.matchMedia = window.matchMedia || (function(doc, undefined){
  4. var bool,
  5. docElem = doc.documentElement,
  6. refNode = docElem.firstElementChild || docElem.firstChild,
  7. // fakeBody required for <FF4 when executed in <head>
  8. fakeBody = doc.createElement('body'),
  9. div = doc.createElement('div');
  10. div.id = 'mq-test-1';
  11. div.style.cssText = "position:absolute;top:-100em";
  12. fakeBody.style.background = "none";
  13. fakeBody.appendChild(div);
  14. return function(q){
  15. div.innerHTML = '&shy;<style media="'+q+'"> #mq-test-1 { width: 42px; }</style>';
  16. docElem.insertBefore(fakeBody, refNode);
  17. bool = div.offsetWidth == 42;
  18. docElem.removeChild(fakeBody);
  19. return { matches: bool, media: q };
  20. };
  21. })(document);
  22. /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
  23. (function( win ){
  24. //exposed namespace
  25. win.respond = {};
  26. //define update even in native-mq-supporting browsers, to avoid errors
  27. respond.update = function(){};
  28. //expose media query support flag for external use
  29. respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches;
  30. //if media queries are supported, exit here
  31. if( respond.mediaQueriesSupported ){ return; }
  32. //define vars
  33. var doc = win.document,
  34. docElem = doc.documentElement,
  35. mediastyles = [],
  36. rules = [],
  37. appendedEls = [],
  38. parsedSheets = {},
  39. resizeThrottle = 30,
  40. head = doc.getElementsByTagName( "head" )[0] || docElem,
  41. base = doc.getElementsByTagName( "base" )[0],
  42. links = head.getElementsByTagName( "link" ),
  43. requestQueue = [],
  44. //loop stylesheets, send text content to translate
  45. ripCSS = function(){
  46. var sheets = links,
  47. sl = sheets.length,
  48. i = 0,
  49. //vars for loop:
  50. sheet, href, media, isCSS;
  51. for( ; i < sl; i++ ){
  52. sheet = sheets[ i ],
  53. href = sheet.href,
  54. media = sheet.media,
  55. isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
  56. //only links plz and prevent re-parsing
  57. if( !!href && isCSS && !parsedSheets[ href ] ){
  58. // selectivizr exposes css through the rawCssText expando
  59. if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
  60. translate( sheet.styleSheet.rawCssText, href, media );
  61. parsedSheets[ href ] = true;
  62. } else {
  63. if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base)
  64. || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
  65. requestQueue.push( {
  66. href: href,
  67. media: media
  68. } );
  69. }
  70. }
  71. }
  72. }
  73. makeRequests();
  74. },
  75. //recurse through request queue, get css text
  76. makeRequests = function(){
  77. if( requestQueue.length ){
  78. var thisRequest = requestQueue.shift();
  79. ajax( thisRequest.href, function( styles ){
  80. translate( styles, thisRequest.href, thisRequest.media );
  81. parsedSheets[ thisRequest.href ] = true;
  82. makeRequests();
  83. } );
  84. }
  85. },
  86. //find media blocks in css text, convert to style blocks
  87. translate = function( styles, href, media ){
  88. var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),
  89. ql = qs && qs.length || 0,
  90. //try to get CSS path
  91. href = href.substring( 0, href.lastIndexOf( "/" )),
  92. repUrls = function( css ){
  93. return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
  94. },
  95. useMedia = !ql && media,
  96. //vars used in loop
  97. i = 0,
  98. j, fullq, thisq, eachq, eql;
  99. //if path exists, tack on trailing slash
  100. if( href.length ){ href += "/"; }
  101. //if no internal queries exist, but media attr does, use that
  102. //note: this currently lacks support for situations where a media attr is specified on a link AND
  103. //its associated stylesheet has internal CSS media queries.
  104. //In those cases, the media attribute will currently be ignored.
  105. if( useMedia ){
  106. ql = 1;
  107. }
  108. for( ; i < ql; i++ ){
  109. j = 0;
  110. //media attr
  111. if( useMedia ){
  112. fullq = media;
  113. rules.push( repUrls( styles ) );
  114. }
  115. //parse for styles
  116. else{
  117. fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
  118. rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
  119. }
  120. eachq = fullq.split( "," );
  121. eql = eachq.length;
  122. for( ; j < eql; j++ ){
  123. thisq = eachq[ j ];
  124. mediastyles.push( {
  125. media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",
  126. rules : rules.length - 1,
  127. hasquery: thisq.indexOf("(") > -1,
  128. minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
  129. maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
  130. } );
  131. }
  132. }
  133. applyMedia();
  134. },
  135. lastCall,
  136. resizeDefer,
  137. // returns the value of 1em in pixels
  138. getEmValue = function() {
  139. var ret,
  140. div = doc.createElement('div'),
  141. body = doc.body,
  142. fakeUsed = false;
  143. div.style.cssText = "position:absolute;font-size:1em;width:1em";
  144. if( !body ){
  145. body = fakeUsed = doc.createElement( "body" );
  146. body.style.background = "none";
  147. }
  148. body.appendChild( div );
  149. docElem.insertBefore( body, docElem.firstChild );
  150. ret = div.offsetWidth;
  151. if( fakeUsed ){
  152. docElem.removeChild( body );
  153. }
  154. else {
  155. body.removeChild( div );
  156. }
  157. //also update eminpx before returning
  158. ret = eminpx = parseFloat(ret);
  159. return ret;
  160. },
  161. //cached container for 1em value, populated the first time it's needed
  162. eminpx,
  163. //enable/disable styles
  164. applyMedia = function( fromResize ){
  165. var name = "clientWidth",
  166. docElemProp = docElem[ name ],
  167. currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
  168. styleBlocks = {},
  169. lastLink = links[ links.length-1 ],
  170. now = (new Date()).getTime();
  171. //throttle resize calls
  172. if( fromResize && lastCall && now - lastCall < resizeThrottle ){
  173. clearTimeout( resizeDefer );
  174. resizeDefer = setTimeout( applyMedia, resizeThrottle );
  175. return;
  176. }
  177. else {
  178. lastCall = now;
  179. }
  180. for( var i in mediastyles ){
  181. var thisstyle = mediastyles[ i ],
  182. min = thisstyle.minw,
  183. max = thisstyle.maxw,
  184. minnull = min === null,
  185. maxnull = max === null,
  186. em = "em";
  187. if( !!min ){
  188. min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
  189. }
  190. if( !!max ){
  191. max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
  192. }
  193. // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
  194. if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
  195. if( !styleBlocks[ thisstyle.media ] ){
  196. styleBlocks[ thisstyle.media ] = [];
  197. }
  198. styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
  199. }
  200. }
  201. //remove any existing respond style element(s)
  202. for( var i in appendedEls ){
  203. if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){
  204. head.removeChild( appendedEls[ i ] );
  205. }
  206. }
  207. //inject active styles, grouped by media type
  208. for( var i in styleBlocks ){
  209. var ss = doc.createElement( "style" ),
  210. css = styleBlocks[ i ].join( "\n" );
  211. ss.type = "text/css";
  212. ss.media = i;
  213. //originally, ss was appended to a documentFragment and sheets were appended in bulk.
  214. //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
  215. head.insertBefore( ss, lastLink.nextSibling );
  216. if ( ss.styleSheet ){
  217. ss.styleSheet.cssText = css;
  218. }
  219. else {
  220. ss.appendChild( doc.createTextNode( css ) );
  221. }
  222. //push to appendedEls to track for later removal
  223. appendedEls.push( ss );
  224. }
  225. },
  226. //tweaked Ajax functions from Quirksmode
  227. ajax = function( url, callback ) {
  228. var req = xmlHttp();
  229. if (!req){
  230. return;
  231. }
  232. req.open( "GET", url, true );
  233. req.onreadystatechange = function () {
  234. if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){
  235. return;
  236. }
  237. callback( req.responseText );
  238. }
  239. if ( req.readyState == 4 ){
  240. return;
  241. }
  242. req.send( null );
  243. },
  244. //define ajax obj
  245. xmlHttp = (function() {
  246. var xmlhttpmethod = false;
  247. try {
  248. xmlhttpmethod = new XMLHttpRequest();
  249. }
  250. catch( e ){
  251. xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" );
  252. }
  253. return function(){
  254. return xmlhttpmethod;
  255. };
  256. })();
  257. //translate CSS
  258. ripCSS();
  259. //expose update for re-running respond later on
  260. respond.update = ripCSS;
  261. //adjust on resize
  262. function callMedia(){
  263. applyMedia( true );
  264. }
  265. if( win.addEventListener ){
  266. win.addEventListener( "resize", callMedia, false );
  267. }
  268. else if( win.attachEvent ){
  269. win.attachEvent( "onresize", callMedia );
  270. }
  271. })(this);