From 5202c3f0c8da618e2d3821917f6f5d48ae8ae3c2 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Tue, 5 Dec 2017 18:47:31 +0100 Subject: fix resetFavicon so that it actually resets --- app/assets/javascripts/lib/utils/common_utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/assets/javascripts') diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index 8b5445d012b..310b731c6d8 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -393,8 +393,9 @@ export const setFavicon = (faviconPath) => { export const resetFavicon = () => { const faviconEl = document.getElementById('favicon'); - const originalFavicon = faviconEl ? faviconEl.getAttribute('href') : null; + if (faviconEl) { + const originalFavicon = faviconEl.getAttribute('data-default-href'); faviconEl.setAttribute('href', originalFavicon); } }; -- cgit v1.2.1 From 9e14f437b6ed205744d916f5566ee2c11e52b734 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Wed, 6 Dec 2017 21:04:53 +0100 Subject: create favicon overlay on the client the initial reason for this change was that graphicsmagick does not support writing to ico files. this fact lead to a chain of changes: 1. use png instead of ico (browser support is good enough) 2. render the overlays on the client using the canvas API. this way we only need to store the original favion and generate the overlay versions dynamically. this change also enables (next step) to simplify the handling of the stock favicons as well, as we don't need to generate all the versions upfront. --- app/assets/javascripts/favicon_admin.js | 19 ++++++++ app/assets/javascripts/lib/utils/common_utils.js | 50 ++++++++++++++++++++-- .../vue_merge_request_widget/mr_widget_options.vue | 5 ++- 3 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 app/assets/javascripts/favicon_admin.js (limited to 'app/assets/javascripts') diff --git a/app/assets/javascripts/favicon_admin.js b/app/assets/javascripts/favicon_admin.js new file mode 100644 index 00000000000..6b2dcf4502e --- /dev/null +++ b/app/assets/javascripts/favicon_admin.js @@ -0,0 +1,19 @@ +import {createOverlayIcon} from '~/lib/utils/common_utils'; + +export default class FaviconAdmin { + constructor() { + const faviconContainer = $('.js-favicons'); + const faviconUrl = faviconContainer.data('favicon'); + const overlayUrls = faviconContainer.data('status-overlays'); + + overlayUrls.forEach((statusOverlay) => { + createOverlayIcon(faviconUrl, statusOverlay).then((faviconWithOverlayUrl) => { + const image = $(''); + image.addClass('appearance-light-logo-preview'); + image.attr('src', faviconWithOverlayUrl); + + faviconContainer.append(image); + }); + }); + } +} diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index 310b731c6d8..d55d0585031 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -384,6 +384,49 @@ export const backOff = (fn, timeout = 60000) => { }); }; +export const createOverlayIcon = (iconPath, overlayPath) => { + const faviconImage = document.createElement('img'); + + return new Promise((resolve) => { + faviconImage.onload = () => { + const size = 32; + + const canvas = document.createElement('canvas'); + canvas.width = size; + canvas.height = size; + + const context = canvas.getContext('2d'); + context.clearRect(0, 0, size, size); + context.drawImage( + faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size, + ); + + const overlayImage = document.createElement('img'); + overlayImage.onload = () => { + context.drawImage( + overlayImage, 0, 0, overlayImage.width, overlayImage.height, 0, 0, size, size, + ); + + const faviconWithOverlayUrl = canvas.toDataURL(); + + resolve(faviconWithOverlayUrl); + }; + overlayImage.src = overlayPath; + }; + faviconImage.src = iconPath; + }); +}; + +export const setFaviconOverlay = (overlayPath) => { + const faviconEl = document.getElementById('favicon'); + + if (!faviconEl) { return null; } + + const iconPath = faviconEl.getAttribute('data-original-href'); + + return createOverlayIcon(iconPath, overlayPath).then(faviconWithOverlayUrl => faviconEl.setAttribute('href', faviconWithOverlayUrl)); +}; + export const setFavicon = (faviconPath) => { const faviconEl = document.getElementById('favicon'); if (faviconEl && faviconPath) { @@ -395,7 +438,7 @@ export const resetFavicon = () => { const faviconEl = document.getElementById('favicon'); if (faviconEl) { - const originalFavicon = faviconEl.getAttribute('data-default-href'); + const originalFavicon = faviconEl.getAttribute('data-original-href'); faviconEl.setAttribute('href', originalFavicon); } }; @@ -404,10 +447,9 @@ export const setCiStatusFavicon = pageUrl => axios.get(pageUrl) .then(({ data }) => { if (data && data.favicon) { - setFavicon(data.favicon); - } else { - resetFavicon(); + return setFaviconOverlay(data.favicon); } + return resetFavicon(); }) .catch(resetFavicon); diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index f69fe03fcb3..d6cba878b28 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -36,7 +36,7 @@ import { notify, SourceBranchRemovalStatus, } from './dependencies'; -import { setFavicon } from '../lib/utils/common_utils'; +import { setFaviconOverlay } from '../lib/utils/common_utils'; export default { el: '#js-vue-mr-widget', @@ -159,8 +159,9 @@ export default { }, setFaviconHelper() { if (this.mr.ciStatusFaviconPath) { - setFavicon(this.mr.ciStatusFaviconPath); + return setFaviconOverlay(this.mr.ciStatusFaviconPath); } + return Promise.resolve(); }, fetchDeployments() { return this.service.fetchDeployments() -- cgit v1.2.1 From 949c30d42b91a0dd3959a3ca303b8f76158a2556 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Thu, 7 Dec 2017 13:15:49 +0100 Subject: remove all .ico favicon variations, use png always the ci status icons are generated client side, wo we don't need the static files anymore. --- app/assets/javascripts/favicon_admin.js | 2 +- app/assets/javascripts/vue_shared/components/file_icon/file_icon_map.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app/assets/javascripts') diff --git a/app/assets/javascripts/favicon_admin.js b/app/assets/javascripts/favicon_admin.js index 6b2dcf4502e..97e87054ce0 100644 --- a/app/assets/javascripts/favicon_admin.js +++ b/app/assets/javascripts/favicon_admin.js @@ -4,7 +4,7 @@ export default class FaviconAdmin { constructor() { const faviconContainer = $('.js-favicons'); const faviconUrl = faviconContainer.data('favicon'); - const overlayUrls = faviconContainer.data('status-overlays'); + const overlayUrls = faviconContainer.data('status-overlays') || []; overlayUrls.forEach((statusOverlay) => { createOverlayIcon(faviconUrl, statusOverlay).then((faviconWithOverlayUrl) => { diff --git a/app/assets/javascripts/vue_shared/components/file_icon/file_icon_map.js b/app/assets/javascripts/vue_shared/components/file_icon/file_icon_map.js index 9ffbaae3ea5..9bca1993ccc 100644 --- a/app/assets/javascripts/vue_shared/components/file_icon/file_icon_map.js +++ b/app/assets/javascripts/vue_shared/components/file_icon/file_icon_map.js @@ -513,7 +513,7 @@ const fileNameIcons = { 'credits.md': 'credits', 'credits.md.rendered': 'credits', '.flowconfig': 'flow', - 'favicon.ico': 'favicon', + 'favicon.png': 'favicon', 'karma.conf.js': 'karma', 'karma.conf.ts': 'karma', 'karma.conf.coffee': 'karma', -- cgit v1.2.1 From b4d84c07bcf143aeab7abccb8d0cdb849f605af5 Mon Sep 17 00:00:00 2001 From: Alexis Reigel Date: Mon, 5 Feb 2018 15:41:37 +0100 Subject: remove favicon preview on appearance page --- app/assets/javascripts/favicon_admin.js | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 app/assets/javascripts/favicon_admin.js (limited to 'app/assets/javascripts') diff --git a/app/assets/javascripts/favicon_admin.js b/app/assets/javascripts/favicon_admin.js deleted file mode 100644 index 97e87054ce0..00000000000 --- a/app/assets/javascripts/favicon_admin.js +++ /dev/null @@ -1,19 +0,0 @@ -import {createOverlayIcon} from '~/lib/utils/common_utils'; - -export default class FaviconAdmin { - constructor() { - const faviconContainer = $('.js-favicons'); - const faviconUrl = faviconContainer.data('favicon'); - const overlayUrls = faviconContainer.data('status-overlays') || []; - - overlayUrls.forEach((statusOverlay) => { - createOverlayIcon(faviconUrl, statusOverlay).then((faviconWithOverlayUrl) => { - const image = $(''); - image.addClass('appearance-light-logo-preview'); - image.attr('src', faviconWithOverlayUrl); - - faviconContainer.append(image); - }); - }); - } -} -- cgit v1.2.1