1/*! 2 * Retina.js v1.3.0 3 * 4 * Copyright 2014 Imulus, LLC 5 * Released under the MIT license 6 * 7 * Retina.js is an open source script that makes it easy to serve 8 * high-resolution images to devices with retina displays. 9 */ 10 11(function() { 12 var root = (typeof exports === 'undefined' ? window : exports); 13 var config = { 14 // An option to choose a suffix for 2x images 15 retinaImageSuffix : '@2x', 16 17 // Ensure Content-Type is an image before trying to load @2x image 18 // https://github.com/imulus/retinajs/pull/45) 19 check_mime_type: true, 20 21 // Resize high-resolution images to original image's pixel dimensions 22 // https://github.com/imulus/retinajs/issues/8 23 force_original_dimensions: true 24 }; 25 26 function Retina() {} 27 28 root.Retina = Retina; 29 30 Retina.configure = function(options) { 31 if (options === null) { 32 options = {}; 33 } 34 35 for (var prop in options) { 36 if (options.hasOwnProperty(prop)) { 37 config[prop] = options[prop]; 38 } 39 } 40 }; 41 42 Retina.init = function(context) { 43 if (context === null) { 44 context = root; 45 } 46 47 var existing_onload = context.onload || function(){}; 48 49 context.onload = function() { 50 var images = document.getElementsByTagName('img'), retinaImages = [], i, image; 51 for (i = 0; i < images.length; i += 1) { 52 image = images[i]; 53 if (!!!image.getAttributeNode('data-no-retina')) { 54 retinaImages.push(new RetinaImage(image)); 55 } 56 } 57 existing_onload(); 58 }; 59 }; 60 61 Retina.isRetina = function(){ 62 var mediaQuery = '(-webkit-min-device-pixel-ratio: 1.5), (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (min-resolution: 1.5dppx)'; 63 64 if (root.devicePixelRatio > 1) { 65 return true; 66 } 67 68 if (root.matchMedia && root.matchMedia(mediaQuery).matches) { 69 return true; 70 } 71 72 return false; 73 }; 74 75 76 var regexMatch = /\.\w+$/; 77 function suffixReplace (match) { 78 return config.retinaImageSuffix + match; 79 } 80 81 function RetinaImagePath(path, at_2x_path) { 82 this.path = path || ''; 83 if (typeof at_2x_path !== 'undefined' && at_2x_path !== null) { 84 this.at_2x_path = at_2x_path; 85 this.perform_check = false; 86 } else { 87 if (undefined !== document.createElement) { 88 var locationObject = document.createElement('a'); 89 locationObject.href = this.path; 90 locationObject.pathname = locationObject.pathname.replace(regexMatch, suffixReplace); 91 this.at_2x_path = locationObject.href; 92 } else { 93 var parts = this.path.split('?'); 94 parts[0] = parts[0].replace(regexMatch, suffixReplace); 95 this.at_2x_path = parts.join('?'); 96 } 97 this.perform_check = true; 98 } 99 } 100 101 root.RetinaImagePath = RetinaImagePath; 102 103 RetinaImagePath.confirmed_paths = []; 104 105 RetinaImagePath.prototype.is_external = function() { 106 return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) ); 107 }; 108 109 RetinaImagePath.prototype.check_2x_variant = function(callback) { 110 var http, that = this; 111 if (this.is_external()) { 112 return callback(false); 113 } else if (!this.perform_check && typeof this.at_2x_path !== 'undefined' && this.at_2x_path !== null) { 114 return callback(true); 115 } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) { 116 return callback(true); 117 } else { 118 http = new XMLHttpRequest(); 119 http.open('HEAD', this.at_2x_path); 120 http.onreadystatechange = function() { 121 if (http.readyState !== 4) { 122 return callback(false); 123 } 124 125 if (http.status >= 200 && http.status <= 399) { 126 if (config.check_mime_type) { 127 var type = http.getResponseHeader('Content-Type'); 128 if (type === null || !type.match(/^image/i)) { 129 return callback(false); 130 } 131 } 132 133 RetinaImagePath.confirmed_paths.push(that.at_2x_path); 134 return callback(true); 135 } else { 136 return callback(false); 137 } 138 }; 139 http.send(); 140 } 141 }; 142 143 144 function RetinaImage(el) { 145 this.el = el; 146 this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x')); 147 var that = this; 148 this.path.check_2x_variant(function(hasVariant) { 149 if (hasVariant) { 150 that.swap(); 151 } 152 }); 153 } 154 155 root.RetinaImage = RetinaImage; 156 157 RetinaImage.prototype.swap = function(path) { 158 if (typeof path === 'undefined') { 159 path = this.path.at_2x_path; 160 } 161 162 var that = this; 163 function load() { 164 if (! that.el.complete) { 165 setTimeout(load, 5); 166 } else { 167 if (config.force_original_dimensions) { 168 that.el.setAttribute('width', that.el.offsetWidth); 169 that.el.setAttribute('height', that.el.offsetHeight); 170 } 171 172 that.el.setAttribute('src', path); 173 } 174 } 175 load(); 176 }; 177 178 179 if (Retina.isRetina()) { 180 Retina.init(root); 181 } 182})();
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.