1(function() { 2 var root = (typeof exports == 'undefined' ? window : exports); 3 4 var config = { 5 // Ensure Content-Type is an image before trying to load @2x image 6 // https://github.com/imulus/retinajs/pull/45) 7 check_mime_type: true, 8 9 // Resize high-resolution images to original image's pixel dimensions 10 // https://github.com/imulus/retinajs/issues/8 11 force_original_dimensions: true 12 }; 13 14 root.Retina = Retina; 15 16 function Retina() {} 17 18 Retina.configure = function(options) { 19 if (options == null) options = {}; 20 for (var prop in options) config[prop] = options[prop]; 21 }; 22 23 Retina.init = function(context) { 24 if (context == null) context = root; 25 26 var existing_onload = context.onload || new Function; 27 28 context.onload = function() { 29 var images = document.getElementsByTagName("img"), retinaImages = [], i, image; 30 for (i = 0; i < images.length; i++) { 31 image = images[i]; 32 retinaImages.push(new RetinaImage(image)); 33 } 34 existing_onload(); 35 } 36 }; 37 38 Retina.isRetina = function(){ 39 var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\ 40 (min--moz-device-pixel-ratio: 1.5),\ 41 (-o-min-device-pixel-ratio: 3/2),\ 42 (min-resolution: 1.5dppx)"; 43 44 if (root.devicePixelRatio > 1) 45 return true; 46 47 if (root.matchMedia && root.matchMedia(mediaQuery).matches) 48 return true; 49 50 return false; 51 }; 52 53 54 root.RetinaImagePath = RetinaImagePath; 55 56 function RetinaImagePath(path, at_2x_path) { 57 this.path = path; 58 if (typeof at_2x_path !== "undefined" && at_2x_path !== null) { 59 this.at_2x_path = at_2x_path; 60 this.perform_check = false; 61 } else { 62 this.at_2x_path = path.replace(/\.\w+$/, function(match) { return "@2x" + match; }); 63 this.perform_check = true; 64 } 65 } 66 67 RetinaImagePath.confirmed_paths = []; 68 69 RetinaImagePath.prototype.is_external = function() { 70 return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) ) 71 } 72 73 RetinaImagePath.prototype.check_2x_variant = function(callback) { 74 var http, that = this; 75 if (this.is_external()) { 76 return callback(false); 77 } else if (!this.perform_check && typeof this.at_2x_path !== "undefined" && this.at_2x_path !== null) { 78 return callback(true); 79 } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) { 80 return callback(true); 81 } else { 82 http = new XMLHttpRequest; 83 http.open('HEAD', this.at_2x_path); 84 http.onreadystatechange = function() { 85 if (http.readyState != 4) { 86 return callback(false); 87 } 88 89 if (http.status >= 200 && http.status <= 399) { 90 if (config.check_mime_type) { 91 var type = http.getResponseHeader('Content-Type'); 92 if (type == null || !type.match(/^image/i)) { 93 return callback(false); 94 } 95 } 96 97 RetinaImagePath.confirmed_paths.push(that.at_2x_path); 98 return callback(true); 99 } else { 100 return callback(false); 101 } 102 } 103 http.send(); 104 } 105 } 106 107 108 109 function RetinaImage(el) { 110 this.el = el; 111 this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x')); 112 var that = this; 113 this.path.check_2x_variant(function(hasVariant) { 114 if (hasVariant) that.swap(); 115 }); 116 } 117 118 root.RetinaImage = RetinaImage; 119 120 RetinaImage.prototype.swap = function(path) { 121 if (typeof path == 'undefined') path = this.path.at_2x_path; 122 123 var that = this; 124 function load() { 125 if (! that.el.complete) { 126 setTimeout(load, 5); 127 } else { 128 if (config.force_original_dimensions) { 129 that.el.setAttribute('width', that.el.offsetWidth); 130 that.el.setAttribute('height', that.el.offsetHeight); 131 } 132 133 that.el.setAttribute('src', path); 134 } 135 } 136 load(); 137 } 138 139 140 141 142 if (Retina.isRetina()) { 143 Retina.init(root); 144 } 145 146})(); 147
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.