retina-1.1.0.js 3.9 KB

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