From 8bca9c4ddc85b1fa45cad8a96077410483c2b24e Mon Sep 17 00:00:00 2001 From: Seth Thompson Date: Sun, 8 Jul 2018 18:15:53 -0400 Subject: [PATCH] first pass at noscript --- index.js | 93 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 30 deletions(-) diff --git a/index.js b/index.js index 67b32c1..16c609b 100644 --- a/index.js +++ b/index.js @@ -12,7 +12,7 @@ module.exports = class MonoImage extends MonoLazy { onEnter () { if (this.loaded) return - + // find best image size for the container var elWidth = this.element.offsetWidth * this.deviceRatio var imgWidth = closest(this.sizes, elWidth) @@ -45,43 +45,76 @@ module.exports = class MonoImage extends MonoLazy { createElement (image, opts) { opts = opts || {} - + this.image = image - this.sizes = Object.keys(this.image.sizes).map(s => parseInt(s)) + this.sizes = Object.keys(this.image.sizes).map(s => parseInt(s)).sort() if (typeof opts.onload === 'function') this.handleCallback = opts.onload - var attributes = { - class: `monoimage${this.loaded ? ' monoimage-loaded' : ''}` - } + var els = [] + + // first iteration constructs lazy-loaded element + // second iteration constructs noscript vanilla element + for (var i = 0; i < 2; i++) { + var noscript = (i == 1) + + var attributes = { + class: `monoimage${(this.loaded || noscript) ? ' monoimage-loaded' : ''}` + } - var styles = ` - width:100%; - display:${opts.inline ? 'inline-block' : 'block'}; - ` - - if (opts.background) { - styles += ` - background-position:center; - background-repeat:no-repeat; - background-size:${opts.background === 'contain' ? 'contain' : 'cover'}; - ${this.loaded ? `background-image:url(${this.loaded});` : ''} + var display = opts.inline ? 'inline-block' : 'block' + + // the lazy-loaded element should be hidden until + // javascript runs on the client (only applicable for SSR) + if (typeof window == 'undefined' && !noscript) { + display = 'none' + } + + var styles = ` + width:100%; + display:${display}; ` - } else { - if (this.loaded) { - attributes.src = this.loaded + + if (opts.background) { + styles += ` + background-position:center; + background-repeat:no-repeat; + background-size:${opts.background === 'contain' ? 'contain' : 'cover'}; + ` } - } - if (opts.fill) { - styles += 'height:100%;' - } else if (!this.loaded || opts.background) { - styles += `padding-top:${image.dimensions.ratio}%;` - } + if (this.loaded || noscript) { + // noscript elements load largest image size to be safe + var largestWidth = this.sizes[this.sizes.length - 1] + var src = this.loaded || this.image.sizes[largestWidth] + + if (opts.background) { + styles += ` + background-image:url(${src}); + ` + } else { + attributes.src = src + } + } + + if (opts.fill) { + styles += 'height:100%;' + } else if ((!this.loaded && !noscript) || opts.background) { + styles += `padding-top:${image.dimensions.ratio}%;` + } - attributes.style = styles.replace((/ |\r\n|\n|\r/gm),"") + attributes.style = styles.replace((/ |\r\n|\n|\r/gm),"") + + var el = opts.background + ? html`
` + : html`` + + if (noscript) { + el = html`` + } + + els.push(el) + } - return opts.background - ? html`
` - : html`` + return html`
${els}
` } }