Обновить gallery.mjs

This commit is contained in:
2025-10-08 14:32:51 +07:00
parent 15a0cacc2b
commit 9d59bb3f0f

View File

@@ -158,7 +158,7 @@ export default class gallery {
*/
prefixes = {
wrap: "",
image: "image_"
image: "image_",
};
/**
@@ -219,7 +219,7 @@ export default class gallery {
// Processing the modification event
this.#events.get("moving").get("dragstart")(event);
}
},
],
[
@@ -233,7 +233,7 @@ export default class gallery {
// Processing the modification event
this.#events.get("moving").get("dragover")(event);
}
},
],
[
@@ -251,7 +251,7 @@ export default class gallery {
// Processing the modification event
this.#events.get("moving").get("dragenter")(event);
}
},
],
[
@@ -269,7 +269,7 @@ export default class gallery {
// Processing the modification event
this.#events.get("moving").get("dragleave")(event);
}
},
],
[
@@ -287,7 +287,7 @@ export default class gallery {
// Processing the modification event
this.#events.get("moving").get("dragend")(event);
}
},
],
[
@@ -315,35 +315,74 @@ export default class gallery {
// Swapping wraps
[this.#identifiers[from], this.#identifiers[to]] = [
this.#identifiers[to],
this.#identifiers[from]
this.#identifiers[from],
];
}
// Processing the modification event
this.#events.get("moving").get("drop")(event);
}
]
])
},
],
]),
],
[
"moving",
new Map([
["dragstart", (event) => {}],
["dragover", (event) => {}],
["dragenter", (event) => {}],
["dragleave", (event) => {}],
["dragend", (event) => {}],
["drop", (event) => {}]
])
[
"dragstart",
async (event) => {},
],
["wrap", new Map([["delete", (event) => {}]])]
[
"dragover",
async (event) => {},
],
[
"dragenter",
async (event) => {},
],
[
"dragleave",
async (event) => {},
],
[
"dragend",
async (event) => {},
],
[
"drop",
async (event) => {},
],
]),
],
[
"wrap",
new Map([
["generated", async (wrap, order) => {}],
]),
],
[
"import",
new Map([
["one", async (wrap) => {}],
["total", async (wraps) => {}],
]),
],
[
"export",
new Map([
["one", async (src) => {}],
["total", async (converted) => {}],
]),
],
]);
/**
@@ -400,7 +439,7 @@ export default class gallery {
this.#identifiers.push(
...[...this.#gallery.querySelectorAll("div.image")].map((image) =>
image.getAttribute("id")
)
),
);
}
@@ -427,7 +466,7 @@ export default class gallery {
// Regenerating the identifiers registry and return (success)
return Reflect.set(target, property, value);
}
},
});
}
@@ -475,7 +514,7 @@ export default class gallery {
* Create the wrap with images and buttons
*
* @param {number|string} order Number for generating identifiers
* @param {(File|string)} target The image for `srt` attribute
* @param {(File|string)} target The image for `src` attribute
*
* @returns {HTMLElement} Created wrap <div> element with images and buttons
*/
@@ -486,14 +525,43 @@ export default class gallery {
wrap.setAttribute("id", this.prefixes.wrap + order);
wrap.setAttribute("draggable", true);
// Creating the button <button> element
const button = document.createElement("button");
button.classList.add("delete");
button.addEventListener("click", (event) => {
// Deleting the identifier
// Creating the image <img> element
const image = document.createElement("img");
image.setAttribute("id", this.prefixes.image + order);
image.setAttribute("draggable", false);
image.setAttribute(
"src",
target instanceof File
? window.URL.createObjectURL(target)
: (target + "?updated=" + Date.now()),
);
// Assembling
wrap.appendChild(image);
// Processing the `generated` wrap event function
this.#events.get("wrap")?.get("generated")(wrap, order);
// Exit (success)
return wrap;
}
/**
* @name Delete
*
* @description
* Delete the wrap element and its identifier from the registry
*
* @param {HTMLElement} wrap The wrap
*
* @returns {boolean} Is the wrap was deleted?
*/
delete(wrap) {
// Initializing identifier of the wrap
const identifier = wrap.getAttribute("id");
// Initializing index of the wrap
const index = this.#identifiers.indexOf(this.prefixes.wrap + order);
const index = this.#identifiers.indexOf(identifier);
if (index > -1) {
// Initialized index of the wrap
@@ -504,33 +572,12 @@ export default class gallery {
// Deleting the wrap
wrap.remove();
// Processing the `ondelete` function
this.#events.get("wrap")?.get("delete")(event);
}
});
// Creating the trash icon <i> element
const trash = document.createElement("i");
trash.classList.add("icon", "trash");
// Creating the image <img> element
const image = document.createElement("img");
image.setAttribute("id", this.prefixes.image + order);
image.setAttribute("draggable", false);
image.setAttribute(
"src",
target instanceof File
? window.URL.createObjectURL(target)
: target + "?updated=" + Date.now()
);
// Assembling
wrap.appendChild(image);
button.appendChild(trash);
wrap.appendChild(button);
// Exit (success)
return wrap;
return true;
}
// Exit (fail)
return false;
}
/**
@@ -539,9 +586,17 @@ export default class gallery {
* @description
* Creating images <img> elements by loaded images
*
* We can not change `FileList` content of `<input type="file">`,
* so if you add images via `gallery.import()`,
* do not rely on the contents of the `<input>` element
*
* Use `gallery.export()` instead
*
* @param {(FileList|object} files Files for importing (can be array of URL`s)
* @param {boolean} reverse Reverse the files registry?
* @param {boolean} silent Do not processing events?
*/
import(files) {
import(files, reverse = false, silent = false) {
// Stopping events handlers
this.stop();
@@ -551,16 +606,20 @@ export default class gallery {
// Deleting deprecated images from the gallery
this.#gallery.innerHTML = "";
for (const [index, file] of files instanceof FileList
? Object.entries(files)
: files) {
// Initializing the imported wraps registry
const imported = new Set();
// Initializing the registry of files
const registry = files instanceof FileList ? Object.entries(files) : files;
for (const [index, file] of reverse ? registry.reverse() : reverse) {
// Iterating over files
if (file) {
// Initialized the file
// Initializing the file extension
const extension = file.name ?? file.match(/\.\w{3,4}$/)[0];
const extension = file.name ?? file.match(/\.\w{3,4}$/)?.[0];
if (this.allowed.test(extension)) {
// Allowed the file
@@ -573,9 +632,26 @@ export default class gallery {
// Writing into the identifiers registry
this.#identifiers.push(wrap.getAttribute("id"));
// Writing into the imported wraps registry
imported.add(wrap);
if (!silent) {
// Requested processing events
// Processing the `one` import event function
this.#events.get("import")?.get("one")(wrap);
}
}
}
}
if (!silent) {
// Requested processing events
// Processing the `total` import event function
this.#events.get("import")?.get("total")(imported);
}
// Starting events handlers
this.start();
@@ -589,10 +665,11 @@ export default class gallery {
*
* @param {(string|number)} [identifier] Identifier of the wrap
* @param {boolean} [base64=false] Convert to Base64 string instead of Blob object
* @param {boolean} silent Do not processing events?
*
* @returns {Promise}
*/
async export(identifier, base64 = false) {
async export(identifier, base64 = false, silent = false) {
// Initializing the reader
const reader = new FileReader();
@@ -601,7 +678,7 @@ export default class gallery {
// Initializing the image
const image = this.#gallery.querySelector(
"div.image#" + CSS.escape(identifier) + ">img"
"div.image#" + CSS.escape(identifier) + ">img",
);
if (image instanceof HTMLImageElement) {
@@ -619,19 +696,34 @@ export default class gallery {
// Initializing listener for the "LoadEnd" event
reader.onloadend = () => resolve(reader.result);
fetch(content)
.then((r) => r.blob())
.then((value) => {
fetch(content).then((r) => r.blob()).then((value) => {
// Converted "blob:..." string to Blob object
if (base64) {
// Base64 string
// Converting blob to base64
reader.readAsDataURL(value);
const converted = reader.readAsDataURL(value);
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(converted);
}
// Exit (success)
resolve(converted);
} else {
// Blob object
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(value);
}
// Exit (success)
resolve(value);
}
@@ -640,12 +732,26 @@ export default class gallery {
} else {
// Base64 or HTTP
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(content);
}
// Exit (success)
return content;
}
} catch {
// Base64 or HTTP
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(content);
}
// Exit (success)
return content;
}
@@ -669,16 +775,24 @@ export default class gallery {
const identifier = wrap.getAttribute("id");
if (
typeof identifier === "string" ||
typeof identifier === "number"
typeof identifier === "string" || typeof identifier === "number"
) {
// Initialized the wrap identifier
// Converting the image and writing into the converted images buffer
converted.push((await this.export(identifier)) ?? null);
converted.push(
await this.export(identifier, base64, silent) ?? null,
);
}
}
if (!silent) {
// Requested processing events
// Processing the `total` export event function
this.#events.get("export")?.get("total")(converted);
}
// Exit (success)
return converted;
}