favicon.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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) { return; }
  28. const favicon = $('link[rel="icon"]');
  29. if (defaultUrl === null) {
  30. defaultUrl = favicon.href;
  31. }
  32. if (urlCache[doc.slug]) {
  33. favicon.href = urlCache[doc.slug];
  34. currentSlug = doc.slug;
  35. return;
  36. }
  37. const iconEl = $(`._icon-${doc.slug.split('~')[0]}`);
  38. if (iconEl === null) { return; }
  39. const styles = window.getComputedStyle(iconEl, ':before');
  40. const backgroundPositionX = styles['background-position-x'];
  41. const backgroundPositionY = styles['background-position-y'];
  42. if ((backgroundPositionX === undefined) || (backgroundPositionY === undefined)) { return; }
  43. const bgUrl = app.config.favicon_spritesheet;
  44. const sourceSize = 16;
  45. const sourceX = Math.abs(parseInt(backgroundPositionX.slice(0, -2)));
  46. const sourceY = Math.abs(parseInt(backgroundPositionY.slice(0, -2)));
  47. return withImage(bgUrl, docImg => withImage(defaultUrl, function(defaultImg) {
  48. const size = defaultImg.width;
  49. const canvas = document.createElement('canvas');
  50. const ctx = canvas.getContext('2d');
  51. canvas.width = size;
  52. canvas.height = size;
  53. ctx.drawImage(defaultImg, 0, 0);
  54. const docIconPercentage = 65;
  55. const destinationCoords = (size / 100) * (100 - docIconPercentage);
  56. const destinationSize = (size / 100) * docIconPercentage;
  57. ctx.drawImage(docImg, sourceX, sourceY, sourceSize, sourceSize, destinationCoords, destinationCoords, destinationSize, destinationSize);
  58. try {
  59. urlCache[doc.slug] = canvas.toDataURL();
  60. favicon.href = urlCache[doc.slug];
  61. return currentSlug = doc.slug;
  62. } catch (error) {
  63. Raven.captureException(error, { level: 'info' });
  64. return this.resetFavicon();
  65. }
  66. }));
  67. };
  68. this.resetFavicon = function() {
  69. if ((defaultUrl !== null) && (currentSlug !== null)) {
  70. $('link[rel="icon"]').href = defaultUrl;
  71. return currentSlug = null;
  72. }
  73. };