diff --git a/app/assets/javascripts/comfy/admin/cms/page_file.js b/app/assets/javascripts/comfy/admin/cms/page_file.js index 24862e94d..2dc009819 100644 --- a/app/assets/javascripts/comfy/admin/cms/page_file.js +++ b/app/assets/javascripts/comfy/admin/cms/page_file.js @@ -1,36 +1,66 @@ -(($) => { - const isImageFile = (link) => !!link.dataset.cmsPageFileThumbUrl; +(() => { + const isFirefox = /\bFirefox\//.test(navigator.userAgent); - const buildPageFileThumbnail = (link) => { - const img = new Image(); - img.src = link.dataset.cmsPageFileThumbUrl; - return img; - }; + class PageFileLink { + constructor(link) { + this.link = link; + this.isImage = !!link.dataset.cmsPageFileThumbUrl; + + link.addEventListener('dragstart', (evt) => { + evt.dataTransfer.setData('text/plain', this.link.dataset.cmsPageFileLinkTag); + }); - const onDragStart = (evt) => { - const link = evt.target; - evt.dataTransfer.setData('text/plain', link.dataset.cmsPageFileLinkTag); - if (isImageFile(link)) { - evt.dataTransfer.setDragImage(buildPageFileThumbnail(link), 4, 2); - $(link).popover('hide'); + if (this.isImage) { + new bootstrap.Popover(link, { + trigger: 'hover', + placement: 'top', + content: this.buildPageFileThumbnail(), + html: true + }); + + link.addEventListener('dragstart', (evt) => { + evt.dataTransfer.setDragImage(this.buildPageFileThumbnail(), 4, 2); + this.getPopover().hide(); + }); + + this.workAroundFirefoxPopoverGlitch(); + } } - }; - const initPageFileLink = (link) => { - link.addEventListener('dragstart', onDragStart); - if (isImageFile(link)) { - $(link).popover({ - trigger: 'hover', - placement: 'top', - content: buildPageFileThumbnail(link), - html: true + buildPageFileThumbnail() { + const img = new Image(); + img.src = this.link.dataset.cmsPageFileThumbUrl; + return img; + } + + // To work around a Firefox bug causing the popover to re-appear after the drop: + // https://github.com/comfy/comfortable-mexican-sofa/pull/799#issuecomment-369124161 + // + // Possibly related to: + // https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + workAroundFirefoxPopoverGlitch() { + if (!isFirefox) return; + this.link.addEventListener('dragstart', () => { + this.getPopover().disable(); + }); + this.link.addEventListener('dragend', () => { + setTimeout(() => { + const popover = this.getPopover(); + popover.enable(); + popover.hide(); + }, 300); }); } - }; + + // We can't keep a reference to the Popover object, because Bootstrap re-creates it internally. + getPopover() { + return jQuery(this.link).data(bootstrap.Popover.DATA_KEY); + } + } window.CMS.page_files = () => { for (const link of document.querySelectorAll('[data-cms-page-file-link-tag]')) { - initPageFileLink(link); + new PageFileLink(link); } }; -})(jQuery); +})();