144 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| (function() {
 | |
| 
 | |
|   var root = (typeof exports == 'undefined' ? window : exports);
 | |
| 
 | |
|   var config = {
 | |
|     // Ensure Content-Type is an image before trying to load @2x image
 | |
|     // https://github.com/imulus/retinajs/pull/45)
 | |
|     check_mime_type: true
 | |
|   };
 | |
| 
 | |
| 
 | |
| 
 | |
|   root.Retina = Retina;
 | |
| 
 | |
|   function Retina() {}
 | |
| 
 | |
|   Retina.configure = function(options) {
 | |
|     if (options == null) options = {};
 | |
|     for (var prop in options) config[prop] = options[prop];
 | |
|   };
 | |
| 
 | |
|   Retina.init = function(context) {
 | |
|     if (context == null) context = root;
 | |
| 
 | |
|     var existing_onload = context.onload || new Function;
 | |
| 
 | |
|     context.onload = function() {
 | |
|       var images = document.getElementsByTagName("img"), retinaImages = [], i, image;
 | |
|       for (i = 0; i < images.length; i++) {
 | |
|         image = images[i];
 | |
|         retinaImages.push(new RetinaImage(image));
 | |
|       }
 | |
|       existing_onload();
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   Retina.isRetina = function(){
 | |
|     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)";
 | |
| 
 | |
|     if (root.devicePixelRatio > 1)
 | |
|       return true;
 | |
| 
 | |
|     if (root.matchMedia && root.matchMedia(mediaQuery).matches)
 | |
|       return true;
 | |
| 
 | |
|     return false;
 | |
|   };
 | |
| 
 | |
| 
 | |
|   root.RetinaImagePath = RetinaImagePath;
 | |
| 
 | |
|   function RetinaImagePath(path, at_2x_path) {
 | |
|     this.path = path;
 | |
|     if (typeof at_2x_path !== "undefined" && at_2x_path !== null) {
 | |
|       this.at_2x_path = at_2x_path;
 | |
|       this.perform_check = false;
 | |
|     } else {
 | |
|       this.at_2x_path = path.replace(/\.\w+$/, function(match) { return "@2x" + match; });
 | |
|       this.perform_check = true;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   RetinaImagePath.confirmed_paths = [];
 | |
| 
 | |
|   RetinaImagePath.prototype.is_external = function() {
 | |
|     return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) )
 | |
|   }
 | |
| 
 | |
|   RetinaImagePath.prototype.check_2x_variant = function(callback) {
 | |
|     var http, that = this;
 | |
|     if (this.is_external()) {
 | |
|       return callback(false);
 | |
|     } else if (!this.perform_check && typeof this.at_2x_path !== "undefined" && this.at_2x_path !== null) {
 | |
|       return callback(true);
 | |
|     } else if (this.at_2x_path in RetinaImagePath.confirmed_paths) {
 | |
|       return callback(true);
 | |
|     } else {
 | |
|       http = new XMLHttpRequest;
 | |
|       http.open('HEAD', this.at_2x_path);
 | |
|       http.onreadystatechange = function() {
 | |
|         if (http.readyState != 4) {
 | |
|           return callback(false);
 | |
|         }
 | |
| 
 | |
|         if (http.status >= 200 && http.status <= 399) {
 | |
|           if (config.check_mime_type) {
 | |
|             var type = http.getResponseHeader('Content-Type');
 | |
|             if (type == null || !type.match(/^image/i)) {
 | |
|               return callback(false);
 | |
|             }
 | |
|           }
 | |
| 
 | |
|           RetinaImagePath.confirmed_paths.push(that.at_2x_path);
 | |
|           return callback(true);
 | |
|         } else {
 | |
|           return callback(false);
 | |
|         }
 | |
|       }
 | |
|       http.send();
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
|   function RetinaImage(el) {
 | |
|     this.el = el;
 | |
|     this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x'));
 | |
|     var that = this;
 | |
|     this.path.check_2x_variant(function(hasVariant) {
 | |
|       if (hasVariant) that.swap();
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   root.RetinaImage = RetinaImage;
 | |
| 
 | |
|   RetinaImage.prototype.swap = function(path) {
 | |
|     if (typeof path == 'undefined') path = this.path.at_2x_path;
 | |
| 
 | |
|     var that = this;
 | |
|     function load() {
 | |
|       if (! that.el.complete) {
 | |
|         setTimeout(load, 5);
 | |
|       } else {
 | |
|         that.el.setAttribute('width', that.el.offsetWidth);
 | |
|         that.el.setAttribute('height', that.el.offsetHeight);
 | |
|         that.el.setAttribute('src', path);
 | |
|       }
 | |
|     }
 | |
|     load();
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|   if (Retina.isRetina()) {
 | |
|     Retina.init(root);
 | |
|   }
 | |
| 
 | |
| })();
 | |
| 
 |