PageSourceSearch

https://scottishmedicines.org.uk/scripts/picturefill.js?cdv=971313061

js scottishmedicines.org.uk collected 2026-10-02 03:44:32 UTC 24,521 bytes, 636 lines download raw bytes

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.