image-exporter 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # image-exporter [v1.0.9]
1
+ # image-exporter [v1.1.0]
2
2
 
3
3
  image-exporter is a client-side javascript tool that downloads DOM elements as images. It can be imported using your favorite package manager or used directly the window.
4
4
 
@@ -4083,12 +4083,30 @@ function requireJszip_min() {
4083
4083
  }
4084
4084
  var jszip_minExports = requireJszip_min();
4085
4085
  const JSZip = /* @__PURE__ */ getDefaultExportFromCjs(jszip_minExports);
4086
- async function downloadImages(images, config) {
4087
- if (images.length === 1) {
4088
- const image = images[0];
4086
+ const defaultImageOptions = {
4087
+ label: "image",
4088
+ format: "jpg",
4089
+ scale: 1,
4090
+ quality: 1,
4091
+ includeScaleInLabel: false
4092
+ };
4093
+ const defaultConfig = {
4094
+ ...defaultImageOptions,
4095
+ downloadImages: true,
4096
+ defaultImageLabel: "image",
4097
+ zipLabel: "images",
4098
+ corsProxyBaseUrl: "",
4099
+ enableWindowLogging: true,
4100
+ loggingLevel: "none"
4101
+ };
4102
+ async function downloadImages(images, userConfig = defaultConfig) {
4103
+ const config = userConfig ? { ...defaultConfig, ...userConfig } : defaultConfig;
4104
+ const uniqueImages = ensureUniqueFileNames(images);
4105
+ if (uniqueImages.length === 1) {
4106
+ const image = uniqueImages[0];
4089
4107
  await download(image.dataURL, image.fileName);
4090
- } else if (images.length > 1) {
4091
- const imagesBlob = await zipUpImages(images);
4108
+ } else if (uniqueImages.length > 1) {
4109
+ const imagesBlob = await zipUpImages(uniqueImages);
4092
4110
  if (imagesBlob) await download(imagesBlob, parseLabel(config));
4093
4111
  }
4094
4112
  }
@@ -4121,6 +4139,26 @@ function parseLabel(config) {
4121
4139
  return "images";
4122
4140
  }
4123
4141
  }
4142
+ function ensureUniqueFileNames(images) {
4143
+ const fileNameMap = /* @__PURE__ */ new Map();
4144
+ return images.map((image) => {
4145
+ const { fileName } = image;
4146
+ const lastDotIndex = fileName.lastIndexOf(".");
4147
+ const baseName = lastDotIndex !== -1 ? fileName.substring(0, lastDotIndex) : fileName;
4148
+ const extension = lastDotIndex !== -1 ? fileName.substring(lastDotIndex) : "";
4149
+ if (!fileNameMap.has(fileName)) {
4150
+ fileNameMap.set(fileName, 1);
4151
+ return image;
4152
+ }
4153
+ const count = fileNameMap.get(fileName) + 1;
4154
+ fileNameMap.set(fileName, count);
4155
+ const newFileName = `${baseName}-${count}${extension}`;
4156
+ return {
4157
+ ...image,
4158
+ fileName: newFileName
4159
+ };
4160
+ });
4161
+ }
4124
4162
  const log = {
4125
4163
  info: (...messages) => logAction(messages, "info"),
4126
4164
  error: (...messages) => logAction(messages, "error"),
@@ -4393,22 +4431,6 @@ async function getImageOptions(element, config) {
4393
4431
  }
4394
4432
  }
4395
4433
  }
4396
- const defaultImageOptions = {
4397
- label: "image",
4398
- format: "jpg",
4399
- scale: 1,
4400
- quality: 1,
4401
- includeScaleInLabel: false
4402
- };
4403
- const defaultConfig = {
4404
- ...defaultImageOptions,
4405
- downloadImages: true,
4406
- defaultImageLabel: "image",
4407
- zipLabel: "images",
4408
- corsProxyBaseUrl: "",
4409
- enableWindowLogging: true,
4410
- loggingLevel: "none"
4411
- };
4412
4434
  function removeHiddenElements(elements) {
4413
4435
  elements = Array.from(elements);
4414
4436
  return elements.filter((element) => isVisible(element));
@@ -4502,7 +4524,9 @@ async function capture(elements, userConfig = defaultConfig) {
4502
4524
  }
4503
4525
  if (typeof window !== "undefined") {
4504
4526
  window.imageExporter = capture;
4527
+ window.imageExporterDownload = downloadImages;
4505
4528
  }
4506
4529
  export {
4507
- capture
4530
+ capture,
4531
+ downloadImages
4508
4532
  };
@@ -4088,12 +4088,30 @@
4088
4088
  }
4089
4089
  var jszip_minExports = requireJszip_min();
4090
4090
  const JSZip = /* @__PURE__ */ getDefaultExportFromCjs(jszip_minExports);
4091
- async function downloadImages(images, config) {
4092
- if (images.length === 1) {
4093
- const image = images[0];
4091
+ const defaultImageOptions = {
4092
+ label: "image",
4093
+ format: "jpg",
4094
+ scale: 1,
4095
+ quality: 1,
4096
+ includeScaleInLabel: false
4097
+ };
4098
+ const defaultConfig = {
4099
+ ...defaultImageOptions,
4100
+ downloadImages: true,
4101
+ defaultImageLabel: "image",
4102
+ zipLabel: "images",
4103
+ corsProxyBaseUrl: "",
4104
+ enableWindowLogging: true,
4105
+ loggingLevel: "none"
4106
+ };
4107
+ async function downloadImages(images, userConfig = defaultConfig) {
4108
+ const config = userConfig ? { ...defaultConfig, ...userConfig } : defaultConfig;
4109
+ const uniqueImages = ensureUniqueFileNames(images);
4110
+ if (uniqueImages.length === 1) {
4111
+ const image = uniqueImages[0];
4094
4112
  await download(image.dataURL, image.fileName);
4095
- } else if (images.length > 1) {
4096
- const imagesBlob = await zipUpImages(images);
4113
+ } else if (uniqueImages.length > 1) {
4114
+ const imagesBlob = await zipUpImages(uniqueImages);
4097
4115
  if (imagesBlob) await download(imagesBlob, parseLabel(config));
4098
4116
  }
4099
4117
  }
@@ -4126,6 +4144,26 @@
4126
4144
  return "images";
4127
4145
  }
4128
4146
  }
4147
+ function ensureUniqueFileNames(images) {
4148
+ const fileNameMap = /* @__PURE__ */ new Map();
4149
+ return images.map((image) => {
4150
+ const { fileName } = image;
4151
+ const lastDotIndex = fileName.lastIndexOf(".");
4152
+ const baseName = lastDotIndex !== -1 ? fileName.substring(0, lastDotIndex) : fileName;
4153
+ const extension = lastDotIndex !== -1 ? fileName.substring(lastDotIndex) : "";
4154
+ if (!fileNameMap.has(fileName)) {
4155
+ fileNameMap.set(fileName, 1);
4156
+ return image;
4157
+ }
4158
+ const count = fileNameMap.get(fileName) + 1;
4159
+ fileNameMap.set(fileName, count);
4160
+ const newFileName = `${baseName}-${count}${extension}`;
4161
+ return {
4162
+ ...image,
4163
+ fileName: newFileName
4164
+ };
4165
+ });
4166
+ }
4129
4167
  const log = {
4130
4168
  info: (...messages) => logAction(messages, "info"),
4131
4169
  error: (...messages) => logAction(messages, "error"),
@@ -4398,22 +4436,6 @@
4398
4436
  }
4399
4437
  }
4400
4438
  }
4401
- const defaultImageOptions = {
4402
- label: "image",
4403
- format: "jpg",
4404
- scale: 1,
4405
- quality: 1,
4406
- includeScaleInLabel: false
4407
- };
4408
- const defaultConfig = {
4409
- ...defaultImageOptions,
4410
- downloadImages: true,
4411
- defaultImageLabel: "image",
4412
- zipLabel: "images",
4413
- corsProxyBaseUrl: "",
4414
- enableWindowLogging: true,
4415
- loggingLevel: "none"
4416
- };
4417
4439
  function removeHiddenElements(elements) {
4418
4440
  elements = Array.from(elements);
4419
4441
  return elements.filter((element) => isVisible(element));
@@ -4507,8 +4529,10 @@
4507
4529
  }
4508
4530
  if (typeof window !== "undefined") {
4509
4531
  window.imageExporter = capture;
4532
+ window.imageExporterDownload = downloadImages;
4510
4533
  }
4511
4534
  exports2.capture = capture;
4535
+ exports2.downloadImages = downloadImages;
4512
4536
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
4513
4537
  });
4514
4538
  })()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "image-exporter",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Easily download one or more DOM elements as images",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -1,6 +1,7 @@
1
1
  import { Config, Image, Label } from "../types";
2
2
  import download from "downloadjs";
3
3
  import JSZip from "jszip";
4
+ import { defaultConfig } from "../config";
4
5
 
5
6
  /**
6
7
  * downloadImages
@@ -9,13 +10,20 @@ import JSZip from "jszip";
9
10
  *
10
11
  * If multiple images are provided, they will be zipped and downloaded as a file.
11
12
  */
12
- export async function downloadImages(images: Image[], config: Config) {
13
- if (images.length === 1) {
14
- const image = images[0];
13
+ export async function downloadImages(
14
+ images: Image[],
15
+ userConfig: Config = defaultConfig
16
+ ) {
17
+ const config = userConfig ? { ...defaultConfig, ...userConfig } : defaultConfig;
15
18
 
19
+ // Ensure unique filenames before downloading
20
+ const uniqueImages = ensureUniqueFileNames(images);
21
+
22
+ if (uniqueImages.length === 1) {
23
+ const image = uniqueImages[0];
16
24
  await download(image.dataURL, image.fileName);
17
- } else if (images.length > 1) {
18
- const imagesBlob = await zipUpImages(images);
25
+ } else if (uniqueImages.length > 1) {
26
+ const imagesBlob = await zipUpImages(uniqueImages);
19
27
  if (imagesBlob) await download(imagesBlob, parseLabel(config));
20
28
  }
21
29
  }
@@ -67,3 +75,41 @@ function parseLabel(config: Config): Label {
67
75
  return "images";
68
76
  }
69
77
  }
78
+
79
+ /**
80
+ * ensureUniqueFileNames
81
+ *
82
+ * Ensures all image filenames are unique by adding -2, -3, etc. to duplicates
83
+ * before the file extension.
84
+ */
85
+ function ensureUniqueFileNames(images: Image[]): Image[] {
86
+ const fileNameMap = new Map<string, number>();
87
+
88
+ return images.map((image) => {
89
+ const { fileName } = image;
90
+
91
+ // Split the filename into base and extension
92
+ const lastDotIndex = fileName.lastIndexOf(".");
93
+ const baseName = lastDotIndex !== -1 ? fileName.substring(0, lastDotIndex) : fileName;
94
+ const extension = lastDotIndex !== -1 ? fileName.substring(lastDotIndex) : "";
95
+
96
+ // Check if this base filename has been seen before
97
+ if (!fileNameMap.has(fileName)) {
98
+ fileNameMap.set(fileName, 1);
99
+ return image;
100
+ }
101
+
102
+ // If it's a duplicate, increment the counter and create a new filename
103
+ const count = fileNameMap.get(fileName)! + 1;
104
+ fileNameMap.set(fileName, count);
105
+
106
+ // Create new filename with -2, -3, etc. before the extension
107
+ const newFileName = `${baseName}-${count}${extension}`;
108
+
109
+ // Return a new image object with the updated filename
110
+ return {
111
+ ...image,
112
+ fileName: newFileName,
113
+ };
114
+ });
115
+ }
package/src/index.ts CHANGED
@@ -4,11 +4,13 @@
4
4
  /* by briantuckerdesign */
5
5
  /* -------------------------------------------------------------------------- */
6
6
  import { capture } from "./capture";
7
+ import { downloadImages } from "./capture/download-images";
7
8
 
8
9
  /** Exports for use in browser */
9
10
  if (typeof window !== "undefined") {
10
11
  (window as any).imageExporter = capture;
12
+ (window as any).imageExporterDownload = downloadImages;
11
13
  }
12
14
 
13
15
  /** Exports for use as an imported package */
14
- export { capture };
16
+ export { capture, downloadImages };