Add clipboard utility functions for preferences page

- Create new utils.ts module with clipboard-related functions
- Implement copyToClipboard and getFromClipboard methods
- Add clipboard functionality to preferences page for hash copying and pasting
- Update app.ts and images.ts to use new clipboard utility functions
- Modify preferences.html template with new element IDs for clipboard interactions
This commit is contained in:
Gnkalk 2025-02-19 18:57:12 +03:30
parent 587ef09958
commit d0e9ba73f5
5 changed files with 147 additions and 16 deletions

View file

@ -590,6 +590,7 @@ parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "$", ()=>$);
parcelHelpers.export(exports, "$$", ()=>$$);
var _images = require("./images");
var _utils = require("./utils");
function $(selector) {
return document.querySelector(selector);
}
@ -597,13 +598,39 @@ function $$(selector) {
return document.querySelectorAll(selector);
}
(0, _images.checkImagePage)();
document.addEventListener("DOMContentLoaded", function() {});
function afterPageLoad() {
// check for preferences page
if ($("#preferences")) {
// check for preferences hash
const hashInput = $("#preferences-hash");
if (!hashInput) return;
const copyBtn = $("#copy-preferences-hash");
if (!copyBtn) return;
copyBtn.addEventListener("click", function() {
(0, _utils.copyToClipboard)(hashInput.value);
copyBtn.innerText = copyBtn.getAttribute("data-copied-text");
setTimeout(()=>{
copyBtn.innerText = copyBtn.getAttribute("data-copy-text");
}, 2000);
});
const pasteBtn = $("#paste-preferences-hash");
const pasteInput = $("#paste-preferences-hash-input");
if (!pasteBtn || !pasteInput) return;
pasteBtn.addEventListener("click", async function() {
const hash = await (0, _utils.getFromClipboard)();
pasteInput.value = hash;
});
}
}
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", afterPageLoad);
else afterPageLoad();
},{"./images":"jxVSe","@parcel/transformer-js/src/esmodule-helpers.js":"j7FRh"}],"jxVSe":[function(require,module,exports,__globalThis) {
},{"./images":"jxVSe","@parcel/transformer-js/src/esmodule-helpers.js":"j7FRh","./utils":"hKc06"}],"jxVSe":[function(require,module,exports,__globalThis) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "checkImagePage", ()=>checkImagePage);
var _app = require("./app");
var _utils = require("./utils");
function handleImageDetails(image, { imageSrc, imageTitle, imageContent, imageSource, imageFilesize, imageDownload, formatSpan, filesizeSpan, engineSpan }) {
const resultsContainer = (0, _app.$)("#results");
resultsContainer.classList.add("image-open");
@ -683,11 +710,9 @@ function setupImages(resultsContainer) {
canvas.getContext("2d").drawImage(imageSrc, 0, 0, imageSrc.width, imageSrc.height);
canvas.toBlob((blob)=>{
if (!blob) return;
navigator.clipboard.write([
new ClipboardItem({
"image/*": blob
})
]);
(0, _utils.copyToClipboard)(new ClipboardItem({
"image/*": blob
}));
});
canvas.remove();
});
@ -712,7 +737,7 @@ function checkImagePage() {
if (resultsContainer.classList.contains("image-page")) setupImages(resultsContainer);
}
},{"@parcel/transformer-js/src/esmodule-helpers.js":"j7FRh","./app":"3uyIQ"}],"j7FRh":[function(require,module,exports,__globalThis) {
},{"./app":"3uyIQ","@parcel/transformer-js/src/esmodule-helpers.js":"j7FRh","./utils":"hKc06"}],"j7FRh":[function(require,module,exports,__globalThis) {
exports.interopDefault = function(a) {
return a && a.__esModule ? a : {
default: a
@ -742,5 +767,38 @@ exports.export = function(dest, destName, get) {
});
};
},{}]},["1Y09f","3uyIQ"], "3uyIQ", "parcelRequire94c2")
},{}],"hKc06":[function(require,module,exports,__globalThis) {
var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
parcelHelpers.defineInteropFlag(exports);
parcelHelpers.export(exports, "copyToClipboard", ()=>copyToClipboard);
parcelHelpers.export(exports, "getFromClipboard", ()=>getFromClipboard);
function copyToClipboard(item) {
if (navigator.clipboard) {
if (item instanceof ClipboardItem) navigator.clipboard.write([
item
]);
else navigator.clipboard.writeText(item);
return;
}
if (typeof item !== "string") return;
const textarea = document.createElement("textarea");
textarea.value = item;
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
}
async function getFromClipboard() {
if (navigator.clipboard) try {
const text = await navigator.clipboard.readText();
return text;
} catch (e) {
console.error(e);
return "";
}
alert("Clipboard not supported");
return "";
}
},{"@parcel/transformer-js/src/esmodule-helpers.js":"j7FRh"}]},["1Y09f","3uyIQ"], "3uyIQ", "parcelRequire94c2")

View file

@ -1,4 +1,5 @@
import { checkImagePage } from "./images";
import { copyToClipboard, getFromClipboard } from "./utils";
export function $(selector: string) {
return document.querySelector(selector);
@ -10,4 +11,39 @@ export function $$(selector: string) {
checkImagePage();
document.addEventListener("DOMContentLoaded", function () {});
function afterPageLoad() {
// check for preferences page
if ($("#preferences")) {
// check for preferences hash
const hashInput = $("#preferences-hash") as HTMLInputElement;
if (!hashInput) return;
const copyBtn = $("#copy-preferences-hash") as HTMLButtonElement;
if (!copyBtn) return;
copyBtn.addEventListener("click", function () {
copyToClipboard(hashInput.value);
copyBtn.innerText = copyBtn.getAttribute(
"data-copied-text"
) as string;
setTimeout(() => {
copyBtn.innerText = copyBtn.getAttribute(
"data-copy-text"
) as string;
}, 2000);
});
const pasteBtn = $("#paste-preferences-hash") as HTMLButtonElement;
const pasteInput = $(
"#paste-preferences-hash-input"
) as HTMLInputElement;
if (!pasteBtn || !pasteInput) return;
pasteBtn.addEventListener("click", async function () {
const hash = await getFromClipboard();
pasteInput.value = hash;
});
}
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", afterPageLoad);
} else {
afterPageLoad();
}

View file

@ -1,4 +1,5 @@
import { $, $$ } from "./app";
import { copyToClipboard } from "./utils";
interface ImageDetails {
imageSrc: HTMLImageElement;
@ -143,7 +144,7 @@ function setupImages(resultsContainer: HTMLElement) {
);
canvas.toBlob((blob) => {
if (!blob) return;
navigator.clipboard.write([new ClipboardItem({ "image/*": blob })]);
copyToClipboard(new ClipboardItem({ "image/*": blob }));
});
void canvas.remove();
});

View file

@ -0,0 +1,33 @@
export function copyToClipboard(item: ClipboardItem | string) {
if (navigator.clipboard) {
if (item instanceof ClipboardItem) {
navigator.clipboard.write([item]);
} else {
navigator.clipboard.writeText(item);
}
return;
}
if (typeof item !== "string") return;
const textarea = document.createElement("textarea");
textarea.value = item;
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
}
export async function getFromClipboard(): Promise<string> {
if (navigator.clipboard) {
try {
const text = await navigator.clipboard.readText();
return text;
} catch (e) {
console.error(e);
return "";
}
}
alert("Clipboard not supported");
return "";
}

View file

@ -76,14 +76,17 @@
<div class="sidebyside">
<input
type="text"
id="preferences-hash"
readonly
value="{{- preferences_url_params|e }}"
/>
<button
id="copy-hash"
id="copy-preferences-hash"
class="btn primary"
type="button"
data-hash="{{- preferences_url_params|e -}}"
data-copied-text="{{- _('Copied') -}}"
data-copied-text="{{- _('Copied') -}}!"
data-copy-text="{{- _('Copy') -}}"
>
{{- _('Copy') -}}
</button>
@ -104,14 +107,14 @@
<div class="sidebyside">
<input
type="text"
id="pref-hash-input"
id="paste-preferences-hash-input"
name="preferences"
placeholder="{{- _('Preferences hash') -}}"
/>
<button
id="paste-hash"
id="paste-preferences-hash"
class="btn secondary"
data-copied-text="{{- _('Copied') -}}"
type="button"
>
{{- _('Paste') -}}
</button>