From 038b267a7bea65e04bbc2d0595ba40034b1c7216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Philipczyk?= Date: Mon, 18 Sep 2023 08:01:13 +0200 Subject: [PATCH 1/4] chore: add watch to html and react packages --- packages/html/package.json | 2 ++ packages/react/package.json | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/html/package.json b/packages/html/package.json index d5b49dee..77c7fbe3 100644 --- a/packages/html/package.json +++ b/packages/html/package.json @@ -10,6 +10,7 @@ "sideEffects": false, "repository": "https://github.com/cloudinary/frontend-frameworks", "scripts": { + "watch": "onchange 'src/**/*.*' -- npm run build", "build": "tsc && npm run prepare-build && rollup -c", "postbuild": "cp index.esm.* ./dist && cp index.umd.* ./dist", "prepare-build": "cp package.json ./dist", @@ -26,6 +27,7 @@ "core-js": "^3.23.5", "jest": "^29.3.1", "jest-environment-jsdom": "^29.3.1", + "onchange": "7.1.0", "rollup": "^2.52.2", "rollup-plugin-peer-deps-external": "^2.2.4", "rollup-plugin-typescript2": "^0.34.1", diff --git a/packages/react/package.json b/packages/react/package.json index 53938290..589f66a7 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -13,6 +13,7 @@ "node": ">=10" }, "scripts": { + "watch": "onchange 'src/*.*' -- npm run build", "build": "npm run build --prefix ../html && tsc && rollup -c && cp package.json ./dist", "test": "jest --config jest.config.json", "test-coverage": "jest --coverage" @@ -57,6 +58,7 @@ "eslint-plugin-react": "^7.17.0", "eslint-plugin-standard": "^4.0.1", "gh-pages": "^2.2.0", + "onchange": "7.1.0", "npm-run-all": "^4.1.5", "prettier": "^2.0.4", "react": "^16.13.1", From b41fbc872b4b0ca1fc752dc2002058a3d86d1ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Philipczyk?= Date: Mon, 18 Sep 2023 14:11:08 +0200 Subject: [PATCH 2/4] fix: update dependencies in react and html playgrounds --- playground/html/package.json | 2 +- playground/react/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playground/html/package.json b/playground/html/package.json index db4f9c95..6a501057 100644 --- a/playground/html/package.json +++ b/playground/html/package.json @@ -13,7 +13,7 @@ "vite": "^4.0.0" }, "dependencies": { - "@cloudinary/html": "1.11.2", + "@cloudinary/html": "file:../../packages/html/dist", "@cloudinary/url-gen": "^1.8.7" } } diff --git a/playground/react/package.json b/playground/react/package.json index ea159bfe..3ce43865 100644 --- a/playground/react/package.json +++ b/playground/react/package.json @@ -9,7 +9,7 @@ "preview": "vite preview" }, "dependencies": { - "@cloudinary/react": "1.11.2", + "@cloudinary/react": "file:../../packages/react/dist", "@cloudinary/url-gen": "^1.10.0", "react": "^16.0.0", "react-dom": "^16.0.0" From b9f6821a97dc8f737f39ccb6f0b7b5b590e89e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Philipczyk?= Date: Wed, 20 Sep 2023 14:32:29 +0200 Subject: [PATCH 3/4] chore: add todos comments to point to most important files --- packages/html/src/plugins/lazyload.ts | 5 ++++- packages/html/src/plugins/placeholder.ts | 2 ++ packages/html/src/utils/render.ts | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/html/src/plugins/lazyload.ts b/packages/html/src/plugins/lazyload.ts index c3a5d1c8..71fbd50f 100644 --- a/packages/html/src/plugins/lazyload.ts +++ b/packages/html/src/plugins/lazyload.ts @@ -29,7 +29,10 @@ export function lazyload({rootMargin='0px', threshold=0.1}:{rootMargin?: string, * @param cloudinaryImage {CloudinaryImage} * @param htmlPluginState {HtmlPluginState} Holds cleanup callbacks and event subscriptions. */ -function lazyloadPlugin(rootMargin='0px', threshold=0.1 , element: HTMLImageElement | HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState): Promise | boolean { +// TODO: We will add new argument to the function with `plugins` so it can know to to run other plugins instead of running default behavior +// This should only be done in case we find in lazyload that responsive plugin is used +// We also might consider delaying the placeholder and run it here instead immediately when plugin is invoked in render +function lazyloadPlugin(rootMargin='0px', threshold=0.1 , element: HTMLImageElement | HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState, plugins): Promise | boolean { // if SSR skip plugin if(!isBrowser()) return false; diff --git a/packages/html/src/plugins/placeholder.ts b/packages/html/src/plugins/placeholder.ts index 3754e11c..0c48790d 100644 --- a/packages/html/src/plugins/placeholder.ts +++ b/packages/html/src/plugins/placeholder.ts @@ -28,6 +28,8 @@ export function placeholder({mode='vectorize'}:{mode?: string}={}): Plugin{ * @param htmlPluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions. * @param baseAnalyticsOptions {BaseAnalyticsOptions} analytics options for the url to be created */ +// TODO: Optionally we might want to hold of with rendering +// Maybe there is something in the responsive plugin already that should be moved here too? function placeholderPlugin(mode: PlaceholderMode, element: HTMLImageElement, pluginCloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState, baseAnalyticsOptions?: BaseAnalyticsOptions): Promise | boolean { // @ts-ignore // If we're using an invalid mode, we default to vectorize diff --git a/packages/html/src/utils/render.ts b/packages/html/src/utils/render.ts index fc8825d5..68beaf35 100644 --- a/packages/html/src/utils/render.ts +++ b/packages/html/src/utils/render.ts @@ -1,3 +1,4 @@ +import { lazyload } from 'plugins/lazyload'; import {Plugins, HtmlPluginState, BaseAnalyticsOptions, PluginResponse} from '../types' import {CloudinaryVideo, CloudinaryImage} from "@cloudinary/url-gen"; @@ -14,10 +15,24 @@ export async function render(element: HTMLImageElement | HTMLVideoElement, plugi if (plugins === undefined) return; let response: PluginResponse; for (let i = 0; i < plugins.length; i++) { - response = await plugins[i](element, pluginCloudinaryAsset, pluginState, analyticsOptions); + // TODO: We have to pass all plugins to each plugin (so that each can determine what to do) + // 1. Pass plugins as a fifth parameter below (after analyticsOptions) + // + // 2. Inside each plugin we can use `name` property of the plugin functions to see what was added + // + // Example given the plugins look like below: + // const plugins = [lazyload(), responsive()] + // Then if you console log plugins[0].name you should get 'bound lazyloadPlugin' + // plugins[0].name === 'bound lazyloadPlugin' + const pluginResponse = await plugins[i](element, pluginCloudinaryAsset, pluginState, analyticsOptions); if (response === 'canceled') { break; } + if(typeof pluginResponse === 'object') { + response = {...response, ...pluginResponse}; + } else { + response = pluginResponse + } } if (response !== 'canceled') { return response; From 6ce8aafec3244723fa06ef9f7a2da9556609ff8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Philipczyk?= Date: Wed, 20 Sep 2023 18:33:56 +0200 Subject: [PATCH 4/4] chore: improve todos comments --- packages/html/src/plugins/lazyload.ts | 5 +---- packages/html/src/plugins/responsive.ts | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/html/src/plugins/lazyload.ts b/packages/html/src/plugins/lazyload.ts index 71fbd50f..c3a5d1c8 100644 --- a/packages/html/src/plugins/lazyload.ts +++ b/packages/html/src/plugins/lazyload.ts @@ -29,10 +29,7 @@ export function lazyload({rootMargin='0px', threshold=0.1}:{rootMargin?: string, * @param cloudinaryImage {CloudinaryImage} * @param htmlPluginState {HtmlPluginState} Holds cleanup callbacks and event subscriptions. */ -// TODO: We will add new argument to the function with `plugins` so it can know to to run other plugins instead of running default behavior -// This should only be done in case we find in lazyload that responsive plugin is used -// We also might consider delaying the placeholder and run it here instead immediately when plugin is invoked in render -function lazyloadPlugin(rootMargin='0px', threshold=0.1 , element: HTMLImageElement | HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState, plugins): Promise | boolean { +function lazyloadPlugin(rootMargin='0px', threshold=0.1 , element: HTMLImageElement | HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState): Promise | boolean { // if SSR skip plugin if(!isBrowser()) return false; diff --git a/packages/html/src/plugins/responsive.ts b/packages/html/src/plugins/responsive.ts index 24092aca..038c2b64 100644 --- a/packages/html/src/plugins/responsive.ts +++ b/packages/html/src/plugins/responsive.ts @@ -46,7 +46,14 @@ function responsivePlugin(steps?: number | number[], element?:HTMLImageElement, // Use a tagged generic action that can be later searched and replaced. responsiveImage.addAction(new Action().setActionTag('responsive')); // Immediately run the resize plugin, ensuring that first render gets a responsive image. - onResize(steps, element, responsiveImage, analyticsOptions); + // If we disable initial run entirely the placeholder will load non-resposive image + const shouldRunImmediately = true // TODO: logic to test if there is a placeholder plugin + if(shouldRunImmediately) { + onResize(steps, element, responsiveImage, analyticsOptions); + } else { + // Probably this has to run on else, see comments in line 83 + // updateByContainerWidth(steps, element, responsiveImage); + } let resizeRef: any; htmlPluginState.pluginEventSubscription.push(()=>{ @@ -68,7 +75,18 @@ function responsivePlugin(steps?: number | number[], element?:HTMLImageElement, */ function onResize(steps?: number | number[], element?:HTMLImageElement, responsiveImage?: CloudinaryImage, analyticsOptions?: AnalyticsOptions){ updateByContainerWidth(steps, element, responsiveImage); - element.src = responsiveImage.toURL(analyticsOptions); + // TODO: 1. Responsive should not load the image if placeholder is running next + // It has to know, the placeholder is in the plugins + // A. Get plugins as a new fifth argument of the `responsivePlugin` function + // B. Loop over plugins and check if any of plugin.name is equal to "bound placeholderPlugin" + + // If we disable each onResize then placeholder will render original image (!) + // So this cannot be conditional because we want run it always on window resize later + // element.src = responsiveImage.toURL(analyticsOptions); + + // So the magic to make sure placeholder loads large image with responsive + // Is done by the updateByContainerWidth function call + // ... and we might need to make sure it's called in line 53 if shouldRunImmediately is false } /**