favicon.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // TODO: This file was created by bulk-decaffeinate.
  2. // Sanity-check the conversion and remove this comment.
  3. /*
  4. * decaffeinate suggestions:
  5. * DS102: Remove unnecessary code created because of implicit returns
  6. * DS208: Avoid top-level this
  7. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  8. */
  9. let defaultUrl = null;
  10. let currentSlug = null;
  11. const imageCache = {};
  12. const urlCache = {};
  13. const withImage = function (url, action) {
  14. if (imageCache[url]) {
  15. return action(imageCache[url]);
  16. } else {
  17. const img = new Image();
  18. img.crossOrigin = "anonymous";
  19. img.src = url;
  20. return (img.onload = () => {
  21. imageCache[url] = img;
  22. return action(img);
  23. });
  24. }
  25. };
  26. this.setFaviconForDoc = function (doc) {
  27. if (currentSlug === doc.slug) {
  28. return;
  29. }
  30. const favicon = $('link[rel="icon"]');
  31. if (defaultUrl === null) {
  32. defaultUrl = favicon.href;
  33. }
  34. if (urlCache[doc.slug]) {
  35. favicon.href = urlCache[doc.slug];
  36. currentSlug = doc.slug;
  37. return;
  38. }
  39. const iconEl = $(`._icon-${doc.slug.split("~")[0]}`);
  40. if (iconEl === null) {
  41. return;
  42. }
  43. const styles = window.getComputedStyle(iconEl, ":before");
  44. const backgroundPositionX = styles["background-position-x"];
  45. const backgroundPositionY = styles["background-position-y"];
  46. if (backgroundPositionX === undefined || backgroundPositionY === undefined) {
  47. return;
  48. }
  49. const bgUrl = app.config.favicon_spritesheet;
  50. const sourceSize = 16;
  51. const sourceX = Math.abs(parseInt(backgroundPositionX.slice(0, -2)));
  52. const sourceY = Math.abs(parseInt(backgroundPositionY.slice(0, -2)));
  53. return withImage(bgUrl, (docImg) =>
  54. withImage(defaultUrl, function (defaultImg) {
  55. const size = defaultImg.width;
  56. const canvas = document.createElement("canvas");
  57. const ctx = canvas.getContext("2d");
  58. canvas.width = size;
  59. canvas.height = size;
  60. ctx.drawImage(defaultImg, 0, 0);
  61. const docIconPercentage = 65;
  62. const destinationCoords = (size / 100) * (100 - docIconPercentage);
  63. const destinationSize = (size / 100) * docIconPercentage;
  64. ctx.drawImage(
  65. docImg,
  66. sourceX,
  67. sourceY,
  68. sourceSize,
  69. sourceSize,
  70. destinationCoords,
  71. destinationCoords,
  72. destinationSize,
  73. destinationSize,
  74. );
  75. try {
  76. urlCache[doc.slug] = canvas.toDataURL();
  77. favicon.href = urlCache[doc.slug];
  78. return (currentSlug = doc.slug);
  79. } catch (error) {
  80. Raven.captureException(error, { level: "info" });
  81. return this.resetFavicon();
  82. }
  83. }),
  84. );
  85. };
  86. this.resetFavicon = function () {
  87. if (defaultUrl !== null && currentSlug !== null) {
  88. $('link[rel="icon"]').href = defaultUrl;
  89. return (currentSlug = null);
  90. }
  91. };