New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@cloudinary/html

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cloudinary/html - npm Package Compare versions

Comparing version
1.13.1
to
1.13.2
+385
dist/CHANGELOG.md
1.11.2 / 2023-03-20
==================
Html
-------
* fix: return last plugin response
1.11.1 / 2023-03-09
==================
Html
-------
* fix: fix placeholder plugin token
1.11.0 / 2023-02-21
==================
Html
-------
* test: add tests for HtmlImageLayer destroy
* fix: cleanup html layer on component unmount
React
-------
* fix: Unmount HtmlImageLayer instance on component unmount
1.10.0 / 2023-02-13
==================
Vue
-------
* feature: add reference docs for the new Vue SDK
1.9.1 / 2023-02-06
==================
Html
-------
* Add analytics features to plugins
1.9.0 / 2023-01-17
==================
Angular
-------
* feature: add cldPoster property with support for auto
React
-------
* feature: add cldPoster property with support for auto
Vue
-------
* feature: add cldPoster property with support for auto
1.8.1 / 2023-01-11
==================
Html
-------
* fix: pass analytics options down to the plugins, and use it in placeholder & responsive
1.8.0 / 2023-01-03
==================
Angular
-------
* Add playground app
React
-------
* Improve video props type
Vue
-------
* Add the advanced video component
Html
-------
* fix: guard html image layer analytics options
React
-------
* fix: change playground package name
* fix: use cloudinary favicon in playground
* fix: use responsive plugin in react playground
* fix: fix react playground by using vite
Vue
------------------
* chore: package @cloudinary/vue3 was renamed to @cloudinary/vue
* fix: fix analytic token in SSR
* fix: fix broken src attribute in SSR
1.6.0 / 2022-11-17
==================
Html
-------
* Add an optional analytics option to be passed to serverSideSrc
React
-------
* use the same analytics token in react ssr and csr
1.5.0 / 2022-09-18
==================
Vue 3
------------------
* Release first version of @cloudinary/vue3 SDK
React
------------------
* Fix react jest configuration (#173)
* Update React SDK readme (#175)
Docs:
------------------
* Update README example (#168)
1.4.2 / 2022-08-09
==================
Angular
------------------
* Fix angular package version (#150)
VUE3
------------------
* Test vue3 responsive (#160)
* Test vue3 placeholder (#159)
* Test vue3 lazyload (#158)
* Test vue3 analytics (#157)
* Test vue3 accessibility tests (#156)
* Add vue3 advanced image (#153)
* Add vue3 sdk base with a build script (#151)
1.4.1 / 2022-05-31
==================
* Fix wrong README links (#148)
1.4.0 / 2022-05-11
==================
React
-------
* Fix incorrect responsive behavior with SSR responsive (#147)
Angular
-------
* Fix incorrect responsive behavior with SSR responsive (#147)
* Add Angular 12 as peer dep (#146)
1.3.0 / 2022-04-11
==================
React
-------
* Add peer dependency for react 18 (#145)
Angular
-------
* Update README.md (#144)
* Remove production mode (#143)
1.2.2 / 2022-03-28
==================
* fix svelte build requirements (#141)
1.2.1 / 2022-03-24
==================
* bump minimist version (#142)
1.2.0 / 2022-03-13
==================
React
-------
* Responsive Plugin will now respect steps to define max width (#133)
Angular
-------
* Responsive Plugin will now respect steps to define max width (#133)
Html
-------
* Update htmlVideo to use the right format for ogg/ogv (#138)
* Adjust package.json fields (#136)
1.1.0 / 2022-02-13
==================
React
-------
* Replace micro-bundle with rollup (#131)
Angular
-------
* Fix muted attribute on angular video (#126)
* Add video reference (#127)
1.0.1 / 2022-01-05
==================
Other changes
-----------------
* Added missing comments
1.0.0 / 2022-01-04
==================
New functionality
-----------------
* Feature/add analytics (#114)
Breaking changes
-----------------
* Change plugin input to object instead of string (#119)
Other changes
-----------------
* Update url-gen version
* Update issue templates
* Update pull_request_template.md
* Add test for muted video (#122)
* Fix video src url with analytics (#121)
* Add img attributes to angular (#118
1.0.0-beta.14 / 2021-12-5
==================
* update readme for packages (#108)
* resolve broken ts imports (#109)
* rename angular package (#107)
1.0.0-beta.13 / 2021-11-30
==================
* Add Lerna (#104)
1.0.0-beta.11 / 2021-09-14
==================
* updated to html to latest version (#96)
1.0.0-beta.10 / 2021-09-14
==================
New functionality
-----------------
* added autoOptimalBreakpoints to picture tag (#86)
Other changes
-----------------
* changed to url-gen package name (#94)
1.0.0-beta.9 / 2021-07-04
==================
* Fix/common js build (#87)
* Add advanced picture (#84)
1.0.0-beta.8 / 2021-05-12
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.7 / 2021-05-12
==================
Other changes
-----------------
* Fix svelte npm package file contents
1.0.0-beta.6 / 2021-05-11
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.4 / 2021-05-09
==================
New functionality
-----------------
* align video attributes in React and Angular(#77)
* Added ondestroy lifecycle hook to video component (#78)
Other changes
-----------------
* Disable package-lock generation by adding .npmrc config
* Feature/add vue sdk infrastructure (#74)
* Add dynamic copy right date (#76)
1.0.0-beta.3 / 2021-04-12
==================
New functionality
-----------------
* React - Add innerRef prop to AdvanceVideo component (#65)
* React - Add video component (#59)
* Shared(Breaking) - Update video sources to accept Transcode action (#64)
Other changes
-----------------
* Svelte - Fix ts errors by adding importsNotUsedAsValues rule (#68)
* Angular - Add enableProdMode() (#63)
* Svelte tests - Add svelte ssr tests (#62)
* Svelte tests - Add responsive unit tests for svelte sdk (#60)
* Angular tests - add missing angular tests (#61)
* React tests - add react e2e tests (#58)
* Svelte docs - Add svelte sdk docs (#57)
* React - Update dependency of react version to be ^16.3.0 || ^17.0.0 (#49)
* Shared - fix status canceled error on placeholder (#54)
* Shared - Feature/add video layer (#52)
1.0.0-beta.1 / 2021-02-24
==================
New functionality
-----------------
* Add svelte sdk (#48)
Other changes
-----------------
* Upgrade to base beta (#51)
* Handle placeholder onerror (#46)
* Add travis.yml file (#50)
* Docs - Add version number to the docs reference (#47)
* Docs - Finalize readme before release (#45)
1.0.0-beta.0 / 2021-02-02
==================
Other changes
---------------
* Beta release
1.0.0-alpha.5 / 2021-02-02
==================
Other changes
---------------
* Add changelog
* Test full release-cycle using jenkins
1.0.0-alpha.4 / 2021-01-31
==========================
Initial Release
-------------
* Implement plugins - Responsive, Placeholder, Accessibility, Lazyload
* Implement React and Angular image components
/**
* Import and export all needed types
*/
export { HtmlImageLayer } from './layers/htmlImageLayer';
export { HtmlVideoLayer } from './layers/htmlVideoLayer';
export { responsive } from './plugins/responsive';
export { lazyload } from './plugins/lazyload';
export { accessibility } from './plugins/accessibility';
export { placeholder } from './plugins/placeholder';
export { isBrowser } from './utils/isBrowser';
export { serverSideSrc } from './utils/serverSideSrc';
export { Plugins, VideoSources, VideoPoster, PictureSources } from './types';
export { cancelCurrentlyRunningPlugins } from './utils/cancelCurrentlyRunningPlugins';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { Plugins, HtmlPluginState, BaseAnalyticsOptions } from '../types';
export declare class HtmlImageLayer {
private imgElement;
private isMounted;
htmlPluginState: HtmlPluginState;
constructor(element: HTMLImageElement | null, userCloudinaryImage: CloudinaryImage, plugins?: Plugins, baseAnalyticsOptions?: BaseAnalyticsOptions);
/**
* Called when component is updated and re-triggers render
* @param userCloudinaryImage
* @param plugins
* @param baseAnalyticsOptions
*/
update(userCloudinaryImage: CloudinaryImage, plugins: any, baseAnalyticsOptions?: BaseAnalyticsOptions): void;
unmount(): void;
}
import { Plugins, HtmlPluginState, VideoSources, VideoType, VideoPoster, VideoOptions } from '../types';
import { CloudinaryVideo } from "@cloudinary/url-gen";
export declare class HtmlVideoLayer {
videoElement: any;
originalVideo: CloudinaryVideo;
htmlPluginState: HtmlPluginState;
mimeType: string;
mimeSubTypes: {
flv: string;
'3gp': string;
mov: string;
mpg: string;
avi: string;
wmv: string;
ogv: string;
webm: string;
mp4: string;
};
videoOptions: VideoOptions;
constructor(element: HTMLVideoElement | null, userCloudinaryVideo: CloudinaryVideo, sources: VideoSources, plugins?: Plugins, videoAttributes?: object, userCloudinaryPoster?: VideoPoster, videoOptions?: VideoOptions);
/**
* Handles user supplied sources or default sources
* @param userCloudinaryVideo {CloudinaryVideo}
* @param sources
*/
handleSourceToVideo(userCloudinaryVideo: CloudinaryVideo, sources: VideoSources): void;
/**
* Generate sources based on user input
* @param userCloudinaryVideo {CloudinaryVideo}
* @param sources
*/
generateUserSources(userCloudinaryVideo: CloudinaryVideo, sources: VideoSources): void;
/**
* Appends source tag to html video element
* @param userCloudinaryVideo {CloudinaryVideo}
* @param type {string}
* @param mimeType {string}
*/
appendSourceTag(userCloudinaryVideo: CloudinaryVideo, type: string, mimeType?: string): void;
/**
* Determines MIME type of given source type and codecs.
* @param type - format of the video
* @param codecs - optional information about codecs of the video
*/
buildMimeType(type: VideoType, codecs: string[]): string;
/**
* Iterates through the video attributes and sets to true if passed in by the user.
* In case of poster, sets the poster.
* @param videoAttributes {object} Supported attributes: controls, loop, muted, poster, preload, autoplay, playsinline
*/
setVideoAttributes(videoAttributes?: object, userCloudinaryPoster?: VideoPoster): void;
/**
* Called when component is updated. If our video source has changed, a video reload is triggered.
* @param updatedCloudinaryVideo
* @param sources
* @param plugins
* @param videoAttributes
*/
update(updatedCloudinaryVideo: CloudinaryVideo, sources: VideoSources, plugins?: Plugins, videoAttributes?: object, userCloudinaryPoster?: VideoPoster): void;
}
MIT License
Copyright (c) 2020 Cloudinary
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { Plugin, AccessibilityMode, HtmlPluginState, PluginResponse } from "../types";
/**
* @namespace
* @description Appends accessibility transformations to the original image.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[accessibility()]}/>
*/
export declare function accessibility({ mode }?: {
mode?: string;
}): Plugin;
/**
* @description Accessibility plugin
* @param mode {AccessibilityMode} The accessibility mode to use. Possible modes: 'darkmode' | 'brightmode' | 'monochrome' | 'colorblind'. Default: 'darkmode'.
* @param element {HTMLImageElement} The image element.
* @param pluginCloudinaryImage {CloudinaryImage}
* @param htmlPluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions.
*/
export declare function accessibilityPlugin(mode: AccessibilityMode, element: HTMLImageElement, pluginCloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState, plugins?: Plugin[]): Promise<PluginResponse> | boolean;
import { Plugin } from '../types';
/**
* @namespace
* @description Loads an image once it is in a certain margin in the viewport. This includes vertical and horizontal scrolling.
* @param rootMargin {string} The root element's bounding box before the intersection test is performed. Default: 0px.
* @param threshold {number} The percentage of the image's visibility at which point the image should load. Default: 0.1 (10%).
* @return {Plugin}
* @example
* <caption>
* NOTE: The following is in React. For further examples, see the Packages tab.
* When using the plugin make sure to add dimensions, otherwise the images will load with
* the size of 0x0, meaning the images will be in the viewport and trigger the lazyload plugin.
* </caption>
* <AdvancedImage style={{width: "400px", height: "400px"}} cldImg={img} plugins={[lazyload({rootMargin: '0px',
* threshold: 0.25})]} />
*/
export declare function lazyload({ rootMargin, threshold }?: {
rootMargin?: string;
threshold?: number;
}): Plugin;
import { Plugin } from "../types";
/**
* @namespace
* @description Displays a placeholder image until the original image loads.
* @param mode {PlaceholderMode} The type of placeholder image to display. Possible modes: 'vectorize' | 'pixelate' | 'blur' | 'predominant-color'. Default: 'vectorize'.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[placeholder({mode: 'blur'})]} />
*/
export declare function placeholder({ mode }?: {
mode?: string;
}): Plugin;
import { Plugin } from "../types";
/**
* @namespace
* @description Updates the src with the size of the parent element and triggers a resize event for
* subsequent resizing.
* @param steps {number | number[]} The step size in pixels or an array of image widths in pixels.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[responsive({steps: [800, 1000, 1400]})]} />
*/
export declare function responsive({ steps }?: {
steps?: number | number[];
}): Plugin;
## Overview
This is Cloudinary's html library.
It acts as a layer that provides all dom manipulation logic used by Cloudinary's
frontend frameworks SDKs like [@cloudinary/react](https://www.npmjs.com/package/@cloudinary/react) and [@cloudinary/ng](https://www.npmjs.com/package/@cloudinary/ng) for rendering images and videos.
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { VideoCodecAction } from "@cloudinary/url-gen/actions/transcode/VideoCodecAction";
import { ITrackedPropertiesThroughAnalytics } from "@cloudinary/url-gen/sdkAnalytics/interfaces/ITrackedPropertiesThroughAnalytics";
export type Plugin = (element: HTMLImageElement | HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState?: HtmlPluginState, baseAnalyticsOptions?: BaseAnalyticsOptions, plugins?: Plugins) => Promise<PluginResponse>;
export type Plugins = Plugin[];
export type PluginResponse = 'canceled' | void | Features;
export type AccessibilityMode = 'darkmode' | 'brightmode' | 'monochrome' | 'colorblind';
export type PlaceholderMode = 'vectorize' | 'pixelate' | 'blur' | 'predominant-color';
export type HtmlPluginState = {
cleanupCallbacks: Function[];
pluginEventSubscription: Function[];
};
export type VideoSources = {
type: VideoType;
codecs: Array<string>;
transcode: VideoCodecAction;
}[] | undefined;
export type VideoType = 'flv' | '3gp' | 'mov' | 'mpg' | 'avi' | 'wmv' | 'ogv' | string;
export type PictureSources = {
minWidth?: number;
maxWidth?: number;
image: CloudinaryImage;
sizes?: string;
}[];
export type PictureSource = {
minWidth?: number;
maxWidth?: number;
image: CloudinaryImage;
sizes?: string;
};
export type BaseAnalyticsOptions = {
sdkSemver: string;
techVersion: string;
sdkCode: string;
};
export type AnalyticsOptions = Parameters<CloudinaryImage['toURL']>[0];
type FeatureNames = Pick<ITrackedPropertiesThroughAnalytics, 'accessibility' | 'lazyload' | 'responsive' | 'placeholder'>;
export type Features = Partial<Record<keyof FeatureNames, boolean>>;
export type VideoPoster = CloudinaryImage | 'auto';
export type VideoOptions = {
useFetchFormat?: boolean;
};
export {};
import { BaseAnalyticsOptions, AnalyticsOptions, Features } from "../types";
export declare const getAnalyticsOptions: (options?: BaseAnalyticsOptions, features?: void | Features) => AnalyticsOptions;
import { HtmlPluginState } from '../types';
/**
* Cancels currently running plugins. This is called from unmount or update
* @param pluginState {HtmlPluginState} Holds cleanup callbacks and event subscriptions
*/
export declare function cancelCurrentlyRunningPlugins(pluginState: HtmlPluginState): void;
import { Transformation } from "@cloudinary/url-gen/transformation/Transformation";
/**
* Predefined accessibility transformations
* @const {Object} Cloudinary.ACCESSIBILITY_MODES
*/
export declare const ACCESSIBILITY_MODES: {
darkmode: import("@cloudinary/transformation-builder-sdk/actions/effect/Colorize").ColorizeEffectAction;
brightmode: import("@cloudinary/transformation-builder-sdk/actions/effect/Colorize").ColorizeEffectAction;
monochrome: import("@cloudinary/transformation-builder-sdk/actions/effect/EffectActions/SimpleEffectAction").SimpleEffectAction;
colorblind: import("@cloudinary/transformation-builder-sdk/actions/effect/AssistColorBlind").AssistColorBlindEffectAction;
};
/**
* Predefined vectorize placeholder transformation
*/
export declare const VECTORIZE: Transformation;
/**
* Predefined pixelate placeholder transformation
*/
export declare const PIXELATE: Transformation;
/**
* Predefined blur placeholder transformation
*/
export declare const BLUR: Transformation;
/**
* Predefined predominant color placeholder transformation
*/
export declare const PREDOMINANT_COLOR_TRANSFORM: Transformation;
/**
* Predefined placeholder image options
*/
export declare const PLACEHOLDER_IMAGE_OPTIONS: {
vectorize: Transformation;
pixelate: Transformation;
blur: Transformation;
'predominant-color': Transformation;
};
/**
* transparent gif
*/
export declare const singleTransparentPixel = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
/**
* Convert common video file extensions to mime types
* Most other common video file extensions have an identical mime type so do not need conversion.
*/
export declare const VIDEO_MIME_TYPES: {
flv: string;
'3gp': string;
mov: string;
mpg: string;
avi: string;
wmv: string;
ogv: string;
webm: string;
mp4: string;
};
/**
* return true when window is defined
*/
export declare function isBrowser(): boolean;
/**
* returns true if input is an image element
* @param i
*/
export declare function isImage(i: any): i is HTMLImageElement;
/**
* Returns true if value is number
* @param value
*/
export declare function isNum(value: number | number[]): boolean;
import { Plugin } from "../types";
declare const initialPlugins: {
accessibility: boolean;
lazyload: boolean;
placeholder: boolean;
responsive: boolean;
};
export declare const isPluginUsed: (plugins: Plugin[], pluginType: keyof typeof initialPlugins) => boolean;
export {};
import { Plugins, HtmlPluginState, BaseAnalyticsOptions } from '../types';
import { CloudinaryVideo, CloudinaryImage } from "@cloudinary/url-gen";
/**
* Iterate through plugins and break in cases where the response is canceled. The
* response is canceled if component is updated or unmounted
* @param element {HTMLImageElement|HTMLVideoElement} Html Image or Video element
* @param pluginCloudinaryAsset {CloudinaryImage|CloudinaryVideo} The Cloudinary asset generated by base
* @param plugins {plugins} array of plugins passed in by the user
* @param pluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions
* @param analyticsOptions {BaseAnalyticsOptions} analytics options for the url to be created
*/
export declare function render(element: HTMLImageElement | HTMLVideoElement, pluginCloudinaryAsset: CloudinaryImage | CloudinaryVideo, plugins: Plugins, pluginState: HtmlPluginState, analyticsOptions?: BaseAnalyticsOptions): Promise<void | Partial<Record<"accessibility" | "lazyload" | "responsive" | "placeholder", boolean>>>;
/**
* Predefined screen dimension table ordered by ranking
*/
export declare const screeWidths: number[];
/**
* Calculates the SSR src based on plugins
* @param plugins The plugins array of plugins passed in by the user
* @param serverCloudinaryImage {CloudinaryImage}
* @return {string} return the src
*/
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { BaseAnalyticsOptions, Plugins } from "../types";
export declare function serverSideSrc(plugins?: Plugins, serverCloudinaryImage?: CloudinaryImage, analyticsOptions?: BaseAnalyticsOptions): string;
+14
-10
{
"name": "@cloudinary/html",
"version": "1.13.1",
"version": "1.13.2",
"description": "An HTML wrapper for Cloudinary",
"main": "./index.js",
"umd": "./index.umd.js",
"module": "./index.esm.js",
"types": "./index.d.ts",
"main": "./dist/index.js",
"umd": "./dist/index.umd.js",
"module": "./dist/index.esm.js",
"types": "./dist/index.d.ts",
"type": "module",
"files": [
"package.json",
"dist"
],
"sideEffects": false,
"repository": "https://github.com/cloudinary/frontend-frameworks",
"scripts": {
"build": "tsc && npm run prepare-build && rollup -c",
"postbuild": "cp index.esm.* ./dist && cp index.umd.* ./dist",
"prepare-build": "cp package.json ./dist",
"build": "rollup -c",
"typecheck": "tsc --noEmit --skipLibCheck",
"test": "jest --config jest.config.json",

@@ -22,3 +25,3 @@ "test-coverage": "jest --coverage"

"@babel/preset-typescript": "^7.14.5",
"@cloudinary/url-gen": "^1.16.0",
"@cloudinary/url-gen": "^1.21.0",
"@rollup/plugin-commonjs": "^19.0.0",

@@ -43,3 +46,4 @@ "@rollup/plugin-node-resolve": "^13.0.0",

"typescript": "^4.1.2"
}
},
"gitHead": "fbb7d159158090f639fea9eda981c962b9c985db"
}
1.11.2 / 2023-03-20
==================
Html
-------
* fix: return last plugin response
1.11.1 / 2023-03-09
==================
Html
-------
* fix: fix placeholder plugin token
1.11.0 / 2023-02-21
==================
Html
-------
* test: add tests for HtmlImageLayer destroy
* fix: cleanup html layer on component unmount
React
-------
* fix: Unmount HtmlImageLayer instance on component unmount
1.10.0 / 2023-02-13
==================
Vue
-------
* feature: add reference docs for the new Vue SDK
1.9.1 / 2023-02-06
==================
Html
-------
* Add analytics features to plugins
1.9.0 / 2023-01-17
==================
Angular
-------
* feature: add cldPoster property with support for auto
React
-------
* feature: add cldPoster property with support for auto
Vue
-------
* feature: add cldPoster property with support for auto
1.8.1 / 2023-01-11
==================
Html
-------
* fix: pass analytics options down to the plugins, and use it in placeholder & responsive
1.8.0 / 2023-01-03
==================
Angular
-------
* Add playground app
React
-------
* Improve video props type
Vue
-------
* Add the advanced video component
Html
-------
* fix: guard html image layer analytics options
React
-------
* fix: change playground package name
* fix: use cloudinary favicon in playground
* fix: use responsive plugin in react playground
* fix: fix react playground by using vite
Vue
------------------
* chore: package @cloudinary/vue3 was renamed to @cloudinary/vue
* fix: fix analytic token in SSR
* fix: fix broken src attribute in SSR
1.6.0 / 2022-11-17
==================
Html
-------
* Add an optional analytics option to be passed to serverSideSrc
React
-------
* use the same analytics token in react ssr and csr
1.5.0 / 2022-09-18
==================
Vue 3
------------------
* Release first version of @cloudinary/vue3 SDK
React
------------------
* Fix react jest configuration (#173)
* Update React SDK readme (#175)
Docs:
------------------
* Update README example (#168)
1.4.2 / 2022-08-09
==================
Angular
------------------
* Fix angular package version (#150)
VUE3
------------------
* Test vue3 responsive (#160)
* Test vue3 placeholder (#159)
* Test vue3 lazyload (#158)
* Test vue3 analytics (#157)
* Test vue3 accessibility tests (#156)
* Add vue3 advanced image (#153)
* Add vue3 sdk base with a build script (#151)
1.4.1 / 2022-05-31
==================
* Fix wrong README links (#148)
1.4.0 / 2022-05-11
==================
React
-------
* Fix incorrect responsive behavior with SSR responsive (#147)
Angular
-------
* Fix incorrect responsive behavior with SSR responsive (#147)
* Add Angular 12 as peer dep (#146)
1.3.0 / 2022-04-11
==================
React
-------
* Add peer dependency for react 18 (#145)
Angular
-------
* Update README.md (#144)
* Remove production mode (#143)
1.2.2 / 2022-03-28
==================
* fix svelte build requirements (#141)
1.2.1 / 2022-03-24
==================
* bump minimist version (#142)
1.2.0 / 2022-03-13
==================
React
-------
* Responsive Plugin will now respect steps to define max width (#133)
Angular
-------
* Responsive Plugin will now respect steps to define max width (#133)
Html
-------
* Update htmlVideo to use the right format for ogg/ogv (#138)
* Adjust package.json fields (#136)
1.1.0 / 2022-02-13
==================
React
-------
* Replace micro-bundle with rollup (#131)
Angular
-------
* Fix muted attribute on angular video (#126)
* Add video reference (#127)
1.0.1 / 2022-01-05
==================
Other changes
-----------------
* Added missing comments
1.0.0 / 2022-01-04
==================
New functionality
-----------------
* Feature/add analytics (#114)
Breaking changes
-----------------
* Change plugin input to object instead of string (#119)
Other changes
-----------------
* Update url-gen version
* Update issue templates
* Update pull_request_template.md
* Add test for muted video (#122)
* Fix video src url with analytics (#121)
* Add img attributes to angular (#118
1.0.0-beta.14 / 2021-12-5
==================
* update readme for packages (#108)
* resolve broken ts imports (#109)
* rename angular package (#107)
1.0.0-beta.13 / 2021-11-30
==================
* Add Lerna (#104)
1.0.0-beta.11 / 2021-09-14
==================
* updated to html to latest version (#96)
1.0.0-beta.10 / 2021-09-14
==================
New functionality
-----------------
* added autoOptimalBreakpoints to picture tag (#86)
Other changes
-----------------
* changed to url-gen package name (#94)
1.0.0-beta.9 / 2021-07-04
==================
* Fix/common js build (#87)
* Add advanced picture (#84)
1.0.0-beta.8 / 2021-05-12
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.7 / 2021-05-12
==================
Other changes
-----------------
* Fix svelte npm package file contents
1.0.0-beta.6 / 2021-05-11
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.4 / 2021-05-09
==================
New functionality
-----------------
* align video attributes in React and Angular(#77)
* Added ondestroy lifecycle hook to video component (#78)
Other changes
-----------------
* Disable package-lock generation by adding .npmrc config
* Feature/add vue sdk infrastructure (#74)
* Add dynamic copy right date (#76)
1.0.0-beta.3 / 2021-04-12
==================
New functionality
-----------------
* React - Add innerRef prop to AdvanceVideo component (#65)
* React - Add video component (#59)
* Shared(Breaking) - Update video sources to accept Transcode action (#64)
Other changes
-----------------
* Svelte - Fix ts errors by adding importsNotUsedAsValues rule (#68)
* Angular - Add enableProdMode() (#63)
* Svelte tests - Add svelte ssr tests (#62)
* Svelte tests - Add responsive unit tests for svelte sdk (#60)
* Angular tests - add missing angular tests (#61)
* React tests - add react e2e tests (#58)
* Svelte docs - Add svelte sdk docs (#57)
* React - Update dependency of react version to be ^16.3.0 || ^17.0.0 (#49)
* Shared - fix status canceled error on placeholder (#54)
* Shared - Feature/add video layer (#52)
1.0.0-beta.1 / 2021-02-24
==================
New functionality
-----------------
* Add svelte sdk (#48)
Other changes
-----------------
* Upgrade to base beta (#51)
* Handle placeholder onerror (#46)
* Add travis.yml file (#50)
* Docs - Add version number to the docs reference (#47)
* Docs - Finalize readme before release (#45)
1.0.0-beta.0 / 2021-02-02
==================
Other changes
---------------
* Beta release
1.0.0-alpha.5 / 2021-02-02
==================
Other changes
---------------
* Add changelog
* Test full release-cycle using jenkins
1.0.0-alpha.4 / 2021-01-31
==========================
Initial Release
-------------
* Implement plugins - Responsive, Placeholder, Accessibility, Lazyload
* Implement React and Angular image components
/**
* Import and export all needed types
*/
export { HtmlImageLayer } from './layers/htmlImageLayer';
export { HtmlVideoLayer } from './layers/htmlVideoLayer';
export { responsive } from './plugins/responsive';
export { lazyload } from './plugins/lazyload';
export { accessibility } from './plugins/accessibility';
export { placeholder } from './plugins/placeholder';
export { isBrowser } from './utils/isBrowser';
export { serverSideSrc } from './utils/serverSideSrc';
export { Plugins, VideoSources, VideoPoster, PictureSources } from './types';
export { cancelCurrentlyRunningPlugins } from './utils/cancelCurrentlyRunningPlugins';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

/**
* Import and export all needed types
*/
export { HtmlImageLayer } from './layers/htmlImageLayer';
export { HtmlVideoLayer } from './layers/htmlVideoLayer';
export { responsive } from './plugins/responsive';
export { lazyload } from './plugins/lazyload';
export { accessibility } from './plugins/accessibility';
export { placeholder } from './plugins/placeholder';
export { isBrowser } from './utils/isBrowser';
export { serverSideSrc } from './utils/serverSideSrc';
export { cancelCurrentlyRunningPlugins } from './utils/cancelCurrentlyRunningPlugins';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { Plugins, HtmlPluginState, BaseAnalyticsOptions } from '../types';
export declare class HtmlImageLayer {
private imgElement;
private isMounted;
htmlPluginState: HtmlPluginState;
constructor(element: HTMLImageElement | null, userCloudinaryImage: CloudinaryImage, plugins?: Plugins, baseAnalyticsOptions?: BaseAnalyticsOptions);
/**
* Called when component is updated and re-triggers render
* @param userCloudinaryImage
* @param plugins
* @param baseAnalyticsOptions
*/
update(userCloudinaryImage: CloudinaryImage, plugins: any, baseAnalyticsOptions?: BaseAnalyticsOptions): void;
unmount(): void;
}
import cloneDeep from 'lodash.clonedeep';
import { render } from '../utils/render';
import { getAnalyticsOptions } from "../utils/analytics";
var HtmlImageLayer = /** @class */ (function () {
function HtmlImageLayer(element, userCloudinaryImage, plugins, baseAnalyticsOptions) {
var _this = this;
this.isMounted = true;
this.imgElement = element;
this.htmlPluginState = { cleanupCallbacks: [], pluginEventSubscription: [] };
var pluginCloudinaryImage = cloneDeep(userCloudinaryImage);
render(element, pluginCloudinaryImage, plugins, this.htmlPluginState, baseAnalyticsOptions)
.then(function (pluginResponse) {
if (!_this.isMounted) {
return;
}
_this.htmlPluginState.pluginEventSubscription.forEach(function (fn) { fn(); });
var analyticsOptions = getAnalyticsOptions(baseAnalyticsOptions, pluginResponse);
_this.imgElement.setAttribute('src', pluginCloudinaryImage.toURL(analyticsOptions));
});
}
/**
* Called when component is updated and re-triggers render
* @param userCloudinaryImage
* @param plugins
* @param baseAnalyticsOptions
*/
HtmlImageLayer.prototype.update = function (userCloudinaryImage, plugins, baseAnalyticsOptions) {
var _this = this;
var pluginCloudinaryImage = cloneDeep(userCloudinaryImage);
render(this.imgElement, pluginCloudinaryImage, plugins, this.htmlPluginState)
.then(function (pluginResponse) {
if (!_this.isMounted) {
return;
}
var featuredAnalyticsOptions = getAnalyticsOptions(baseAnalyticsOptions, pluginResponse);
_this.imgElement.setAttribute('src', pluginCloudinaryImage.toURL(featuredAnalyticsOptions));
});
};
HtmlImageLayer.prototype.unmount = function () {
this.isMounted = false;
};
return HtmlImageLayer;
}());
export { HtmlImageLayer };
import { Plugins, HtmlPluginState, VideoSources, VideoType, VideoPoster, VideoOptions } from '../types';
import { CloudinaryVideo } from "@cloudinary/url-gen";
export declare class HtmlVideoLayer {
videoElement: any;
originalVideo: CloudinaryVideo;
htmlPluginState: HtmlPluginState;
mimeType: string;
mimeSubTypes: {
flv: string;
'3gp': string;
mov: string;
mpg: string;
avi: string;
wmv: string;
ogv: string;
webm: string;
mp4: string;
};
videoOptions: VideoOptions;
constructor(element: HTMLVideoElement | null, userCloudinaryVideo: CloudinaryVideo, sources: VideoSources, plugins?: Plugins, videoAttributes?: object, userCloudinaryPoster?: VideoPoster, videoOptions?: VideoOptions);
/**
* Handles user supplied sources or default sources
* @param userCloudinaryVideo {CloudinaryVideo}
* @param sources
*/
handleSourceToVideo(userCloudinaryVideo: CloudinaryVideo, sources: VideoSources): void;
/**
* Generate sources based on user input
* @param userCloudinaryVideo {CloudinaryVideo}
* @param sources
*/
generateUserSources(userCloudinaryVideo: CloudinaryVideo, sources: VideoSources): void;
/**
* Appends source tag to html video element
* @param userCloudinaryVideo {CloudinaryVideo}
* @param type {string}
* @param mimeType {string}
*/
appendSourceTag(userCloudinaryVideo: CloudinaryVideo, type: string, mimeType?: string): void;
/**
* Determines MIME type of given source type and codecs.
* @param type - format of the video
* @param codecs - optional information about codecs of the video
*/
buildMimeType(type: VideoType, codecs: string[]): string;
/**
* Iterates through the video attributes and sets to true if passed in by the user.
* In case of poster, sets the poster.
* @param videoAttributes {object} Supported attributes: controls, loop, muted, poster, preload, autoplay, playsinline
*/
setVideoAttributes(videoAttributes?: object, userCloudinaryPoster?: VideoPoster): void;
/**
* Called when component is updated. If our video source has changed, a video reload is triggered.
* @param updatedCloudinaryVideo
* @param sources
* @param plugins
* @param videoAttributes
*/
update(updatedCloudinaryVideo: CloudinaryVideo, sources: VideoSources, plugins?: Plugins, videoAttributes?: object, userCloudinaryPoster?: VideoPoster): void;
}
import cloneDeep from 'lodash.clonedeep';
import { render } from '../utils/render';
import { VIDEO_MIME_TYPES } from "../utils/internalConstants";
var ANALYTICS_DELIMITER = '?_a=';
var HtmlVideoLayer = /** @class */ (function () {
function HtmlVideoLayer(element, userCloudinaryVideo, sources, plugins, videoAttributes, userCloudinaryPoster, videoOptions) {
var _this = this;
this.mimeType = 'video';
this.mimeSubTypes = VIDEO_MIME_TYPES;
this.videoElement = element;
this.originalVideo = userCloudinaryVideo;
this.videoOptions = videoOptions;
this.htmlPluginState = { cleanupCallbacks: [], pluginEventSubscription: [] };
var pluginCloudinaryVideo = cloneDeep(userCloudinaryVideo);
render(element, userCloudinaryVideo, plugins, this.htmlPluginState)
.then(function () {
_this.htmlPluginState.pluginEventSubscription.forEach(function (fn) { fn(); });
_this.setVideoAttributes(videoAttributes, userCloudinaryPoster);
_this.handleSourceToVideo(pluginCloudinaryVideo, sources);
});
}
/**
* Handles user supplied sources or default sources
* @param userCloudinaryVideo {CloudinaryVideo}
* @param sources
*/
HtmlVideoLayer.prototype.handleSourceToVideo = function (userCloudinaryVideo, sources) {
var _this = this;
// checks if user supplied sources
if (sources) {
this.generateUserSources(userCloudinaryVideo, sources);
}
else {
var defaultTypes = ['webm', 'mp4', 'ogv'];
defaultTypes.forEach(function (type) {
_this.appendSourceTag(cloneDeep(userCloudinaryVideo), type);
});
}
};
/**
* Generate sources based on user input
* @param userCloudinaryVideo {CloudinaryVideo}
* @param sources
*/
HtmlVideoLayer.prototype.generateUserSources = function (userCloudinaryVideo, sources) {
var _this = this;
sources.map(function (_a) {
var type = _a.type, codecs = _a.codecs, transcode = _a.transcode;
return (_this.appendSourceTag(cloneDeep(userCloudinaryVideo)
.transcode(transcode), type, _this.buildMimeType(type, codecs)));
});
};
/**
* Appends source tag to html video element
* @param userCloudinaryVideo {CloudinaryVideo}
* @param type {string}
* @param mimeType {string}
*/
HtmlVideoLayer.prototype.appendSourceTag = function (userCloudinaryVideo, type, mimeType) {
var _a;
var source = document.createElement('source');
var shouldUseFetchFormat = (_a = this.videoOptions) === null || _a === void 0 ? void 0 : _a.useFetchFormat;
if (shouldUseFetchFormat) {
userCloudinaryVideo.format(type);
}
var url = userCloudinaryVideo.toURL();
// Split url to get analytics string so that we can insert the file extension (type) before it
// To simplify this we could add a .getPublicId to CloudinaryVideo and do vid.setPublicId(vid.getPublicId+type)
// Another option could be to add a .setExtension, which will allow to do vid.setExtension(type)
var srcParts = url.split(ANALYTICS_DELIMITER);
var analyticsStr = srcParts[1] ? "".concat(ANALYTICS_DELIMITER).concat(srcParts[1]) : '';
var ext = shouldUseFetchFormat ? '' : ".".concat(type);
source.src = "".concat(srcParts[0]).concat(ext).concat(analyticsStr);
// Ideally, we want to use the VIDEO_MIME_TYPE to detect the mime of the extension
// For future proofing of simple formats (say .foo and mimetype of video/foo), we also fallback to the actual type
source.type = mimeType ? mimeType : "video/".concat(VIDEO_MIME_TYPES[type] || type);
this.videoElement.appendChild(source);
};
/**
* Determines MIME type of given source type and codecs.
* @param type - format of the video
* @param codecs - optional information about codecs of the video
*/
HtmlVideoLayer.prototype.buildMimeType = function (type, codecs) {
var mimeType = "".concat(this.mimeType, "/").concat(this.mimeSubTypes[type] || type);
if (codecs) {
mimeType += "; codecs=" + (Array.isArray(codecs) ? codecs.join(', ') : codecs);
}
return mimeType;
};
;
/**
* Iterates through the video attributes and sets to true if passed in by the user.
* In case of poster, sets the poster.
* @param videoAttributes {object} Supported attributes: controls, loop, muted, poster, preload, autoplay, playsinline
*/
HtmlVideoLayer.prototype.setVideoAttributes = function (videoAttributes, userCloudinaryPoster) {
var _a;
if (videoAttributes === void 0) { videoAttributes = {}; }
if (userCloudinaryPoster === 'auto') {
var posterCloudinaryVideo = cloneDeep(this.originalVideo);
videoAttributes['poster'] = posterCloudinaryVideo
.quality('auto')
.format('jpg')
.addTransformation('so_auto')
.toURL();
}
else if (userCloudinaryPoster) {
videoAttributes['poster'] = (_a = userCloudinaryPoster.toURL) === null || _a === void 0 ? void 0 : _a.call(userCloudinaryPoster);
}
for (var _i = 0, _b = Object.entries(videoAttributes); _i < _b.length; _i++) {
var _c = _b[_i], key = _c[0], value = _c[1];
// Boolean attributes are considered to be true if they're present on the element at all.
// You should set value to the empty string ("") or the attribute's name.
// See https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute
value && this.videoElement.setAttribute(key, key === 'poster' ? value : '');
}
};
/**
* Called when component is updated. If our video source has changed, a video reload is triggered.
* @param updatedCloudinaryVideo
* @param sources
* @param plugins
* @param videoAttributes
*/
HtmlVideoLayer.prototype.update = function (updatedCloudinaryVideo, sources, plugins, videoAttributes, userCloudinaryPoster) {
var _this = this;
if (updatedCloudinaryVideo !== this.originalVideo) {
var sourcesToDelete = this.videoElement.getElementsByTagName("SOURCE");
while (sourcesToDelete[0])
sourcesToDelete[0].parentNode.removeChild(sourcesToDelete[0]);
render(this.videoElement, updatedCloudinaryVideo, plugins, this.htmlPluginState)
.then(function () {
_this.setVideoAttributes(videoAttributes, userCloudinaryPoster);
_this.handleSourceToVideo(updatedCloudinaryVideo, sources);
_this.videoElement.load();
});
}
};
return HtmlVideoLayer;
}());
export { HtmlVideoLayer };
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { Plugin, AccessibilityMode, HtmlPluginState, PluginResponse } from "../types";
/**
* @namespace
* @description Appends accessibility transformations to the original image.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[accessibility()]}/>
*/
export declare function accessibility({ mode }?: {
mode?: string;
}): Plugin;
/**
* @description Accessibility plugin
* @param mode {AccessibilityMode} The accessibility mode to use. Possible modes: 'darkmode' | 'brightmode' | 'monochrome' | 'colorblind'. Default: 'darkmode'.
* @param element {HTMLImageElement} The image element.
* @param pluginCloudinaryImage {CloudinaryImage}
* @param htmlPluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions.
*/
export declare function accessibilityPlugin(mode: AccessibilityMode, element: HTMLImageElement, pluginCloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState, plugins?: Plugin[]): Promise<PluginResponse> | boolean;
import { ACCESSIBILITY_MODES } from '../utils/internalConstants';
import { isBrowser } from "../utils/isBrowser";
import { isImage } from "../utils/isImage";
/**
* @namespace
* @description Appends accessibility transformations to the original image.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[accessibility()]}/>
*/
export function accessibility(_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.mode, mode = _c === void 0 ? 'darkmode' : _c;
return accessibilityPlugin.bind(null, mode);
}
/**
* @description Accessibility plugin
* @param mode {AccessibilityMode} The accessibility mode to use. Possible modes: 'darkmode' | 'brightmode' | 'monochrome' | 'colorblind'. Default: 'darkmode'.
* @param element {HTMLImageElement} The image element.
* @param pluginCloudinaryImage {CloudinaryImage}
* @param htmlPluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions.
*/
export function accessibilityPlugin(mode, element, pluginCloudinaryImage, htmlPluginState, plugins) {
if (isBrowser()) {
if (!isImage(element))
return;
return new Promise(function (resolve) {
// resolved promise when canceled
htmlPluginState.cleanupCallbacks.push(function () {
resolve('canceled');
});
if (!ACCESSIBILITY_MODES[mode]) {
mode = 'darkmode';
}
pluginCloudinaryImage.effect(ACCESSIBILITY_MODES[mode]);
resolve({ accessibility: true });
});
}
else {
pluginCloudinaryImage.effect(ACCESSIBILITY_MODES[mode]);
return true;
}
}
import { Plugin } from '../types';
/**
* @namespace
* @description Loads an image once it is in a certain margin in the viewport. This includes vertical and horizontal scrolling.
* @param rootMargin {string} The root element's bounding box before the intersection test is performed. Default: 0px.
* @param threshold {number} The percentage of the image's visibility at which point the image should load. Default: 0.1 (10%).
* @return {Plugin}
* @example
* <caption>
* NOTE: The following is in React. For further examples, see the Packages tab.
* When using the plugin make sure to add dimensions, otherwise the images will load with
* the size of 0x0, meaning the images will be in the viewport and trigger the lazyload plugin.
* </caption>
* <AdvancedImage style={{width: "400px", height: "400px"}} cldImg={img} plugins={[lazyload({rootMargin: '0px',
* threshold: 0.25})]} />
*/
export declare function lazyload({ rootMargin, threshold }?: {
rootMargin?: string;
threshold?: number;
}): Plugin;
import { isBrowser } from "../utils/isBrowser";
/**
* @namespace
* @description Loads an image once it is in a certain margin in the viewport. This includes vertical and horizontal scrolling.
* @param rootMargin {string} The root element's bounding box before the intersection test is performed. Default: 0px.
* @param threshold {number} The percentage of the image's visibility at which point the image should load. Default: 0.1 (10%).
* @return {Plugin}
* @example
* <caption>
* NOTE: The following is in React. For further examples, see the Packages tab.
* When using the plugin make sure to add dimensions, otherwise the images will load with
* the size of 0x0, meaning the images will be in the viewport and trigger the lazyload plugin.
* </caption>
* <AdvancedImage style={{width: "400px", height: "400px"}} cldImg={img} plugins={[lazyload({rootMargin: '0px',
* threshold: 0.25})]} />
*/
export function lazyload(_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.rootMargin, rootMargin = _c === void 0 ? '0px' : _c, _d = _b.threshold, threshold = _d === void 0 ? 0.1 : _d;
return lazyloadPlugin.bind(null, rootMargin, threshold);
}
/**
* @description lazyload plugin
* @param rootMargin {string} The root element's bounding box before the intersection test is performed. Default: 0px.
* @param threshold {number} The percentage of the image's visibility at which point the image should load. Default: 0.1 (10%).
* @param element The image element.
* @param element {HTMLImageElement} The image element.
* @param cloudinaryImage {CloudinaryImage}
* @param htmlPluginState {HtmlPluginState} Holds cleanup callbacks and event subscriptions.
*/
function lazyloadPlugin(rootMargin, threshold, element, cloudinaryImage, htmlPluginState, plugins) {
if (rootMargin === void 0) { rootMargin = '0px'; }
if (threshold === void 0) { threshold = 0.1; }
// if SSR skip plugin
if (!isBrowser())
return false;
return new Promise(function (resolve) {
var onIntersect = function () { return (resolve({ lazyload: true })); };
var unobserve = detectIntersection(element, onIntersect, rootMargin, threshold);
htmlPluginState.cleanupCallbacks.push(function () {
unobserve();
resolve('canceled');
});
});
}
/**
* Check if IntersectionObserver is supported
* @return {boolean} true if window.IntersectionObserver is defined
*/
function isIntersectionObserverSupported() {
// Check that 'IntersectionObserver' property is defined on window
return window && 'IntersectionObserver' in window;
}
/**
* Calls onIntersect() to resolve when intersection is detected, or when
* no native lazy loading or when IntersectionObserver isn't supported.
* @param {Element} el - the element to observe
* @param {function} onIntersect - called when the given element is in view
* @param rootMargin {string} The root element's bounding box before the intersection test is performed. Default: 0px.
* @param threshold {number} The percentage of the image's visibility at which point the image should load. Default: 0.1 (10%).
*/
function detectIntersection(el, onIntersect, rootMargin, threshold) {
try {
if (!isIntersectionObserverSupported()) {
// Return if there's no need or possibility to detect intersection
onIntersect();
return function () { };
}
// Detect intersection with given element using IntersectionObserver
var observer_1 = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
observer_1.unobserve(entry.target);
onIntersect();
}
});
}, { rootMargin: rootMargin, threshold: threshold });
observer_1.observe(el);
return function () { el && observer_1.observe(el); };
}
catch (e) {
onIntersect();
}
}
import { Plugin } from "../types";
/**
* @namespace
* @description Displays a placeholder image until the original image loads.
* @param mode {PlaceholderMode} The type of placeholder image to display. Possible modes: 'vectorize' | 'pixelate' | 'blur' | 'predominant-color'. Default: 'vectorize'.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[placeholder({mode: 'blur'})]} />
*/
export declare function placeholder({ mode }?: {
mode?: string;
}): Plugin;
import cloneDeep from 'lodash.clonedeep';
import { PLACEHOLDER_IMAGE_OPTIONS, singleTransparentPixel } from '../utils/internalConstants';
import { isBrowser } from "../utils/isBrowser";
import { Action } from "@cloudinary/url-gen/internal/Action";
import { isImage } from "../utils/isImage";
import { getAnalyticsOptions } from "../utils/analytics";
/**
* @namespace
* @description Displays a placeholder image until the original image loads.
* @param mode {PlaceholderMode} The type of placeholder image to display. Possible modes: 'vectorize' | 'pixelate' | 'blur' | 'predominant-color'. Default: 'vectorize'.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[placeholder({mode: 'blur'})]} />
*/
export function placeholder(_a) {
var _b = _a === void 0 ? {} : _a, _c = _b.mode, mode = _c === void 0 ? 'vectorize' : _c;
return placeholderPlugin.bind(null, mode);
}
/**
* @description Placeholder plugin
* @param mode {PlaceholderMode} The type of placeholder image to display. Possible modes: 'vectorize' | 'pixelate' | 'blur' | 'predominant-color'. Default: 'vectorize'.
* @param element {HTMLImageElement} The image element.
* @param pluginCloudinaryImage {CloudinaryImage}
* @param htmlPluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions.
* @param baseAnalyticsOptions {BaseAnalyticsOptions} analytics options for the url to be created
*/
function placeholderPlugin(mode, element, pluginCloudinaryImage, htmlPluginState, baseAnalyticsOptions, plugins) {
// @ts-ignore
// If we're using an invalid mode, we default to vectorize
if (!PLACEHOLDER_IMAGE_OPTIONS[mode]) {
mode = 'vectorize';
}
// A placeholder mode maps to an array of transformations
var PLACEHOLDER_ACTIONS = PLACEHOLDER_IMAGE_OPTIONS[mode].actions;
// Before proceeding, clone the original image
// We clone because we don't want to pollute the state of the image
// Future renders (after the placeholder is loaded) should not load placeholder transformations
var placeholderClonedImage = cloneDeep(pluginCloudinaryImage);
//appends a placeholder transformation on the clone
// @ts-ignore
PLACEHOLDER_ACTIONS.forEach(function (transformation) {
placeholderClonedImage.addAction(transformation);
});
if (!isBrowser()) {
// in SSR, we copy the transformations of the clone to the user provided CloudinaryImage
// We return here, since we don't have HTML elements to work with.
pluginCloudinaryImage.transformation = placeholderClonedImage.transformation;
return true;
}
// Client side rendering, if an image was not provided we don't perform any action
if (!isImage(element))
return;
// For the cloned placeholder image, we remove the responsive action.
// There's no need to load e_pixelate,w_{responsive} beacuse that image is temporary as-is
// and it just causes another image to load.
// This also means that the de-facto way to use responsive in SSR is WITH placeholder.
// This also means that the user must provide dimensions for the responsive plugin on the img tag.
placeholderClonedImage.transformation.actions.forEach(function (action, index) {
if (action instanceof Action && action.getActionTag() === 'responsive') {
delete placeholderClonedImage.transformation.actions[index];
}
});
var analyticsOptions = getAnalyticsOptions(baseAnalyticsOptions, { placeholder: true });
// Set the SRC of the imageElement to the URL of the placeholder Image
element.src = placeholderClonedImage.toURL(analyticsOptions);
//Fallback, if placeholder errors, load a single transparent pixel
element.onerror = function () {
element.src = singleTransparentPixel;
};
/*
* This plugin loads two images:
* - The first image is loaded as a placeholder
* - The second image is loaded after the placeholder is loaded
*
* Placeholder image loads first. Once it loads, the promise is resolved and the
* larger image will load. Once the larger image loads, promised and plugin is resolved.
*/
return new Promise(function (resolve) {
element.onload = function () {
resolve();
};
}).then(function () {
return new Promise(function (resolve) {
htmlPluginState.cleanupCallbacks.push(function () {
element.src = singleTransparentPixel;
resolve('canceled');
});
// load image once placeholder is done loading
var largeImage = new Image();
largeImage.src = pluginCloudinaryImage.toURL(analyticsOptions);
largeImage.onload = function () {
resolve({ placeholder: true });
};
// image does not load, resolve
largeImage.onerror = function () {
resolve({ placeholder: true });
};
});
});
}
import { Plugin } from "../types";
/**
* @namespace
* @description Updates the src with the size of the parent element and triggers a resize event for
* subsequent resizing.
* @param steps {number | number[]} The step size in pixels or an array of image widths in pixels.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[responsive({steps: [800, 1000, 1400]})]} />
*/
export declare function responsive({ steps }?: {
steps?: number | number[];
}): Plugin;
import { scale } from "@cloudinary/url-gen/actions/resize";
import debounce from 'lodash.debounce';
import { isNum } from '../utils/isNum';
import { isBrowser } from "../utils/isBrowser";
import { Action } from "@cloudinary/url-gen/internal/Action";
import { isImage } from "../utils/isImage";
import { getAnalyticsOptions } from '../utils/analytics';
import { isPluginUsed } from "../utils/isPluginUsed";
/**
* @namespace
* @description Updates the src with the size of the parent element and triggers a resize event for
* subsequent resizing.
* @param steps {number | number[]} The step size in pixels or an array of image widths in pixels.
* @return {Plugin}
* @example <caption>NOTE: The following is in React. For further examples, see the Packages tab.</caption>
* <AdvancedImage cldImg={img} plugins={[responsive({steps: [800, 1000, 1400]})]} />
*/
export function responsive(_a) {
var _b = _a === void 0 ? {} : _a, steps = _b.steps;
return responsivePlugin.bind(null, steps);
}
/**
* @description Responsive plugin
* @param steps {number | number[]} The step size in pixels.
* @param element {HTMLImageElement} The image element
* @param responsiveImage {CloudinaryImage}
* @param htmlPluginState {HtmlPluginState} holds cleanup callbacks and event subscriptions
* @param analyticsOptions {BaseAnalyticsOptions} analytics options for the url to be created
*/
function responsivePlugin(steps, element, responsiveImage, htmlPluginState, baseAnalyticsOptions, plugins) {
if (!isBrowser())
return true;
if (!isImage(element))
return;
return new Promise(function (resolve) {
htmlPluginState.cleanupCallbacks.push(function () {
window.removeEventListener("resize", resizeRef);
resolve('canceled');
});
var analyticsOptions = getAnalyticsOptions(baseAnalyticsOptions, { responsive: true });
// Use a tagged generic action that can be later searched and replaced.
responsiveImage.addAction(new Action().setActionTag('responsive'));
var shouldRunImmediately = !isPluginUsed(plugins, 'placeholder');
if (shouldRunImmediately) {
// Immediately run the resize plugin, ensuring that first render gets a responsive image.
onResize(steps, element, responsiveImage, analyticsOptions);
}
else {
updateByContainerWidth(steps, element, responsiveImage);
}
var resizeRef;
htmlPluginState.pluginEventSubscription.push(function () {
window.addEventListener('resize', resizeRef = debounce(function () {
onResize(steps, element, responsiveImage, analyticsOptions);
}, 100));
});
resolve({ responsive: true });
});
}
/**
* On resize updates image src
* @param steps {number | number[]} The step size in pixels.
* | number[] A set of image sizes in pixels.
* @param element {HTMLImageElement} The image element
* @param responsiveImage {CloudinaryImage}
* @param analyticsOptions {AnalyticsOptions} analytics options for the url to be created
*/
function onResize(steps, element, responsiveImage, analyticsOptions) {
updateByContainerWidth(steps, element, responsiveImage);
element.src = responsiveImage.toURL(analyticsOptions);
}
/**
* Updates the responsiveImage by container width.
* @param steps {number | number[]} The step size in pixels.
* | number[] A set of image sizes in pixels.
* @param element {HTMLImageElement} The image element
* @param responsiveImage {CloudinaryImage}
*/
function updateByContainerWidth(steps, element, responsiveImage) {
// Default value for responsiveImgWidth, used when no steps are passed.
var responsiveImgWidth = element.parentElement.clientWidth;
if (isNum(steps)) {
var WIDTH_INTERVALS = steps;
// We need to force the container width to be intervals of max width.
responsiveImgWidth = Math.ceil(responsiveImgWidth / WIDTH_INTERVALS) * WIDTH_INTERVALS;
}
else if (Array.isArray(steps)) {
responsiveImgWidth = steps.reduce(function (prev, curr) {
return (Math.abs(curr - responsiveImgWidth) < Math.abs(prev - responsiveImgWidth) ? curr : prev);
});
}
responsiveImage.transformation.actions.forEach(function (action, index) {
if (action instanceof Action && action.getActionTag() === 'responsive') {
responsiveImage.transformation.actions[index] = scale(responsiveImgWidth).setActionTag('responsive');
}
});
}
expect.extend({
toEqualAnalyticsToken: function (received, expected) {
if (!received) {
return {
pass: false,
message: function () { return "Expected ".concat(received, " to be a valid string"); }
};
}
var parts = received.split("?_a=");
if (parts.length === 1) {
return {
pass: false,
message: function () { return "Expected ".concat(received, " to be have an analytics token"); }
};
}
var token = parts[1];
if (token === expected) {
return {
pass: true,
message: function () { return "Expected ".concat(received, " not to be a valid ISO date string"); },
};
}
else {
return {
pass: false,
message: function () { return "Expected ".concat(token, " to equal ").concat(expected); }
};
}
},
});
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { VideoCodecAction } from "@cloudinary/url-gen/actions/transcode/VideoCodecAction";
import { ITrackedPropertiesThroughAnalytics } from "@cloudinary/url-gen/sdkAnalytics/interfaces/ITrackedPropertiesThroughAnalytics";
export type Plugin = (element: HTMLImageElement | HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState?: HtmlPluginState, baseAnalyticsOptions?: BaseAnalyticsOptions, plugins?: Plugins) => Promise<PluginResponse>;
export type Plugins = Plugin[];
export type PluginResponse = 'canceled' | void | Features;
export type AccessibilityMode = 'darkmode' | 'brightmode' | 'monochrome' | 'colorblind';
export type PlaceholderMode = 'vectorize' | 'pixelate' | 'blur' | 'predominant-color';
export type HtmlPluginState = {
cleanupCallbacks: Function[];
pluginEventSubscription: Function[];
};
export type VideoSources = {
type: VideoType;
codecs: Array<string>;
transcode: VideoCodecAction;
}[] | undefined;
export type VideoType = 'flv' | '3gp' | 'mov' | 'mpg' | 'avi' | 'wmv' | 'ogv' | string;
export type PictureSources = {
minWidth?: number;
maxWidth?: number;
image: CloudinaryImage;
sizes?: string;
}[];
export type PictureSource = {
minWidth?: number;
maxWidth?: number;
image: CloudinaryImage;
sizes?: string;
};
export type BaseAnalyticsOptions = {
sdkSemver: string;
techVersion: string;
sdkCode: string;
};
export type AnalyticsOptions = Parameters<CloudinaryImage['toURL']>[0];
type FeatureNames = Pick<ITrackedPropertiesThroughAnalytics, 'accessibility' | 'lazyload' | 'responsive' | 'placeholder'>;
export type Features = Partial<Record<keyof FeatureNames, boolean>>;
export type VideoPoster = CloudinaryImage | 'auto';
export type VideoOptions = {
useFetchFormat?: boolean;
};
export {};
export {};
import { BaseAnalyticsOptions, AnalyticsOptions, Features } from "../types";
export declare const getAnalyticsOptions: (options?: BaseAnalyticsOptions, features?: void | Features) => AnalyticsOptions;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
export var getAnalyticsOptions = function (options, features) {
if (features === void 0) { features = {}; }
return options ? {
trackedAnalytics: __assign({ sdkCode: options.sdkCode, sdkSemver: options.sdkSemver, techVersion: options.techVersion }, features)
} : null;
};
import { HtmlPluginState } from '../types';
/**
* Cancels currently running plugins. This is called from unmount or update
* @param pluginState {HtmlPluginState} Holds cleanup callbacks and event subscriptions
*/
export declare function cancelCurrentlyRunningPlugins(pluginState: HtmlPluginState): void;
/**
* Cancels currently running plugins. This is called from unmount or update
* @param pluginState {HtmlPluginState} Holds cleanup callbacks and event subscriptions
*/
export function cancelCurrentlyRunningPlugins(pluginState) {
pluginState.cleanupCallbacks.forEach(function (fn) {
fn(); // resolve each promise with 'canceled'
});
}
import { Transformation } from "@cloudinary/url-gen/transformation/Transformation";
/**
* Predefined accessibility transformations
* @const {Object} Cloudinary.ACCESSIBILITY_MODES
*/
export declare const ACCESSIBILITY_MODES: {
darkmode: import("@cloudinary/transformation-builder-sdk/actions/effect/Colorize").ColorizeEffectAction;
brightmode: import("@cloudinary/transformation-builder-sdk/actions/effect/Colorize").ColorizeEffectAction;
monochrome: import("@cloudinary/transformation-builder-sdk/actions/effect/EffectActions/SimpleEffectAction").SimpleEffectAction;
colorblind: import("@cloudinary/transformation-builder-sdk/actions/effect/AssistColorBlind").AssistColorBlindEffectAction;
};
/**
* Predefined vectorize placeholder transformation
*/
export declare const VECTORIZE: Transformation;
/**
* Predefined pixelate placeholder transformation
*/
export declare const PIXELATE: Transformation;
/**
* Predefined blur placeholder transformation
*/
export declare const BLUR: Transformation;
/**
* Predefined predominant color placeholder transformation
*/
export declare const PREDOMINANT_COLOR_TRANSFORM: Transformation;
/**
* Predefined placeholder image options
*/
export declare const PLACEHOLDER_IMAGE_OPTIONS: {
vectorize: Transformation;
pixelate: Transformation;
blur: Transformation;
'predominant-color': Transformation;
};
/**
* transparent gif
*/
export declare const singleTransparentPixel = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
/**
* Convert common video file extensions to mime types
* Most other common video file extensions have an identical mime type so do not need conversion.
*/
export declare const VIDEO_MIME_TYPES: {
flv: string;
'3gp': string;
mov: string;
mpg: string;
avi: string;
wmv: string;
ogv: string;
webm: string;
mp4: string;
};
import { colorize, grayscale, assistColorBlind, vectorize, pixelate, blur } from "@cloudinary/url-gen/actions/effect";
import { Transformation } from "@cloudinary/url-gen/transformation/Transformation";
import { pad, crop, fill } from "@cloudinary/url-gen/actions/resize";
import { Background } from "@cloudinary/url-gen/qualifiers/background";
import { compass } from "@cloudinary/url-gen/qualifiers/gravity";
import { northEast } from "@cloudinary/url-gen/qualifiers/compass";
import { format, quality } from "@cloudinary/url-gen/actions/delivery";
import { auto, svg } from "@cloudinary/url-gen/qualifiers/format";
/**
* Predefined accessibility transformations
* @const {Object} Cloudinary.ACCESSIBILITY_MODES
*/
export var ACCESSIBILITY_MODES = {
'darkmode': colorize(70).color('black'),
'brightmode': colorize(40).color('white'),
'monochrome': grayscale(),
'colorblind': assistColorBlind()
};
/**
* Predefined vectorize placeholder transformation
*/
export var VECTORIZE = new Transformation()
.effect(vectorize())
.delivery(quality('auto'))
.delivery(format(svg()));
/**
* Predefined pixelate placeholder transformation
*/
export var PIXELATE = new Transformation()
.effect(pixelate())
.delivery(quality('auto'))
.delivery(format(auto()));
/**
* Predefined blur placeholder transformation
*/
export var BLUR = new Transformation()
.effect(blur(2000))
.delivery(quality('auto'))
.delivery(format(auto()));
/**
* Predefined predominant color placeholder transformation
*/
export var PREDOMINANT_COLOR_TRANSFORM = new Transformation()
.resize(pad('iw_div_2').aspectRatio(1).background(Background.auto()))
.resize(crop(1, 1).gravity(compass(northEast())))
.resize(fill().height('ih').width('iw'))
.delivery(quality('auto'))
.delivery(format(auto()));
/**
* Predefined placeholder image options
*/
export var PLACEHOLDER_IMAGE_OPTIONS = {
'vectorize': VECTORIZE,
'pixelate': PIXELATE,
'blur': BLUR,
'predominant-color': PREDOMINANT_COLOR_TRANSFORM
};
/**
* transparent gif
*/
export var singleTransparentPixel = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
/**
* Convert common video file extensions to mime types
* Most other common video file extensions have an identical mime type so do not need conversion.
*/
export var VIDEO_MIME_TYPES = {
'flv': 'x-flv',
'3gp': '3gpp',
'mov': 'quicktime',
'mpg': 'mpeg',
'avi': 'x-msvideo',
'wmv': 'x-ms-wmv',
'ogv': 'ogg',
'webm': 'webm',
'mp4': 'mp4',
};
/**
* return true when window is defined
*/
export declare function isBrowser(): boolean;
/**
* return true when window is defined
*/
export function isBrowser() {
return typeof window !== 'undefined';
}
/**
* returns true if input is an image element
* @param i
*/
export declare function isImage(i: any): i is HTMLImageElement;
/**
* returns true if input is an image element
* @param i
*/
export function isImage(i) {
return i instanceof HTMLImageElement;
}
/**
* Returns true if value is number
* @param value
*/
export declare function isNum(value: number | number[]): boolean;
/**
* Returns true if value is number
* @param value
*/
export function isNum(value) {
return typeof value === "number";
}
import { Plugin } from "../types";
declare const initialPlugins: {
accessibility: boolean;
lazyload: boolean;
placeholder: boolean;
responsive: boolean;
};
export declare const isPluginUsed: (plugins: Plugin[], pluginType: keyof typeof initialPlugins) => boolean;
export {};
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var initialPlugins = {
accessibility: false,
lazyload: false,
placeholder: false,
responsive: false,
};
var getPluginType = function (name) { return name.replace('bound ', '').replace('Plugin', ''); };
export var isPluginUsed = function (plugins, pluginType) {
if (plugins === void 0) { plugins = []; }
var usedPlugins = plugins.reduce(function (used, _a) {
var _b;
var name = _a.name;
return (__assign(__assign({}, used), (_b = {}, _b[getPluginType(name)] = true, _b)));
}, initialPlugins);
return usedPlugins[pluginType];
};
import { Plugins, HtmlPluginState, BaseAnalyticsOptions } from '../types';
import { CloudinaryVideo, CloudinaryImage } from "@cloudinary/url-gen";
/**
* Iterate through plugins and break in cases where the response is canceled. The
* response is canceled if component is updated or unmounted
* @param element {HTMLImageElement|HTMLVideoElement} Html Image or Video element
* @param pluginCloudinaryAsset {CloudinaryImage|CloudinaryVideo} The Cloudinary asset generated by base
* @param plugins {plugins} array of plugins passed in by the user
* @param pluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions
* @param analyticsOptions {BaseAnalyticsOptions} analytics options for the url to be created
*/
export declare function render(element: HTMLImageElement | HTMLVideoElement, pluginCloudinaryAsset: CloudinaryImage | CloudinaryVideo, plugins: Plugins, pluginState: HtmlPluginState, analyticsOptions?: BaseAnalyticsOptions): Promise<void | Partial<Record<"accessibility" | "lazyload" | "responsive" | "placeholder", boolean>>>;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
/**
* Iterate through plugins and break in cases where the response is canceled. The
* response is canceled if component is updated or unmounted
* @param element {HTMLImageElement|HTMLVideoElement} Html Image or Video element
* @param pluginCloudinaryAsset {CloudinaryImage|CloudinaryVideo} The Cloudinary asset generated by base
* @param plugins {plugins} array of plugins passed in by the user
* @param pluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions
* @param analyticsOptions {BaseAnalyticsOptions} analytics options for the url to be created
*/
export function render(element, pluginCloudinaryAsset, plugins, pluginState, analyticsOptions) {
return __awaiter(this, void 0, void 0, function () {
var response, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (plugins === undefined)
return [2 /*return*/];
i = 0;
_a.label = 1;
case 1:
if (!(i < plugins.length)) return [3 /*break*/, 4];
return [4 /*yield*/, plugins[i](element, pluginCloudinaryAsset, pluginState, analyticsOptions, plugins)];
case 2:
response = _a.sent();
if (response === 'canceled') {
return [3 /*break*/, 4];
}
_a.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4:
if (response !== 'canceled') {
return [2 /*return*/, response];
}
return [2 /*return*/];
}
});
});
}
/**
* Predefined screen dimension table ordered by ranking
*/
export declare const screeWidths: number[];
/**
* Predefined screen dimension table ordered by ranking
*/
export var screeWidths = [
1366,
828,
1920,
3840,
1536,
750,
1280,
1600,
1440
];
/**
* Calculates the SSR src based on plugins
* @param plugins The plugins array of plugins passed in by the user
* @param serverCloudinaryImage {CloudinaryImage}
* @return {string} return the src
*/
import { CloudinaryImage } from "@cloudinary/url-gen/assets/CloudinaryImage";
import { BaseAnalyticsOptions, Plugins } from "../types";
export declare function serverSideSrc(plugins?: Plugins, serverCloudinaryImage?: CloudinaryImage, analyticsOptions?: BaseAnalyticsOptions): string;
import cloneDeep from 'lodash.clonedeep';
export function serverSideSrc(plugins, serverCloudinaryImage, analyticsOptions) {
var clonedServerCloudinaryImage = cloneDeep(serverCloudinaryImage);
if (plugins) {
for (var i = 0; i < plugins.length; i++) {
var response = plugins[i](null, clonedServerCloudinaryImage);
if (!response) { //lazyload
break;
}
}
}
return clonedServerCloudinaryImage.toURL(analyticsOptions ? { trackedAnalytics: analyticsOptions } : null);
}