From 13cc5980ee44d4502a19976d7f1574a07e073832 Mon Sep 17 00:00:00 2001 From: Arsen Mirzaev Tatyano-Muradovich Date: Wed, 9 Jul 2025 22:51:28 +0700 Subject: [PATCH] mega ebanul --- gallery.mjs | 548 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 406 insertions(+), 142 deletions(-) diff --git a/gallery.mjs b/gallery.mjs index 48c2165..51ad2f9 100644 --- a/gallery.mjs +++ b/gallery.mjs @@ -10,7 +10,7 @@ * @public * * @example - * import gallery from "https://codepen.io/mirzaev-sexy/pen/RNPdYvv.js"; + * import gallery from "https://git.svoboda.works/mirzaev/gallery.mjs/raw/branch/stable/gallery.mjs"; * * // Initializing the instance * const instance = new gallery( @@ -41,6 +41,20 @@ export default class gallery { */ #wrap; + /** + * @name Wrap (get) + * + * @description + * Wrap for the gallery + * + * @return {HTMLElement} + * + * @public + */ + get wrap() { + return this.#wrap; + } + /** * @name Input * @@ -53,6 +67,20 @@ export default class gallery { */ #input; + /** + * @name Input (get) + * + * @description + * Input for importing images + * + * @return {HTMLInputElement} + * + * @public + */ + get input() { + return this.#input; + } + /** * @name Gallery * @@ -65,6 +93,20 @@ export default class gallery { */ #gallery; + /** + * @name Gallery (get) + * + * @description + * Wrap for images elements (`flex-flow: row wrap`) + * + * @return {HTMLElement} + * + * @public + */ + get gallery() { + return this.#gallery; + } + /** * @name Identifiers * @@ -119,6 +161,16 @@ export default class gallery { image: "image_" }; + /** + * @name Allowed + * + * @description + * Regular expression for checking matching to images extensions (not MIME-types) + * + * @type {RegExp} + */ + allowed = /\.(jpe?g|png|gif|webp)$/i; + /** * @name Dragged * @@ -131,6 +183,20 @@ export default class gallery { */ #dragged; + /** + * @name Dragged (get) + * + * @description + * Buffer of currently dragged wrap identifier + * + * @type {string|number} + * + * @public + */ + get dragged() { + return this.#dragged; + } + /** * @name Events * @@ -140,104 +206,157 @@ export default class gallery { */ #events = new Map([ [ - "dragstart", - (event) => { - // Disabling default actions - this.#dragged = event.target.getAttribute("id"); + "system", + new Map([ + [ + "dragstart", + (event) => { + // Disabling default actions + this.#dragged = event.target.getAttribute("id"); - // Allowing moving - event.dataTransfer.effectAllowed = "move"; - } + // Allowing moving + event.dataTransfer.effectAllowed = "move"; + + // Processing the modification event + this.#events.get("moving").get("dragstart")(event); + } + ], + + [ + "dragover", + (event) => { + // Disabling default actions + event.preventDefault(); + + // Allowing moving + event.dataTransfer.dropEffect = "move"; + + // Processing the modification event + this.#events.get("moving").get("dragover")(event); + } + ], + + [ + "dragenter", + (event) => { + // Searching for the wrap + const wrap = event.target.closest("div.image"); + + if (wrap?.getAttribute("id") !== this.#dragged) { + // Wrap is not currently draggable wrap + + // Writing class about targeting + wrap?.classList.add("target"); + } + + // Processing the modification event + this.#events.get("moving").get("dragenter")(event); + } + ], + + [ + "dragleave", + (event) => { + // Searching for the closest parent wrap + const wrap = event.target.closest("div.image"); + + if (wrap instanceof HTMLElement) { + // Found the wrap + + // Deleting class about targeting + wrap.classList.remove("target"); + } + + // Processing the modification event + this.#events.get("moving").get("dragleave")(event); + } + ], + + [ + "dragend", + (event) => { + // Searching for the closest parent wrap + const wrap = event.target.closest("div.image"); + + if (wrap instanceof HTMLElement) { + // Found the wrap + + // Deleting class about targeting + wrap.classList.remove("target"); + } + + // Processing the modification event + this.#events.get("moving").get("dragend")(event); + } + ], + + [ + "drop", + (event) => { + // Searching for the closest parent wrap + const wrap = event.target.closest("div.image"); + + if ( + wrap instanceof HTMLElement && + wrap.getAttribute("id") && + wrap.getAttribute("id") !== this.#dragged + ) { + // Found the wrap and has it identifier and it not currently draggable wrap + + // Deleting class about targeting from every wrap + this.#gallery + .querySelector("div.image.target") + ?.classList.remove("target"); + + // Initializing indexes of wraps in the identifiers registry + const from = this.#identifiers.indexOf(this.#dragged); + const to = this.#identifiers.indexOf(wrap.getAttribute("id")); + + // Swapping wraps + [this.#identifiers[from], this.#identifiers[to]] = [ + this.#identifiers[to], + this.#identifiers[from] + ]; + } + + // Processing the modification event + this.#events.get("moving").get("drop")(event); + } + ] + ]) ], [ - "dragover", - (event) => { - // Disabling default actions - event.preventDefault(); + "moving", + new Map([ + ["dragstart", (event) => {}], - // Allowing moving - event.dataTransfer.dropEffect = "move"; - } + ["dragover", (event) => {}], + + ["dragenter", (event) => {}], + + ["dragleave", (event) => {}], + + ["dragend", (event) => {}], + + ["drop", (event) => {}] + ]) ], - [ - "dragenter", - (event) => { - // Searching for the wrap - const wrap = event.target.closest("div.image"); - - if (wrap?.getAttribute("id") !== this.#dragged) { - // Wrap is not currently draggable wrap - - // Writing class about targeting - wrap?.classList.add("target"); - } - } - ], - - [ - "dragleave", - (event) => { - // Searching for the closest parent wrap - const wrap = event.target.closest("div.image"); - - if (wrap instanceof HTMLElement) { - // Found the wrap - - // Deleting class about targeting - wrap.classList.remove("target"); - } - } - ], - - [ - "dragend", - (event) => { - // Searching for the closest parent wrap - const wrap = event.target.closest("div.image"); - - if (wrap instanceof HTMLElement) { - // Found the wrap - - // Deleting class about targeting - wrap.classList.remove("target"); - } - } - ], - - [ - "drop", - (event) => { - // Searching for the closest parent wrap - const wrap = event.target.closest("div.image"); - - if ( - wrap instanceof HTMLElement && - wrap.getAttribute("id") && - wrap.getAttribute("id") !== this.#dragged - ) { - // Found the wrap and has it identifier and it not currently draggable wrap - - // Deleting class about targeting from every wrap - this.#gallery - .querySelector("div.image.target") - ?.classList.remove("target"); - - // Initializing indexes of wraps in the identifiers registry - const from = this.#identifiers.indexOf(this.#dragged); - const to = this.#identifiers.indexOf(wrap.getAttribute("id")); - - // Swapping wraps - [this.#identifiers[from], this.#identifiers[to]] = [ - this.#identifiers[to], - this.#identifiers[from] - ]; - } - } - ] + ["wrap", new Map([["delete", (event) => {}]])] ]); + /** + * @name Events (get) + * + * @type {Map} + * + * @public + */ + get events() { + return this.#events; + } + /** * @name Constructor * @@ -248,7 +367,7 @@ export default class gallery { * @param {HTMLInputElement} input The input element * @param {HTMLElement} gallery The gallery element * @param {boolean} [inject=false] Write the instance into the wrap element? - **/ + */ constructor(wrap, input, gallery, inject = false) { if (wrap instanceof HTMLElement) { // Initialized the wrap element @@ -292,7 +411,7 @@ export default class gallery { * Initialize the identifiers registry proxy */ proxy() { - // Initializing the identifiers registry + // Initializing the identifiers registry proxy this.#identifiers = new Proxy([], { set: (target, property, value) => { // Postponing the update with a microtask @@ -300,14 +419,10 @@ export default class gallery { // Deinitializing the update promise this.#update = null; - // Generating the order row (can be deleted without any problems) - document.getElementById("order").textContent = - "Order: " + target.join(", "); - // Re-ordering wraps
elements by the identifiers registry - target.forEach((identifier) => { - this.#gallery.appendChild(document.getElementById(identifier)); - }); + target.forEach((identifier) => + this.#gallery.appendChild(document.getElementById(identifier)) + ); }); // Regenerating the identifiers registry and return (success) @@ -323,6 +438,7 @@ export default class gallery { * Sort images in ascending order */ ascending() { + // Sorting this.#identifiers.sort((a, b) => a - b); } @@ -334,8 +450,9 @@ export default class gallery { */ start() { // Initializing events listeners - for (const [event, handler] of this.#events) + for (const [event, handler] of this.#events.get("system")) { this.#gallery.addEventListener(event, handler); + } } /** @@ -346,8 +463,74 @@ export default class gallery { */ stop() { // Deinitializing events listeners - for (const [event, handler] of this.#events) + for (const [event, handler] of this.#events.get("system")) { this.#gallery.removeEventListener(event, handler); + } + } + + /** + * @name Generate + * + * @description + * Create the wrap with images and buttons + * + * @param {number|string} order Number for generating identifiers + * @param {(File|string)} target The image for `srt` attribute + * + * @returns {HTMLElement} Created wrap
element with images and buttons + */ + generate(order, target) { + // Creating the wrap
element + const wrap = document.createElement("div"); + wrap.classList.add("image"); + wrap.setAttribute("id", this.prefixes.wrap + order); + wrap.setAttribute("draggable", true); + + // Creating the button