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 11var retina = {}; 12retina.root = (typeof exports === 'undefined' ? window : exports); 13retina.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 }; 25retina.config.retinaImagePattern = new RegExp( retina.config.retinaImageSuffix + "." ); 26 27(function() { 28 function Retina() {} 29 30 window.retina.root.Retina = Retina; 31 32 Retina.configure = function(options) { 33 if (options === null) { 34 options = {}; 35 } 36 37 for (var prop in options) { 38 if (options.hasOwnProperty(prop)) { 39 window.retina.config[prop] = options[prop]; 40 } 41 } 42 }; 43 44 Retina.init = function(context) { 45 if (context === null) { 46 context = window.retina.root; 47 } 48 49 var existing_onload = context.onload || function(){}; 50 51 context.onload = function() { 52 var images = document.getElementsByTagName('img'), retinaImages = [], i, image; 53 for (i = 0; i < images.length; i += 1) { 54 image = images[i]; 55 if ( !retina.config.retinaImagePattern.test(image.getAttribute("src")) ){ 56 if (!!!image.getAttributeNode('data-no-retina')) { 57 retinaImages.push(new RetinaImage(image)); 58 } 59 } 60 } 61 existing_onload(); 62 }; 63 }; 64 65 Retina.isRetina = function(){ 66 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)'; 67 68 if (window.retina.root.devicePixelRatio > 1) { 69 return true; 70 } 71 72 if (window.retina.root.matchMedia && window.retina.root.matchMedia(mediaQuery).matches) { 73 return true; 74 } 75 76 return false; 77 }; 78 79 80 var regexMatch = /\.\w+$/; 81 function suffixReplace (match) { 82 return window.retina.config.retinaImageSuffix + match; 83 } 84 85 function RetinaImagePath(path, at_2x_path) { 86 this.path = path || ''; 87 if (typeof at_2x_path !== 'undefined' && at_2x_path !== null) { 88 this.at_2x_path = at_2x_path; 89 this.perform_check = false; 90 } else { 91 if (undefined !== document.createElement) { 92 var locationObject = document.createElement('a'); 93 locationObject.href = this.path; 94 locationObject.pathname = locationObject.pathname.replace(regexMatch, suffixReplace); 95 this.at_2x_path = locationObject.href; 96 } else { 97 var parts = this.path.split('?'); 98 parts[0] = parts[0].replace(regexMatch, suffixReplace); 99 this.at_2x_path = parts.join('?'); 100 } 101 this.perform_check = true; 102 } 103 } 104 105 window.retina.root.RetinaImagePath = RetinaImagePath; 106 107 RetinaImagePath.confirmed_paths = []; 108 109 RetinaImagePath.prototype.is_external = function() { 110 return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) ); 111 }; 112 113 RetinaImagePath.prototype.check_2x_variant = function(callback) { 114 var http, that = this; 115 if (this.is_external()) { 116 return callback(false); 117 } else if (!this.perform_check && typeof this.at_2x_path !== 'undefined' && this.at_2x_path !== null) { 118 return callback(true); 119 } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) { 120 return callback(true); 121 } else { 122 http = new XMLHttpRequest(); 123 http.open('HEAD', this.at_2x_path); 124 http.onreadystatechange = function() { 125 if (http.readyState !== 4) { 126 return callback(false); 127 } 128 129 if (http.status >= 200 && http.status <= 399) {
130 if (window.retina.config.check_mime_type) { 131 var type = http.getResponseHeader('Content-Type'); 132 if (type === null || !type.match(/^image/i)) { 133 return callback(false); 134 } 135 } 136 137 RetinaImagePath.confirmed_paths.push(that.at_2x_path); 138 return callback(true); 139 } else { 140 return callback(false); 141 } 142 }; 143 http.send(); 144 } 145 }; 146 147 148 function RetinaImage(el) { 149 this.el = el; 150 this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x')); 151 var that = this; 152 this.path.check_2x_variant(function(hasVariant) { 153 if (hasVariant) { 154 that.swap(); 155 } 156 }); 157 } 158 159 window.retina.root.RetinaImage = RetinaImage; 160 161 RetinaImage.prototype.swap = function(path) { 162 if (typeof path === 'undefined') { 163 path = this.path.at_2x_path; 164 } 165 166 var that = this; 167 function load() { 168 var width = that.el.offsetWidth; 169 var height = that.el.offsetHeight; 170 if ( !that.el.complete || !width || !height ) { 171 setTimeout(load, 5); 172 } else { 173 if (window.retina.config.force_original_dimensions) { 174 that.el.setAttribute('width', width); 175 that.el.setAttribute('height', height); 176 } 177 178 that.el.setAttribute('src', path); 179 } 180 } 181 load(); 182 }; 183 184 185 if (Retina.isRetina()) { 186 Retina.init(window.retina.root); 187 } 188})();
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.