Обновить 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 = { prefixes = {
wrap: "", wrap: "",
image: "image_" image: "image_",
}; };
/** /**
@@ -219,7 +219,7 @@ export default class gallery {
// Processing the modification event // Processing the modification event
this.#events.get("moving").get("dragstart")(event); this.#events.get("moving").get("dragstart")(event);
} },
], ],
[ [
@@ -233,7 +233,7 @@ export default class gallery {
// Processing the modification event // Processing the modification event
this.#events.get("moving").get("dragover")(event); this.#events.get("moving").get("dragover")(event);
} },
], ],
[ [
@@ -251,7 +251,7 @@ export default class gallery {
// Processing the modification event // Processing the modification event
this.#events.get("moving").get("dragenter")(event); this.#events.get("moving").get("dragenter")(event);
} },
], ],
[ [
@@ -269,7 +269,7 @@ export default class gallery {
// Processing the modification event // Processing the modification event
this.#events.get("moving").get("dragleave")(event); this.#events.get("moving").get("dragleave")(event);
} },
], ],
[ [
@@ -287,7 +287,7 @@ export default class gallery {
// Processing the modification event // Processing the modification event
this.#events.get("moving").get("dragend")(event); this.#events.get("moving").get("dragend")(event);
} },
], ],
[ [
@@ -315,35 +315,74 @@ export default class gallery {
// Swapping wraps // Swapping wraps
[this.#identifiers[from], this.#identifiers[to]] = [ [this.#identifiers[from], this.#identifiers[to]] = [
this.#identifiers[to], this.#identifiers[to],
this.#identifiers[from] this.#identifiers[from],
]; ];
} }
// Processing the modification event // Processing the modification event
this.#events.get("moving").get("drop")(event); this.#events.get("moving").get("drop")(event);
} },
] ],
]) ]),
], ],
[ [
"moving", "moving",
new Map([ new Map([
["dragstart", (event) => {}], [
"dragstart",
["dragover", (event) => {}], async (event) => {},
["dragenter", (event) => {}],
["dragleave", (event) => {}],
["dragend", (event) => {}],
["drop", (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.#identifiers.push(
...[...this.#gallery.querySelectorAll("div.image")].map((image) => ...[...this.#gallery.querySelectorAll("div.image")].map((image) =>
image.getAttribute("id") image.getAttribute("id")
) ),
); );
} }
@@ -427,7 +466,7 @@ export default class gallery {
// Regenerating the identifiers registry and return (success) // Regenerating the identifiers registry and return (success)
return Reflect.set(target, property, value); return Reflect.set(target, property, value);
} },
}); });
} }
@@ -475,7 +514,7 @@ export default class gallery {
* Create the wrap with images and buttons * Create the wrap with images and buttons
* *
* @param {number|string} order Number for generating identifiers * @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 * @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("id", this.prefixes.wrap + order);
wrap.setAttribute("draggable", true); wrap.setAttribute("draggable", true);
// Creating the button <button> element // Creating the image <img> element
const button = document.createElement("button"); const image = document.createElement("img");
button.classList.add("delete"); image.setAttribute("id", this.prefixes.image + order);
button.addEventListener("click", (event) => { image.setAttribute("draggable", false);
// Deleting the identifier 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 // Initializing index of the wrap
const index = this.#identifiers.indexOf(this.prefixes.wrap + order); const index = this.#identifiers.indexOf(identifier);
if (index > -1) { if (index > -1) {
// Initialized index of the wrap // Initialized index of the wrap
@@ -504,33 +572,12 @@ export default class gallery {
// Deleting the wrap // Deleting the wrap
wrap.remove(); 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) // Exit (success)
return wrap; return true;
}
// Exit (fail)
return false;
} }
/** /**
@@ -539,9 +586,17 @@ export default class gallery {
* @description * @description
* Creating images <img> elements by loaded images * 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 {(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 // Stopping events handlers
this.stop(); this.stop();
@@ -551,16 +606,20 @@ export default class gallery {
// Deleting deprecated images from the gallery // Deleting deprecated images from the gallery
this.#gallery.innerHTML = ""; this.#gallery.innerHTML = "";
for (const [index, file] of files instanceof FileList // Initializing the imported wraps registry
? Object.entries(files) const imported = new Set();
: files) {
// 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 // Iterating over files
if (file) { if (file) {
// Initialized the file // Initialized the file
// Initializing the file extension // 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)) { if (this.allowed.test(extension)) {
// Allowed the file // Allowed the file
@@ -573,9 +632,26 @@ export default class gallery {
// Writing into the identifiers registry // Writing into the identifiers registry
this.#identifiers.push(wrap.getAttribute("id")); 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 // Starting events handlers
this.start(); this.start();
@@ -589,10 +665,11 @@ export default class gallery {
* *
* @param {(string|number)} [identifier] Identifier of the wrap * @param {(string|number)} [identifier] Identifier of the wrap
* @param {boolean} [base64=false] Convert to Base64 string instead of Blob object * @param {boolean} [base64=false] Convert to Base64 string instead of Blob object
* @param {boolean} silent Do not processing events?
* *
* @returns {Promise} * @returns {Promise}
*/ */
async export(identifier, base64 = false) { async export(identifier, base64 = false, silent = false) {
// Initializing the reader // Initializing the reader
const reader = new FileReader(); const reader = new FileReader();
@@ -601,7 +678,7 @@ export default class gallery {
// Initializing the image // Initializing the image
const image = this.#gallery.querySelector( const image = this.#gallery.querySelector(
"div.image#" + CSS.escape(identifier) + ">img" "div.image#" + CSS.escape(identifier) + ">img",
); );
if (image instanceof HTMLImageElement) { if (image instanceof HTMLImageElement) {
@@ -619,19 +696,34 @@ export default class gallery {
// Initializing listener for the "LoadEnd" event // Initializing listener for the "LoadEnd" event
reader.onloadend = () => resolve(reader.result); reader.onloadend = () => resolve(reader.result);
fetch(content) fetch(content).then((r) => r.blob()).then((value) => {
.then((r) => r.blob())
.then((value) => {
// Converted "blob:..." string to Blob object // Converted "blob:..." string to Blob object
if (base64) { if (base64) {
// Base64 string // Base64 string
// Converting blob to base64 // 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 { } else {
// Blob object // Blob object
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(value);
}
// Exit (success) // Exit (success)
resolve(value); resolve(value);
} }
@@ -640,12 +732,26 @@ export default class gallery {
} else { } else {
// Base64 or HTTP // Base64 or HTTP
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(content);
}
// Exit (success) // Exit (success)
return content; return content;
} }
} catch { } catch {
// Base64 or HTTP // Base64 or HTTP
if (!silent) {
// Requested processing events
// Processing the `one` export event function
this.#events.get("export")?.get("one")(content);
}
// Exit (success) // Exit (success)
return content; return content;
} }
@@ -669,16 +775,24 @@ export default class gallery {
const identifier = wrap.getAttribute("id"); const identifier = wrap.getAttribute("id");
if ( if (
typeof identifier === "string" || typeof identifier === "string" || typeof identifier === "number"
typeof identifier === "number"
) { ) {
// Initialized the wrap identifier // Initialized the wrap identifier
// Converting the image and writing into the converted images buffer // 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) // Exit (success)
return converted; return converted;
} }