From c9feb1c18af8b3bcb0c58fac77fe52289c2153c4 Mon Sep 17 00:00:00 2001 From: Nils Enevoldsen Date: Thu, 26 Apr 2018 21:17:23 -0400 Subject: [PATCH] Modernize image fetching; use proper error handling Fixes #25 This breaks on old browsers, which probably isn't a problem since it's optional functionality. A fetch polyfill could be added if needed. --- modules/ext.scryfallLinks.less | 5 +-- modules/ext.scryfallLinks.tooltip.js | 67 ++++++++++++++++++---------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/modules/ext.scryfallLinks.less b/modules/ext.scryfallLinks.less index 3d5531d..032e273 100644 --- a/modules/ext.scryfallLinks.less +++ b/modules/ext.scryfallLinks.less @@ -13,11 +13,10 @@ div.tippy-tooltip.scryfall-theme { width: 244px; height: 340px; } -div.tippy-content > a { +div.tippy-tooltip.ext-scryfall-notfound { + border-radius: 12px; color: #fff; text-shadow: 2px 2px 6px #000; - font-size: x-large; - font-weight: bold; } img.ext-scryfall-cardimage { border-radius: 12px; diff --git a/modules/ext.scryfallLinks.tooltip.js b/modules/ext.scryfallLinks.tooltip.js index 42bfbc0..5d564ee 100644 --- a/modules/ext.scryfallLinks.tooltip.js +++ b/modules/ext.scryfallLinks.tooltip.js @@ -7,13 +7,12 @@ $( function () { /* global tippy */ - tippy( '.ext-scryfall-link', { + const tip = tippy( '.ext-scryfall-link', { arrow: false, animateFill: false, - // "followCursor" mutually exclusive with "interactive" followCursor: true, html: '#js--card-popup', - placement: 'bottom', + placement: 'top', touchHold: true, delay: [ 50, 0 ], animation: 'fade', @@ -21,30 +20,52 @@ $( function () { performance: true, theme: 'scryfall', onShow() { - var thisPopper = this, - cardImage = new Image( 244 ); - /* eslint no-underscore-dangle: ["error", { "allow": ["_reference"] }] */ - const target = thisPopper._reference, - anchorElement = '', - cardNameQuery = '&exact=' + target.dataset.cardName, + const thisPopper = this, + content = thisPopper.querySelector( '.tippy-content' ), + /* eslint no-underscore-dangle: ["error", { "allow": ["_reference"] }] */ + target = thisPopper._reference, + cardNameParam = 'exact=' + target.dataset.cardName, cardSet = target.dataset.cardSet, - cardSetQuery = cardSet ? '&set=' + cardSet : '', - formatQuery = '&format=image', - versionQuery = '&version=normal', - imageSrc = 'https://api.scryfall.com/cards/named?' + cardNameQuery + cardSetQuery + formatQuery + versionQuery; + cardSetParam = cardSet ? '&set=' + cardSet : '', + formatParam = '&format=image', + versionParam = '&version=normal', + imageSrc = 'https://api.scryfall.com/cards/named?' + cardNameParam + cardSetParam + formatParam + versionParam; + if ( tip.loading || content.innerHTML !== '' ) { return; } + tip.loading = true; + // Hide the tooltip until we've finished loaded the image thisPopper.style.display = 'none'; - thisPopper.querySelector( '.tippy-content' ).innerHTML = anchorElement; - cardImage.alt = target.text; - cardImage.className = 'ext-scryfall-cardimage'; - cardImage.onload = function () { - var placeholder = thisPopper.querySelector( '.ext-scryfall-placeholder' ); - placeholder.replaceWith( cardImage ); - thisPopper.style.display = ''; - }; - cardImage.src = imageSrc; + // fetch() only works on modern browsers + fetch( imageSrc ) + .then( response => { + if ( !response.ok ) { + throw Error( response.statusText ); + } + return response; + } ) + .then( response => response.blob() ) + .then( blob => { + const url = URL.createObjectURL( blob ), + img = document.createElement( 'img' ); + img.classList.add( 'ext-scryfall-cardimage' ); + img.src = url; + img.alt = target.text; + img.width = 244; + content.append( img ); + thisPopper.style.removeProperty( 'display' ); + tip.loading = false; + } ) + .catch( function () { + // TODO: This should be localized + content.innerHTML = 'Not found'; + content.parentNode.classList.remove( 'scryfall-theme' ); + content.parentNode.classList.add( 'ext-scryfall-notfound' ); + thisPopper.style.removeProperty( 'display' ); + tip.loading = false; + } ); }, onHidden() { - this.querySelector( '.tippy-content' ).innerHTML = ''; + const content = this.querySelector( '.tippy-content' ); + content.innerHTML = ''; }, // prevent tooltip from displaying over button popperOptions: {