From f007eb38d544c4d99428083edd2f8d6152cb5546 Mon Sep 17 00:00:00 2001 From: simonihmig Date: Mon, 22 Feb 2021 00:57:23 +0100 Subject: [PATCH 1/2] Apply LQIP styles with dynamically generated CSS, to support FastBoot Instead of applying styles with JS *after* rehydration, which is too late. --- addon/components/responsive-image.hbs | 4 +- addon/components/responsive-image.ts | 57 ++++--------------- addon/services/responsive-image.ts | 6 +- addon/styles/ember-responsive-image.css | 4 ++ addon/utils/data-uri.ts | 7 --- index.js | 16 ++++++ lib/css-writer.js | 51 +++++++++++++++++ lib/plugins/lqip-color.js | 16 +++++- lib/plugins/lqip-inline.js | 24 +++++++- .../blurry-svg.ts => lib/utils/blurry-svg.js | 8 +-- lib/utils/data-uri.js | 5 ++ package.json | 1 + tests/dummy/app/templates/image.hbs | 6 +- tests/fastboot/image-test.js | 32 ++++++++++- .../components/responsive-image-test.js | 35 +++++++----- yarn.lock | 9 ++- 16 files changed, 192 insertions(+), 89 deletions(-) delete mode 100644 addon/utils/data-uri.ts create mode 100644 lib/css-writer.js rename addon/utils/blurry-svg.ts => lib/utils/blurry-svg.js (85%) create mode 100644 lib/utils/data-uri.js diff --git a/addon/components/responsive-image.hbs b/addon/components/responsive-image.hbs index 3e12b1995..343d53c69 100644 --- a/addon/components/responsive-image.hbs +++ b/addon/components/responsive-image.hbs @@ -10,14 +10,12 @@ src={{this.src}} width={{this.width}} height={{this.height}} - class="eri-{{this.layout}}" + class={{this.classNames}} loading="lazy" decoding="async" ...attributes {{style - (if this.showLqipImage (hash background-image=this.lqipImage background-size="cover")) (if this.showLqipBlurhash (hash background-image=this.lqipBlurhash background-size="cover")) - (if this.showLqipColor (hash background-color=this.lqipColor)) }} {{on "load" this.onLoad}} /> diff --git a/addon/components/responsive-image.ts b/addon/components/responsive-image.ts index ea5697f83..12627d23e 100644 --- a/addon/components/responsive-image.ts +++ b/addon/components/responsive-image.ts @@ -4,19 +4,12 @@ import ResponsiveImageService, { ImageMeta, ImageType, LqipBlurhash, - LqipColor, - LqipInline, Meta, } from 'ember-responsive-image/services/responsive-image'; import { assert } from '@ember/debug'; -import dataUri from 'ember-responsive-image/utils/data-uri'; -import blurrySvg from 'ember-responsive-image/utils/blurry-svg'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; -import { - macroCondition, - getOwnConfig /*, importSync*/, -} from '@embroider/macros'; +import { getOwnConfig, macroCondition } from '@embroider/macros'; import { decode } from 'blurhash'; declare module '@embroider/macros' { @@ -187,47 +180,17 @@ export default class ResponsiveImageComponent extends Component).lqip as LqipInline; - - const uri = dataUri( - blurrySvg( - dataUri(lqip.image, 'image/png', true), - lqip.width, - lqip.height - ), - 'image/svg+xml' - ); - - return `url("${uri}")`; - } - - get hasLqipColor(): boolean { - return this.meta.lqip?.type === 'color'; - } - - get showLqipColor(): boolean { - return !this.isLoaded && this.hasLqipColor; - } - - get lqipColor(): string | undefined { - if (!this.hasLqipColor) { - return undefined; + get classNames(): string { + const classNames = [`eri-${this.layout}`]; + const lqip = this.meta.lqip; + if (lqip && !this.isLoaded) { + classNames.push(`eri-lqip-${lqip.type}`); + if (lqip.type === 'color' || lqip.type === 'inline') { + classNames.push(lqip.class); + } } - const lqip = (this.meta as Required).lqip as LqipColor; - return lqip.color; + return classNames.join(' '); } get hasLqipBlurhash(): boolean { diff --git a/addon/services/responsive-image.ts b/addon/services/responsive-image.ts index 9f12b5565..78aa016ca 100644 --- a/addon/services/responsive-image.ts +++ b/addon/services/responsive-image.ts @@ -13,14 +13,12 @@ export interface LqipBase { export interface LqipInline extends LqipBase { type: 'inline'; - image: string; - width: number; - height: number; + class: string; } export interface LqipColor extends LqipBase { type: 'color'; - color: string; + class: string; } export interface LqipBlurhash extends LqipBase { diff --git a/addon/styles/ember-responsive-image.css b/addon/styles/ember-responsive-image.css index ea6b02fbc..a59125afd 100644 --- a/addon/styles/ember-responsive-image.css +++ b/addon/styles/ember-responsive-image.css @@ -7,3 +7,7 @@ .eri-responsive { content-visibility: auto; } + +.eri-lqip-inline { + background-size: cover; +} diff --git a/addon/utils/data-uri.ts b/addon/utils/data-uri.ts deleted file mode 100644 index 6fa1dd976..000000000 --- a/addon/utils/data-uri.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default function dataUri( - data: string, - type: string, - base64 = false -): string { - return `data:${type};base64,${base64 ? data : btoa(data)}`; -} diff --git a/index.js b/index.js index 712e23c03..cfd823bec 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,7 @@ const path = require('path'); const Funnel = require('broccoli-funnel'); const Writer = require('./lib/image-writer'); +const CssWriter = require('./lib/css-writer'); const fs = require('fs-extra'); const map = require('broccoli-stew').map; const mergeTrees = require('broccoli-merge-trees'); @@ -26,6 +27,7 @@ module.exports = { metaData: {}, configData: {}, app: null, + cssExtensions: [], metadataExtensions: [], extendedMetaData: null, imagePreProcessors: [], @@ -62,6 +64,10 @@ module.exports = { this.metadataExtensions.push({ callback, target }); }, + addCssExtension(callback, target) { + this.cssExtensions.push({ callback, target }); + }, + /** * Add a callback function to hook into image processing before the addon's image processes are executed. * The callback method you provide must have the following signature: @@ -223,6 +229,7 @@ module.exports = { // we write our image meta data as a script tag into the app's index.html, which the service will read from // (that happens only in the browser, where we have easy access to the DOM. For FastBoot this is different, see below) if (type === 'head-footer') { + console.log('content'); return [ '