1/*! Picturefill - v2.1.0-beta - 2014-06-06 2 * http://scottjehl.github.io/picturefill 3 * Copyright (c) 2014 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT */ 4/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ 5 6window.matchMedia || (window.matchMedia = function() { 7 "use strict"; 8 9 // For browsers that support matchMedium api such as IE 9 and webkit 10 var styleMedia = (window.styleMedia || window.media); 11 12 // For those that don't support matchMedium 13 if (!styleMedia) { 14 var style = document.createElement('style'), 15 script = document.getElementsByTagName('script')[0], 16 info = null; 17 18 style.type = 'text/css'; 19 style.id = 'matchmediajs-test'; 20 21 script.parentNode.insertBefore(style, script); 22 23 // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers 24 info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; 25 26 styleMedia = { 27 matchMedium: function(media) { 28 var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; 29 30 // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers 31 if (style.styleSheet) { 32 style.styleSheet.cssText = text; 33 } else { 34 style.textContent = text; 35 } 36 37 // Test if media query is true or false 38 return info.width === '1px'; 39 } 40 }; 41 } 42 43 return function(media) { 44 return { 45 matches: styleMedia.matchMedium(media || 'all'), 46 media: media || 'all' 47 }; 48 }; 49}()); 50/*! Picturefill - Responsive Images that work today. 51 * Author: Scott Jehl, Filament Group, 2012 ( new proposal implemented by Shawn Jansepar ) 52 * License: MIT/GPLv2 53 * Spec: http://picture.responsiveimages.org/ 54 */ 55(function( w, doc ) { 56 // Enable strict mode 57 "use strict"; 58 59 // If picture is supported, well, that's awesome. Let's get outta here... 60 if ( w.HTMLPictureElement ) { 61 return; 62 } 63 64 // HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround) 65 doc.createElement( "picture" ); 66 67 // local object for method references and testing exposure 68 var pf = {}; 69 70 // namespace 71 pf.ns = "picturefill"; 72 73 // srcset support test 74 pf.srcsetSupported = new w.Image().srcset !== undefined; 75 76 // just a string trim workaround 77 pf.trim = function( str ) { 78 return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" ); 79 }; 80 81 // just a string endsWith workaround 82 pf.endsWith = function( str, suffix ) { 83 return str.endsWith ? str.endsWith( suffix ) : str.indexOf( suffix, str.length - suffix.length ) !== -1; 84 }; 85 86 /** 87 * Shortcut method for matchMedia ( for easy overriding in tests ) 88 */ 89 pf.matchesMedia = function( media ) { 90 return w.matchMedia && w.matchMedia( media ).matches; 91 }; 92 93 /** 94 * Shortcut method for `devicePixelRatio` ( for easy overriding in tests ) 95 */ 96 pf.getDpr = function() { 97 return ( w.devicePixelRatio || 1 ); 98 }; 99 100 /** 101 * Get width in css pixel value from a "length" value 102 * http://dev.w3.org/csswg/css-values-3/#length-value 103 */ 104 pf.getWidthFromLength = function( length ) { 105 // If no length was specified, or it is 0, default to `100vw` (per the spec). 106 length = length && parseFloat( length ) > 0 ? length : "100vw"; 107 108 /** 109 * If length is specified in `vw` units, use `%` instead since the div weâre measuring 110 * is injected at the top of the document. 111 * 112 * TODO: maybe we should put this behind a feature test for `vw`? 113 */ 114 length = length.replace( "vw", "%" ); 115 116 // Create a cached element for getting length value widths 117 if ( !pf.lengthEl ) { 118 pf.lengthEl = doc.createElement( "div" ); 119 doc.documentElement.insertBefore( pf.lengthEl, doc.documentElement.firstChild ); 120 } 121 122 // Positioning styles help prevent padding/margin/width on `html` from throwing calculations off. 123 pf.lengthEl.style.cssText = "position: absolute; left: 0; width: " + length + ";"; 124 // Using offsetWidth to get width from CSS 125 return pf.lengthEl.offsetWidth; 126 }; 127 128 // container of supported mime types that one might need to qualify before using 129 pf.types = {}; 130 131 // Add support for standard mime types. 132 pf.types["image/jpeg"] = true; 133 pf.types["image/gif"] = true; 134 pf.types["image/png"] = true; 135 136 // test svg support 137 pf.types[ "image/svg+xml" ] = doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1"); 138 139 // test webp support, only when the markup calls for it 140 pf.types[ "image/webp" ] = function() { 141 // based on Modernizr's lossless img-webp test 142 // note: asynchronous 143 var img = new w.Image(), 144 type = "image/webp"; 145 146 img.onerror = function() { 147 pf.types[ type ] = false; 148 picturefill(); 149 }; 150 img.onload = function() { 151 pf.types[ type ] = img.width === 1; 152 picturefill(); 153 }; 154 img.src = "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA="; 155 }; 156 157 /** 158 * Takes a source element and checks if its type attribute is present and if so, supported 159 * Note: for type tests that require a async logic, 160 * you can define them as a function that'll run only if that type needs to be tested. Just make the test function call picturefill again when it is complete. 161 * see the async webp test above for example 162 */
163 pf.verifyTypeSupport = function( source ) { 164 var type = source.getAttribute( "type" ); 165 // if type attribute exists, return test result, otherwise return true 166 if ( type === null || type === "" ) { 167 return true; 168 } else { 169 // if the type test is a function, run it and return "pending" status. The function will rerun picturefill on pending elements once finished. 170 if ( typeof( pf.types[ type ] ) === "function" ) { 171 pf.types[ type ](); 172 return "pending"; 173 } else { 174 return pf.types[ type ]; 175 } 176 } 177 }; 178 179 /** 180 * Parses an individual `size` and returns the length, and optional media query 181 */ 182 pf.parseSize = function( sourceSizeStr ) { 183 var match = /(\([^)]+\))?\s*(.+)/g.exec( sourceSizeStr ); 184 return { 185 media: match && match[1], 186 length: match && match[2] 187 }; 188 }; 189 190 /** 191 * Takes a string of sizes and returns the width in pixels as a number 192 */ 193 pf.findWidthFromSourceSize = function( sourceSizeListStr ) { 194 // Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33% 195 // or (min-width:30em) calc(30% - 15px) 196 var sourceSizeList = pf.trim( sourceSizeListStr ).split( /\s*,\s*/ ), 197 winningLength; 198 199 for ( var i = 0, len = sourceSizeList.length; i < len; i++ ) { 200 // Match <media-condition>? length, ie ( min-width: 50em ) 100% 201 var sourceSize = sourceSizeList[ i ], 202 // Split "( min-width: 50em ) 100%" into separate strings 203 parsedSize = pf.parseSize( sourceSize ), 204 length = parsedSize.length, 205 media = parsedSize.media; 206 207 if ( !length ) { 208 continue; 209 } 210 if ( !media || pf.matchesMedia( media ) ) { 211 // if there is no media query or it matches, choose this as our winning length 212 // and end algorithm 213 winningLength = length; 214 break; 215 } 216 } 217 218 // pass the length to a method that can properly determine length 219 // in pixels based on these formats: http://dev.w3.org/csswg/css-values-3/#length-value 220 return pf.getWidthFromLength( winningLength ); 221 }; 222 223 pf.parseSrcset = function( srcset ) { 224 /** 225 * A lot of this was pulled from Boris Smusâ parser for the now-defunct WHATWG `srcset` 226 * https://github.com/borismus/srcset-polyfill/blob/master/js/srcset-info.js 227 * 228 * 1. Let input (`srcset`) be the value passed to this algorithm. 229 * 2. Let position be a pointer into input, initially pointing at the start of the string. 230 * 3. Let raw candidates be an initially empty ordered list of URLs with associated 231 * unparsed descriptors. The order of entries in the list is the order in which entries 232 * are added to the list. 233 */ 234 var candidates = []; 235 236 while ( srcset !== "" ) { 237 srcset = srcset.replace(/^\s+/g,""); 238 239 // 5. Collect a sequence of characters that are not space characters, and let that be url. 240 var pos = srcset.search(/\s/g), 241 url, descriptor = null; 242 243 if ( pos !== -1 ) { 244 url = srcset.slice( 0, pos ); 245 246 var last = url[ url.length - 1 ]; 247 248 // 6. If url ends with a U+002C COMMA character (,), remove that character from url 249 // and let descriptors be the empty string. Otherwise, follow these substeps 250 // 6.1. If url is empty, then jump to the step labeled descriptor parser. 251 252 if ( last === "," || url === "" ) { 253 url = url.replace(/,+$/, ""); 254 descriptor = ""; 255 } 256 srcset = srcset.slice( pos + 1 ); 257 258 // 6.2. Collect a sequence of characters that are not U+002C COMMA
258characters (,), and 259 // let that be descriptors. 260 if ( descriptor === null ) { 261 var descpos = srcset.indexOf(","); 262 if ( descpos !== -1 ) { 263 descriptor = srcset.slice( 0, descpos ); 264 srcset = srcset.slice( descpos + 1 ); 265 } else { 266 descriptor = srcset; 267 srcset = ""; 268 } 269 } 270 } else { 271 url = srcset; 272 srcset = ""; 273 } 274 275 // 7. Add url to raw candidates, associated with descriptors. 276 if ( url || descriptor ) { 277 candidates.push({ 278 url: url, 279 descriptor: descriptor 280 }); 281 } 282 } 283 return candidates; 284 }; 285 286 pf.parseDescriptor = function( descriptor, sizes ) { 287 // 11. Descriptor parser: Let candidates be an initially empty source set. The order of entries in the list 288 // is the order in which entries are added to the list. 289 var sizeDescriptor = descriptor && descriptor.replace(/(^\s+|\s+$)/g, ""), 290 widthInCssPixels = sizes ? pf.findWidthFromSourceSize( sizes ) : "100%", 291 resCandidate; 292 293 if ( sizeDescriptor ) { 294 var splitDescriptor = sizeDescriptor.split(" "); 295 296 for (var i = splitDescriptor.length + 1; i >= 0; i--) { 297 298 var curr = splitDescriptor[ i ], 299 lastchar = curr && curr.slice( curr.length - 1 ); 300 301 if ( lastchar === "w" || lastchar === "x" ) { 302 resCandidate = curr; 303 } 304 if ( sizes && resCandidate ) { 305 // get the dpr by taking the length / width in css pixels 306 resCandidate = parseFloat( ( parseInt( curr, 10 ) / widthInCssPixels ) ); 307 } else { 308 // get the dpr by grabbing the value of Nx 309 var res = curr && parseFloat( curr, 10 ); 310 311 resCandidate = res && !isNaN( res ) && lastchar === "x" || lastchar === "w" ? res : 1; 312 } 313 } 314 } else { 315 resCandidate = 1; 316 } 317 return resCandidate; 318 }; 319 320 /** 321 * Takes a srcset in the form of url/ 322 * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or 323 * "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or 324 * "images/pic-small.png" 325 * Get an array of image candidates in the form of 326 * {url: "/foo/bar.png", resolution: 1} 327 * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value 328 * If sizes is specified, resolution is calculated 329 */ 330 pf.getCandidatesFromSourceSet = function( srcset, sizes ) { 331 var candidates = pf.parseSrcset( srcset ), 332 formattedCandidates = []; 333 334 for ( var i = 0, len = candidates.length; i < len; i++ ) { 335 var candidate = candidates[ i ]; 336 337 formattedCandidates.push({ 338 url: candidate.url, 339 resolution: pf.parseDescriptor( candidate.descriptor, sizes ) 340 }); 341 } 342 return formattedCandidates; 343 }; 344 345 /* 346 * if it's an img element and it has a srcset property, 347 * we need to remove the attribute so we can manipulate src 348 * (the property's existence infers native srcset support, and a srcset-supporting browser will prioritize srcset's value over our winning picture candidate) 349 * this moves srcset's value to memory for later use and removes the attr 350 */ 351 pf.dodgeSrcset = function( img ) { 352 if ( img.srcset ) { 353 img[ pf.ns ].srcset = img.srcset; 354 img.removeAttribute( "srcset" ); 355 } 356 }; 357 358 /* 359 * Accept a source or img element and process its srcset and sizes attrs 360 */ 361 pf.processSourceSet = function( el ) { 362 var srcset = el.getAttribute( "srcset" ), 363 sizes = el.getAttribute( "sizes" ), 364 candidates = []; 365 366 // if it's an img element, use the cached srcset property (defined or not) 367 if ( el.nodeName.toUpperCase() === "IMG" && el[ pf.ns ] && el[ pf.ns ].srcset ) { 368 srcset = el[ pf.ns ].srcset; 369 } 370 371 if ( srcset ) { 372 candidates = pf.getCandidatesFromSourceSet( srcset, sizes ); 373 } 374 return candidates; 375 }; 376 377 pf.applyBestCandidate = function( candidates, picImg ) { 378 var candidate, 379 length, 380 bestCandidate; 381 382 candidates.sort( pf.ascendingSort ); 383 384 length = candidates.length; 385 bestCandidate = candidates[ length - 1 ]; 386 387 for ( var i = 0; i < length; i++ ) { 388 candidate = candidates[ i ]; 389 if ( candidate.resolution >= pf.getDpr() ) { 390 bestCandidate = candidate; 391 break; 392 } 393 } 394 395 if ( !pf.endsWith( picImg.src, bestCandidate.url ) ) { 396 picImg.src = bestCandidate.url; 397 // currentSrc attribute and property to match 398 // http://picture.responsiveimages.org/#the-img-element 399 picImg.currentSrc = picImg.src; 400 } 401 }; 402 403 pf.ascendingSort = function( a, b ) { 404 return a.resolution - b.resolution; 405 }; 406 407 /* 408 * In IE9, <source> elements get removed if they aren't children of 409 * video elements. Thus, we conditionally wrap source elements 410 * using <!--[if IE 9]><video style="display: none;"><![endif]--> 411 * and must account for that here by moving those source elements 412 * back into the picture element. 413 */ 414 pf.removeVideoShim = function( picture ) { 415 var videos = picture.getElementsByTagName( "video" ); 416 if ( videos.length ) { 417 var video = videos[ 0 ], 418 vsources = video.getElementsByTagName( "source" ); 419 while ( vsources.length ) { 420 picture.insertBefore( vsources[ 0 ], video ); 421 } 422 // Remove the video element once we're finished removing its children 423 video.parentNode.removeChild( video ); 424 } 425 }; 426 427 /* 428 * Find all picture elements and, 429 * in browsers that don't natively support srcset, find all img elements 430 * with srcset attrs that don't have picture parents 431 */ 432 pf.getAllElements = function() { 433 var pictures = doc.getElementsByTagName( "picture" ), 434 elems = [], 435 imgs = doc.getElementsByTagName( "img" ); 436 437 for ( var h = 0, len = pictures.length + imgs.length; h < len; h++ ) { 438 if ( h < pictures.length ) { 439 elems[ h ] = pictures[ h ]; 440 } else { 441 var currImg = imgs[ h - pictures.length ]; 442 443 if ( currImg.parentNode.nodeName.toUpperCase() !== "PICTURE" && 444 ( ( pf.srcsetSupported && currImg.getAttribute( "sizes" ) ) || 445 currImg.getAttribute( "srcset" ) !== null ) ) { 446 elems.push( currImg ); 447 } 448 } 449 } 450 return elems; 451 }; 452 453 pf.getMatch = function( picture ) { 454 var sources = picture.childNodes, 455 match; 456 457 // Go through each child, and if they have media queries, evaluate them 458 for ( var j = 0, slen = sources.length; j < slen; j++ ) { 459 var source = sources[ j ]; 460 461 // ignore non-element nodes 462 if ( source.nodeType !== 1 ) { 463 continue; 464 } 465 466 // Hitting an `img` element stops the search for `sources`. 467 // If no previous `source` matches, the `img` itself is evaluated later. 468 if ( source.nodeName.toUpperCase() === "IMG" ) { 469 return match; 470 } 471 472 // ignore non-`source` nodes 473 if ( source.nodeName.toUpperCase() !== "SOURCE" ) { 474 continue; 475 } 476 477 var media = source.getAttribute( "media" ); 478 479 // if source does not have a srcset attribute, skip 480 if ( !source.getAttribute( "srcset" ) ) { 481 continue; 482 } 483 484 // if there's no media specified, OR w.matchMedia is supported 485 if ( ( !media || pf.matchesMedia( media ) ) ) {
486 var typeSupported = pf.verifyTypeSupport( source ); 487 488 if ( typeSupported === true ) { 489 match = source; 490 break; 491 } else if ( typeSupported === "pending" ) { 492 return false; 493 } 494 } 495 } 496 497 return match; 498 }; 499 500 function picturefill( options ) { 501 var elements, 502 element, 503 elemType, 504 firstMatch, 505 candidates, 506 picImg; 507 508 options = options || {}; 509 elements = options.elements || pf.getAllElements(); 510 511 // Loop through all elements 512 for ( var i = 0, plen = elements.length; i < plen; i++ ) { 513 element = elements[ i ]; 514 elemType = element.nodeName.toUpperCase(); 515 firstMatch = undefined; 516 candidates = undefined; 517 picImg = undefined; 518 519 // expando for caching data on the img 520 if ( !element[ pf.ns ] ) { 521 element[ pf.ns ] = {}; 522 } 523 524 // if the element has already been evaluated, skip it 525 // unless `options.force` is set to true ( this, for example, 526 // is set to true when running `picturefill` on `resize` ). 527 if ( !options.reevaluate && element[ pf.ns ].evaluated ) { 528 continue; 529 } 530 531 // if element is a picture element 532 if ( elemType === "PICTURE" ) { 533 534 // IE9 video workaround 535 pf.removeVideoShim( element ); 536 537 // return the first match which might undefined 538 // returns false if there is a pending source 539 // TODO the return type here is brutal, cleanup 540 firstMatch = pf.getMatch( element ); 541 542 // if any sources are pending in this picture due to async type test(s) 543 // remove the evaluated attr and skip for now ( the pending test will 544 // rerun picturefill on this element when complete) 545 if ( firstMatch === false ) { 546 continue; 547 } 548 549 // Find any existing img element in the picture element 550 picImg = element.getElementsByTagName( "img" )[ 0 ]; 551 } else { 552 // if it's an img element 553 firstMatch = undefined; 554 picImg = element; 555 } 556 557 if ( picImg ) { 558 559 // expando for caching data on the img 560 if ( !picImg[ pf.ns ] ) { 561 picImg[ pf.ns ] = {}; 562 } 563 564 // Cache and remove `srcset` if present and weâre going to be doing `sizes`/`picture` polyfilling to it. 565 if ( picImg.srcset && ( elemType === "PICTURE" || picImg.getAttribute( "sizes" ) ) ) { 566 pf.dodgeSrcset( picImg ); 567 } 568 569 if ( firstMatch ) { 570 candidates = pf.processSourceSet( firstMatch ); 571 pf.applyBestCandidate( candidates, picImg ); 572 } else { 573 // No sources matched, so weâre down to processing the inner `img` as a source. 574 candidates = pf.processSourceSet( picImg ); 575 576 if ( picImg.srcset === undefined || picImg[ pf.ns ].srcset ) { 577 // Either `srcset` is completely unsupported, or we need to polyfill `sizes` functionality. 578 pf.applyBestCandidate( candidates, picImg ); 579 } // Else, resolution-only `srcset` is supported natively. 580 } 581 582 // set evaluated to true to avoid unnecessary reparsing 583 element[ pf.ns ].evaluated = true; 584 } 585 } 586 } 587 588 /** 589 * Sets up picture polyfill by polling the document and running 590 * the polyfill every 250ms until the document is ready. 591 * Also attaches picturefill on resize 592 */ 593 function runPicturefill() { 594 picturefill(); 595 var intervalId = setInterval( function() { 596 // When the document has finished loading, stop checking for new images 597 // https://github.com/ded/domready/blob/master/ready.js#L15 598 picturefill(); 599 if ( /^loaded|^i|^c/.test( doc.readyState ) ) { 600 clearInterval( intervalId ); 601 return; 602 } 603 }, 250 ); 604 if ( w.addEventListener ) { 605 var resizeThrottle; 606 w.addEventListener( "resize", function() { 607 if (!w._picturefillWorking) { 608 w._picturefillWorking = true; 609 w.clearTimeout( resizeThrottle ); 610 resizeThrottle = w.setTimeout( function() { 611 picturefill({ reevaluate: true });
612 w._picturefillWorking = false; 613 }, 60 ); 614 } 615 }, false ); 616 } 617 } 618 619 runPicturefill(); 620 621 /* expose methods for testing */ 622 picturefill._ = pf; 623 624 /* expose picturefill */ 625 if ( typeof module === "object" && typeof module.exports === "object" ) { 626 // CommonJS, just export 627 module.exports = picturefill; 628 } else if ( typeof define === "function" && define.amd ){ 629 // AMD support 630 define( function() { return picturefill; } ); 631 } else if ( typeof w === "object" ) { 632 // If no AMD and we are in the browser, attach to window 633 w.picturefill = picturefill; 634 } 635 636} )( this, this.document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.