Skip to content

Commit 23db138

Browse files
Merge pull request #196 from cloudinary/plugins-use-analytics-tokens
fix: pass analytics options down to the plugins, and use it in placeh…
2 parents 8466e99 + 0dcffd9 commit 23db138

File tree

6 files changed

+36
-30
lines changed

6 files changed

+36
-30
lines changed

packages/html/src/layers/htmlImageLayer.ts

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
22
import {Plugins, HtmlPluginState, AnalyticsOptions} from '../types.js'
33
import cloneDeep from 'lodash.clonedeep';
44
import {render} from '../utils/render.js';
5+
import {getAnalyticsOptions} from "../utils/analytics";
56

67
export class HtmlImageLayer{
78
private imgElement: any;
@@ -11,16 +12,10 @@ export class HtmlImageLayer{
1112
this.htmlPluginState = {cleanupCallbacks:[], pluginEventSubscription: []};
1213
const pluginCloudinaryImage = cloneDeep(userCloudinaryImage);
1314

14-
render(element, pluginCloudinaryImage, plugins, this.htmlPluginState)
15+
render(element, pluginCloudinaryImage, plugins, this.htmlPluginState, analyticsOptions)
1516
.then(()=>{ // when resolved updates the src
1617
this.htmlPluginState.pluginEventSubscription.forEach(fn=>{fn()});
17-
this.imgElement.setAttribute('src', pluginCloudinaryImage.toURL({
18-
...analyticsOptions && {trackedAnalytics: {
19-
sdkCode: analyticsOptions.sdkCode,
20-
sdkSemver: analyticsOptions.sdkSemver,
21-
techVersion: analyticsOptions.techVersion,
22-
}}
23-
}));
18+
this.imgElement.setAttribute('src', pluginCloudinaryImage.toURL(getAnalyticsOptions(analyticsOptions)));
2419
});
2520
}
2621

@@ -34,13 +29,7 @@ export class HtmlImageLayer{
3429
const pluginCloudinaryImage = cloneDeep(userCloudinaryImage);
3530
render(this.imgElement, pluginCloudinaryImage, plugins, this.htmlPluginState)
3631
.then(()=>{
37-
this.imgElement.setAttribute('src', pluginCloudinaryImage.toURL({
38-
...analyticsOptions && {trackedAnalytics: {
39-
sdkCode: analyticsOptions.sdkCode,
40-
sdkSemver: analyticsOptions.sdkSemver,
41-
techVersion: analyticsOptions.techVersion,
42-
}}
43-
}));
32+
this.imgElement.setAttribute('src', pluginCloudinaryImage.toURL(getAnalyticsOptions(analyticsOptions)));
4433
});
4534
}
4635
}

packages/html/src/plugins/placeholder.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import cloneDeep from 'lodash.clonedeep'
22
import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
3-
import {Plugin, HtmlPluginState} from "../types";
3+
import {Plugin, HtmlPluginState, AnalyticsOptions} from "../types";
44
import {PLACEHOLDER_IMAGE_OPTIONS, singleTransparentPixel} from '../utils/internalConstants.js';
55
import {PlaceholderMode} from '../types.js';
66
import {isBrowser} from "../utils/isBrowser.js";
77
import {Action} from "@cloudinary/url-gen/internal/Action";
8-
import {isImage} from "../utils/isImage.js";
8+
import {isImage} from "../utils/isImage";
9+
import {getAnalyticsOptions} from "../utils/analytics";
910

1011
/**
1112
* @namespace
@@ -25,8 +26,9 @@ export function placeholder({mode='vectorize'}:{mode?: string}={}): Plugin{
2526
* @param element {HTMLImageElement} The image element.
2627
* @param pluginCloudinaryImage {CloudinaryImage}
2728
* @param htmlPluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions.
29+
* @param analyticsOptions {AnalyticsOptions} analytics options for the url to be created
2830
*/
29-
function placeholderPlugin(mode: PlaceholderMode, element: HTMLImageElement, pluginCloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState): Promise<void | string> | boolean {
31+
function placeholderPlugin(mode: PlaceholderMode, element: HTMLImageElement, pluginCloudinaryImage: CloudinaryImage, htmlPluginState: HtmlPluginState, analyticsOptions?: AnalyticsOptions): Promise<void | string> | boolean {
3032
// @ts-ignore
3133
// If we're using an invalid mode, we default to vectorize
3234
if(!PLACEHOLDER_IMAGE_OPTIONS[mode]){
@@ -71,7 +73,7 @@ function placeholderPlugin(mode: PlaceholderMode, element: HTMLImageElement, plu
7173
});
7274

7375
// Set the SRC of the imageElement to the URL of the placeholder Image
74-
element.src = placeholderClonedImage.toURL();
76+
element.src = placeholderClonedImage.toURL(getAnalyticsOptions(analyticsOptions));
7577

7678
//Fallback, if placeholder errors, load a single transparent pixel
7779
element.onerror = () => {
@@ -98,7 +100,7 @@ function placeholderPlugin(mode: PlaceholderMode, element: HTMLImageElement, plu
98100
});
99101
// load image once placeholder is done loading
100102
const largeImage = new Image();
101-
largeImage.src = pluginCloudinaryImage.toURL();
103+
largeImage.src = pluginCloudinaryImage.toURL(getAnalyticsOptions(analyticsOptions));
102104
largeImage.onload = () => {
103105
resolve();
104106
};

packages/html/src/plugins/responsive.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
2-
import {Plugin, HtmlPluginState} from "../types.js";
2+
import {Plugin, HtmlPluginState, AnalyticsOptions} from "../types.js";
33
import {scale} from "@cloudinary/url-gen/actions/resize";
44
import debounce from 'lodash.debounce';
55
import {isNum} from '../utils/isNum.js';
66
import {isBrowser} from "../utils/isBrowser.js";
77
import {Action} from "@cloudinary/url-gen/internal/Action";
88
import {isImage} from "../utils/isImage.js";
9+
import {getAnalyticsOptions} from '../utils/analytics'
910

1011
/**
1112
* @namespace
@@ -26,8 +27,9 @@ export function responsive({steps}:{steps?: number | number[]}={}): Plugin{
2627
* @param element {HTMLImageElement} The image element
2728
* @param responsiveImage {CloudinaryImage}
2829
* @param htmlPluginState {HtmlPluginState} holds cleanup callbacks and event subscriptions
30+
* @param analyticsOptions {AnalyticsOptions} analytics options for the url to be created
2931
*/
30-
function responsivePlugin(steps?: number | number[], element?:HTMLImageElement, responsiveImage?: CloudinaryImage, htmlPluginState?: HtmlPluginState): Promise<void | string> | boolean {
32+
function responsivePlugin(steps?: number | number[], element?:HTMLImageElement, responsiveImage?: CloudinaryImage, htmlPluginState?: HtmlPluginState, analyticsOptions?: AnalyticsOptions): Promise<void | string> | boolean {
3133

3234
if(!isBrowser()) return true;
3335

@@ -42,12 +44,12 @@ function responsivePlugin(steps?: number | number[], element?:HTMLImageElement,
4244
// Use a tagged generic action that can be later searched and replaced.
4345
responsiveImage.addAction(new Action().setActionTag('responsive'));
4446
// Immediately run the resize plugin, ensuring that first render gets a responsive image.
45-
onResize(steps, element, responsiveImage);
47+
onResize(steps, element, responsiveImage, analyticsOptions);
4648

4749
let resizeRef: any;
4850
htmlPluginState.pluginEventSubscription.push(()=>{
4951
window.addEventListener('resize', resizeRef = debounce(()=>{
50-
onResize(steps, element, responsiveImage);
52+
onResize(steps, element, responsiveImage, analyticsOptions);
5153
}, 100));
5254
});
5355
resolve();
@@ -60,10 +62,11 @@ function responsivePlugin(steps?: number | number[], element?:HTMLImageElement,
6062
* | number[] A set of image sizes in pixels.
6163
* @param element {HTMLImageElement} The image element
6264
* @param responsiveImage {CloudinaryImage}
65+
* @param analyticsOptions {AnalyticsOptions} analytics options for the url to be created
6366
*/
64-
function onResize(steps?: number | number[], element?:HTMLImageElement, responsiveImage?: CloudinaryImage){
67+
function onResize(steps?: number | number[], element?:HTMLImageElement, responsiveImage?: CloudinaryImage, analyticsOptions?: AnalyticsOptions){
6568
updateByContainerWidth(steps, element, responsiveImage);
66-
element.src = responsiveImage.toURL();
69+
element.src = responsiveImage.toURL(getAnalyticsOptions(analyticsOptions));
6770
}
6871

6972
/**

packages/html/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
22
import {VideoCodecAction} from "@cloudinary/url-gen/actions/transcode/VideoCodecAction";
33

4-
export type Plugin = (element: HTMLImageElement|HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState?: HtmlPluginState) => Promise<string | void>;
4+
export type Plugin = (element: HTMLImageElement|HTMLVideoElement, cloudinaryImage: CloudinaryImage, htmlPluginState?: HtmlPluginState, analyticsOptions?: AnalyticsOptions) => Promise<string | void>;
55

66
export type Plugins = Plugin[];
77

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {AnalyticsOptions} from "../types";
2+
3+
export const getAnalyticsOptions = (options?: AnalyticsOptions) => {
4+
return options ? {
5+
trackedAnalytics: {
6+
sdkCode: options.sdkCode,
7+
sdkSemver: options.sdkSemver,
8+
techVersion: options.techVersion,
9+
}
10+
} : null
11+
}

packages/html/src/utils/render.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Plugins, HtmlPluginState} from '../types.js'
1+
import {Plugins, HtmlPluginState, AnalyticsOptions} from '../types.js'
22
import {CloudinaryVideo, CloudinaryImage} from "@cloudinary/url-gen";
33

44
/**
@@ -8,11 +8,12 @@ import {CloudinaryVideo, CloudinaryImage} from "@cloudinary/url-gen";
88
* @param pluginCloudinaryAsset {CloudinaryImage|CloudinaryVideo} The Cloudinary asset generated by base
99
* @param plugins {plugins} array of plugins passed in by the user
1010
* @param pluginState {htmlPluginState} Holds cleanup callbacks and event subscriptions
11+
* @param analyticsOptions {AnalyticsOptions} analytics options for the url to be created
1112
*/
12-
export async function render(element: HTMLImageElement | HTMLVideoElement, pluginCloudinaryAsset: CloudinaryImage | CloudinaryVideo, plugins: Plugins, pluginState: HtmlPluginState) {
13+
export async function render(element: HTMLImageElement | HTMLVideoElement, pluginCloudinaryAsset: CloudinaryImage | CloudinaryVideo, plugins: Plugins, pluginState: HtmlPluginState, analyticsOptions?: AnalyticsOptions) {
1314
if(plugins === undefined) return;
1415
for(let i = 0; i < plugins.length; i++){
15-
const response = await plugins[i](element, pluginCloudinaryAsset, pluginState);
16+
const response = await plugins[i](element, pluginCloudinaryAsset, pluginState, analyticsOptions);
1617
if(response === 'canceled'){
1718
break;
1819
}

0 commit comments

Comments
 (0)