PageSourceSearch

https://patelheaters.com/wp-content/themes/miva/assets/js/dense.js?ver=1790321255

js patelheaters.com collected 2026-09-30 20:44:38 UTC 12,958 bytes, 398 lines download raw bytes

1/**
2 * Dense - Device pixel ratio aware images
3 *
4 * @link    http://dense.rah.pw
5 * @license MIT
6 */
7
8/*
9 * Copyright (C) 2013 Jukka Svahn
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29/**
30 * @name jQuery
31 * @class
32 */
33
34/**
35 * @name fn
36 * @class
37 * @memberOf jQuery
38 */
39
40(function (factory)
41{
42    'use strict';
43
44    if (typeof define === 'function' && define.amd)
45    {
46        define(['jquery'], factory);
47    }
48    else
49    {
50        factory(window.jQuery || window.Zepto);
51    }
52}(function ($)
53{
54    'use strict';
55
56    /**
57     * An array of checked image URLs.
58     */
59
60    var pathStack = [],
61
62    /**
63     * Methods.
64     */
65
66    methods = {},
67
68    /**
69     * Regular expression to check whether the URL has a protocol.
70     *
71     * Is used to check whether the image URL is external.
72     */
73
74    regexHasProtocol = /^([a-z]:)?\/\//i,
75
76    /**
77     * Regular expression that split extensions from the file.
78     *
79     * Is used to inject the DPR suffix to the name.
80     */
81
82    regexSuffix = /\.\w+$/,
83
84    /**
85     * Device pixel ratio.
86     */
87
88    devicePixelRatio;
89
90    /**
91     * Init is the default method responsible for rendering 
92     * a pixel-ratio-aware images.
93     *
94     * This method is used to select the images that
95     * should display retina-size images on high pixel ratio
96     * devices. Dense defaults to the init method if no
97     * method is specified.
98     *
99     * When attached to an image, the correct image variation is
100     * selected based on the device's pixel ratio. If the image element
101     * defines <code>data-{ratio}x</code> attributes (e.g. data-1x, data-2x, data-3x),
102     * the most appropriate of those is selected.
103     *
104     * If no data-ratio attributes are defined, the retina image is
105     * constructed from the <code>src</code> attribute.
106     * The searched high pixel ratio images follows
107     * a <code>{imageName}_{ratio}x.{ext}</code> naming convention.
108     * For an image found in /path/to/images/image.jpg, the 2x retina
109     * image would be looked from /path/to/images/image_2x.jpg.
110     *
111     * When image is constructed from the src, the image existance is
112     * verified using HTTP HEAD request, if <code>ping</code> option is
113     * <code>true</code>. The check makes sure no HTTP error code is returned,
114     * and that the received content-type is of an image. Vector image formats,
115     * like svg, are skipped based on the file extension.
116     *
117     * This method can also be used to load image in semi-lazy fashion,
118     * and avoid larger extra HTTP requests due to retina replacements.
119     * The data-1x attribute can be used to supstitute the src, making
120     * sure the browser doesn't try to download the normal image variation
121     * before the JavaScript driven behaviour kicks in.
122     *
123     * Some classes are added to the selected elements while Dense is processing
124     * the document. These classes include <code>dense-image</code>, <code>dense-loading</code>
125     * and <code>dense-ready</code>. These classes can be used to style the images,
126     * or hide them while they are being loaded.
127     *
128     * @param {Object} [options={}] Options
129     * @param {Boolean} [options.ping=null] Check image existence. If the default <code>NULL</code> checks local images, <code>FALSE</code> disables checking and <code>TRUE</code> checks even external images cross-domain
130     * @param {String} [options.dimensions=preserve] What to do with the image's <code>width</code> and <code>height</code> attributes. Either <code>update</code>, <code>remove</code> or <code>preserve</code>
131     * @param {String} [options.glue=_] String that glues the retina "nx" suffix to the image. This option can be used to change the naming convention between the two commonly used practices, <code>[email protected]</code> and <code>image_2x.jpg</code>
132     * @param {Array} [options.skipExtensions=['svg']] Skipped image file extensions. There might be situations where you might want to exclude vector image formats
133     * @return {Object} this
134     * @method init
135     * @memberof jQuery.fn.dense
136     * @fires jQuery.fn.dense#denseRetinaReady.dense
137     * @example
138     * $('img').dense({
139     *  ping: false,
140     *  dimension: 'update'
141     * });
142     */
143
144    methods.init = function (options)
145    {
146        options = $.extend({
147            ping: null,
148            dimensions: 'preserve',
149            glue: '_',
150            skipExtensions: ['svg']
151        }, options);
152
153        this.each(function ()
154        {
155            var $this = $(this);
156
157            if (!$this.is('img') || $this.hasClass('dense-image'))
158            {
159                return;
160            }
161
162            $this.addClass('dense-image dense-loading');
163
164            var image = methods.getImageAttribute.call(this),
165                originalImage = $this.attr('src'),
166                ping = false,
167                updateImage;
168
169            if (!image)
170            {
171                if (!originalImage || devicePixelRatio === 1 || $.inArray(originalImage.split('.').pop().split(/[\?\#]/).shift(), options.skipExtensions) !== -1)
172                {
173                    $this.removeClass('dense-image dense-loading');
174                    return;
175                }
176
177                image = originalImage.replace(regexSuffix, function (extension)
178                {
179                    return options.glue + devicePixelRatio + 'x' + extension;
180                });
181
182                ping = options.ping !== false && $.inArray(image, pathStack) === -1 && (options.ping === true || !regexH
182asProtocol.test(image) || image.indexOf('//'+document.domain) === 0 || image.indexOf(document.location.protocol+'//'+document.domain) === 0);
183            }
184
185            updateImage = function ()
186            {
187                var readyImage = function ()
188                {
189                    $this.removeClass('dense-loading').addClass('dense-ready').trigger('denseRetinaReady.dense');
190                };
191
192                $this.attr('src', image);
193
194                if (options.dimensions === 'update')
195                {
196                    $this.dense('updateDimensions').one('denseDimensionChanged', readyImage);
197                }
198                else
199                {
200                    if (options.dimensions === 'remove')
201                    {
202                        $this.removeAttr('width height');
203                    }
204
205                    readyImage();
206                }
207            };
208
209            if (ping)
210            {
211                $.ajax({
212                    url  : image,
213                    type : 'HEAD'
214                })
215                    .done(function (data, textStatus, jqXHR)
216                    {
217                        var type = jqXHR.getResponseHeader('Content-type');
218
219                        if (!type || type.indexOf('image/') === 0)
220                        {
221                            pathStack.push(image);
222                            updateImage();
223                        }
224                    });
225            }
226            else
227            {
228                updateImage();
229            }
230        });
231
232        return this;
233    };
234
235    /**
236     * Sets an image's width and height attributes to its native values.
237     *
238     * Updates an img element's dimensions to the source image's
239     * real values. This method is asynchronous, so you can not directly
240     * return its values. Instead, use the 'dense-dimensions-updated'
241     * event to detect when the action is done.
242     *
243     * @return {Object} this
244     * @method updateDimensions
245     * @memberof jQuery.fn.dense
246     * @fires jQuery.fn.dense#denseDimensionChanged.dense
247     * @example
248     * var image = $('img').dense('updateDimensions');
249     */
250
251    methods.updateDimensions = function ()
252    {
253        return this.each(function ()
254        {
255            var img, $this = $(this), src = $this.attr('src');
256
257            if (src)
258            {
259                img = new Image();
260                img.src = src;
261
262                $(img).on('load.dense', function ()
263                {
264                    $this.attr({
265                        width: img.width,
266                        height: img.height
267                    }).trigger('denseDimensionChanged.dense');
268                });
269            }
270        });
271    };
272
273    /**
274     * Gets device pixel ratio rounded up to the closest integer.
275     *
276     * @return {Integer} The pixel ratio
277     * @method devicePixelRatio
278     * @memberof jQuery.fn.dense
279     * @example
280     * var ratio = $(window).dense('devicePixelRatio');
281     * alert(ratio);
282     */
283
284    methods.devicePixelRatio = function ()
285    {
286        var pixelRatio = 1;
287
288        if ($.type(window.devicePixelRatio) !== 'undefined')
289        {
290            pixelRatio = window.devicePixelRatio;
291        }
292        else if ($.type(window.matchMedia) !== 'undefined')
293        {
294            $.each([1.3, 2, 3, 4, 5, 6], function (key, ratio)
295            {
296                var mediaQuery = [
297                    '(-webkit-min-device-pixel-ratio: '+ratio+')',
298                    '(min-resolution: '+Math.floor(ratio*96)+'dpi)',
299                    '(min-resolution: '+ratio+'dppx)'
300                ].join(',');
301
302                if (!window.matchMedia(mediaQuery).matches)
303                {
304                    return false;
305                }
306
307                pixelRatio = ratio;
308            });
309        }
310
311        return Math.ceil(pixelRatio);
312    };
313
314    /**
315     * Gets an appropriate URL for the pixel ratio from the data attribute list.
316     *
317     * Selects the most appropriate <code>data-{ratio}x</code> attribute from
318     * the given element's attributes. If the devices pixel ratio is greater
319     * than the largest specified image, the largest one of the available is used.
320     *
321     * @return {String|Boolean} The attribute value
322     * @method getImageAttribute
323     * @memberof jQuery.fn.dense
324     * @example
325     * var image = $('<div data-1x="image.jpg" data-2x="image_2x.jpg" />').dense('getImageAttribute');
326     * $('body').css('background-image', 'url(' + image + ')');
327     */
328
329    methods.getImageAttribute = function ()
330    {
331        var $this = $(this).eq(0), image = false, url;
332
333        for (var i = 1; i <= devicePixelRatio; i++)
334        {
335            url = $this.attr('data-' + i + 'x');
336
337            if (url)
338            {
339                image = url;
340            }
341        }
342
343        return image;
344    };
345
346    devicePixelRatio = methods.devicePixelRatio();
347
348    /**
349     * Dense offers few methods and options that can be used to both customize the
350     * plugin's functionality and return resulting values. All interaction is done through
351     * the <code>$.fn.dense()</code> method, that accepts a called method and its options
352     * object as its arguments. Both arguments are optional, and either one can be omitted.
353     *
354     * @param {String} [method=init] The called method
355     * @param {Object} [options={}] Options passed to the method
356     * @class dense
357     * @memberof jQuery.fn
358     */
359
360    $.fn.dense = function (method, options)
361    {
362        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
363        {
364            options = method;
365            method = 'init';
366        }
367
368        return methods[method].call(this, options);
369    };
370
371    /**
372     * Initialize automatically when document is ready.
373     *
374     * Dense is initialized automatically if the body element
375     * has a <code>dense-retina</code> class.
376     */
377
378    $(function ()
379    {
380        $('body.dense-retina img').dense();
381    });
382
383    /**
384     * This event is invoked when a retina image has finished loading.
385     *
386     * @event jQuery.fn.dense#denseRetinaReady.dense
387     * @type {Object}
388     */
389
390    /**
391     * This event is invoked when an image's dimension values
392     * have been updated by the <code>updateDimensions</code>
393     * method.
394     *
395     * @event jQuery.fn.dense#denseDimensionChanged.dense
396     * @type {Object}
397     */
398}));

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.