clipxjs 1.2.2 → 1.3.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/dist/clipx.min.js +2 -8
- package/package.json +1 -1
- package/src/clipx.js +208 -262
package/dist/clipx.min.js
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
https://clipx.js.org
|
|
4
|
-
Version: 1.2.0
|
|
5
|
-
Copyright (c) 2024 Mr Akshay Shinde
|
|
6
|
-
Licensed under the MIT license
|
|
7
|
-
*/
|
|
8
|
-
(function(t){function e(){this.attach=this.attach.bind(this),this.isProcessing=!1,this.disable={msg:!1,toast:!1},this.customStyles={}}e.prototype.copyText=function(t){if(navigator.clipboard)return navigator.clipboard.writeText(t);if(navigator.permissions)return navigator.permissions.query({name:"clipboard-write"}).then(function(e){if("granted"===e.state||"prompt"===e.state)return navigator.clipboard.writeText(t);throw new Error("Clipboard write permission denied.")});var e=document.createElement("textarea");return e.value=t,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e),Promise.resolve()},e.prototype.cutText=function(t,e){return this.copyText(t).then(function(){e&&(e.value="",e.textContent="")})},e.prototype.copyFromElement=function(t){var e=t.value||t.textContent;return this.copyText(e)},e.prototype.cutFromElement=function(t){var e=t.value||t.textContent;return this.cutText(e,t)},e.prototype.attach=function(t){var e=document.querySelectorAll(t);e.forEach(function(t){t.addEventListener("click",function(){if(!this.isProcessing){this.isProcessing=!0;var e,n=t.getAttribute("data-clipx-target"),o=t.getAttribute("data-clipx-text"),i=t.hasAttribute("data-clipx-cut"),s=t.getAttribute("data-clipx-msg"),a=t.hasAttribute("data-clipx-toast"),r=t.hasAttribute("data-clipx-disable-msg"),c=t.hasAttribute("data-clipx-disable-toast"),l=t.getAttribute("data-clipx-toast-position")||"bottom",p=parseInt(t.getAttribute("data-clipx-duration"),10)||1500;if(n){var d=document.querySelector(n);d&&(e=i?this.cutFromElement(d):this.copyFromElement(d))}else o&&(e=i?this.cutText(o):this.copyText(o));e&&e.then(()=>this.onSuccess(t,s,a,r,c,l,p)).catch(e=>this.onError(t,e)).finally(()=>{this.isProcessing=!1})}}.bind(this))}.bind(this))},e.prototype.onSuccess=function(t,e,n,o,i,s,a){var r=t.textContent,c=e||"Copied !",l="top"===s?"clipx-toast top":"clipx-toast bottom";if(n||o||this.disable.msg||(t.textContent=c),i||this.disable.toast)setTimeout(function(){this.disable.msg||(t.textContent=r)}.bind(this),a);else{var p=document.createElement("div");p.className=l;var d='<svg class="clipx-js-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="rgba(0,210,65,1)" fill="currentColor"><path d="M4 12C4 7.58172 7.58172 4 12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM17.4571 9.45711L16.0429 8.04289L11 13.0858L8.20711 10.2929L6.79289 11.7071L11 15.9142L17.4571 9.45711Z"></path></svg>';p.innerHTML=d+c,p.setAttribute("role","alert"),p.setAttribute("aria-live","assertive"),p.style.cssText=this.customStyles.toast||"",document.body.appendChild(p),p.style.opacity=0,setTimeout(()=>p.style.opacity=1,0),setTimeout(function(){p.style.opacity=0,setTimeout(()=>document.body.removeChild(p),500),n||o||this.disable.msg||(t.textContent=r)}.bind(this),a)}},e.prototype.onError=function(t,e){console.error("Failed to cut/copy text: ",e);var n=document.createElement("div");n.className="clipx-toast error";var o='<svg xmlns="http://www.w3.org/2000/svg" class="clipx-js-svg-icon" viewBox="0 0 24 24" width="16" height="16" fill="rgba(231,0,0,1)" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z"></path></svg>';n.innerHTML=o+"Failed to copy!",n.setAttribute("role","alert"),n.setAttribute("aria-live","assertive"),n.style.cssText=this.customStyles.toast||"",document.body.appendChild(n),setTimeout(()=>{n.style.opacity=0,setTimeout(()=>document.body.removeChild(n),500)},1500)},e.prototype.setCustomStyles=function(t){this.customStyles=t},t.clipx=e;var n=document.createElement("style");n.textContent="\n .clipx-toast {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;\n position: fixed;\n left: 50%;\n transform: translateX(-50%);\n background-color: #fff;\n color: #363636;\n padding: 8px 10px;\n border-radius: 8px;\n z-index: 9999;\n box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05);\n font-size: 14px;\n text-align: center;\n opacity: 0;\n animation: fadeIn 0.5s ease forwards;\n transition: opacity 0.5s ease;\n max-width: 90%; /* Ensure it fits well on smaller screens */\n width: auto; /* Ensure the width adjusts based on content */\n display: flex;\n align-items: center;\n gap: 5px;\n}\n\n.clipx-toast.top {\n top: 20px;\n bottom: auto;\n}\n\n.clipx-toast.bottom {\n bottom: 20px;\n}\n\n.clipx-toast.error {\n background-color: #f8d7da;\n color: #721c24;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px) translateX(-50%);\n }\n to {\n opacity: 1;\n transform: translateY(0) translateX(-50%);\n }\n}\n\n@keyframes fadeOut {\n from {\n opacity: 1;\n transform: translateY(0) translateX(-50%);\n }\n to {\n opacity: 0;\n transform: translateY(10px) translateX(-50%);\n }\n}",document.head.appendChild(n)})(this);
|
|
1
|
+
/*! ClipX JS v1.3.0 | MIT | https://clipx.js.org */
|
|
2
|
+
!function(){var t=function(){"use strict";var t="undefined"!=typeof document&&document,i="undefined"!=typeof navigator?navigator:{},o=(t,i)=>'<svg class="clipx-js-svg-icon" viewBox="0 0 24 24" width="16" height="16" fill="'+t+'" aria-hidden="true"><path fill-rule="evenodd" d="'+i+'"/></svg>',e={ok:o("#00d241","M12 2a10 10 0 100 20 10 10 0 000-20zm-1 14.4-4-4 1.4-1.4 2.6 2.6 5.6-5.6L18 9.4z"),err:o("#e70000","M12 2a10 10 0 100 20 10 10 0 000-20zm1 15h-2v-2h2zm0-4h-2V7h2z")},r=t=>t&&t.parentNode&&t.parentNode.removeChild(t),s=t=>/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName),n=t=>s(t)?t.value:t.textContent,a=(t,i,o)=>t.dispatchEvent(o?new CustomEvent(i,{bubbles:!0,detail:o}):new Event(i,{bubbles:!0})),c=(t,i)=>{s(t)?(t.value=i,a(t,"input"),a(t,"change")):t.textContent=i},p=i=>new Promise((o,e)=>{var s=t.activeElement,n=t.createElement("textarea"),a=!1;n.value=i,n.readOnly=!0,n.style.cssText="position:fixed;top:0;opacity:0",t.body.appendChild(n),n.select();try{n.setSelectionRange(0,i.length),a=t.execCommand("copy")}catch(t){}r(n),s&&s.focus&&s.focus(),a?o():e(Error("Copy failed"))}),h={trim:t=>t.trim(),uppercase:t=>t.toUpperCase(),lowercase:t=>t.toLowerCase(),capitalize:t=>t.charAt(0).toUpperCase()+t.slice(1),titlecase:t=>t.toLowerCase().replace(/(^|\s)\S/g,t=>t.toUpperCase()),collapse:t=>t.replace(/\s+/g," "),singleline:t=>t.replace(/\s*[\r\n]+\s*/g," "),striphtml:t=>t.replace(/<[^>]*>/g,"")};function l(){this.disable={msg:!1,toast:!1},this.customStyles={},this.formatters=Object.assign({},h),this._sel=[],this._fn=null,this.t={}}var u=l.prototype;return l.version="1.3.0",u.addFormatter=function(t,i){if("function"!=typeof i)throw new TypeError("Formatter must be a function");return this.formatters[String(t).toLowerCase()]=i,this},u.format=function(t,i){return t=null==t?"":String(t),(Array.isArray(i)?i:String(i||"").split(",")).forEach(i=>{i=String(i).trim().toLowerCase();var o=this.formatters[i];o?t=String(o(t)):i&&console.warn("ClipX: unknown format '"+i+"'")}),t},u.copyText=function(t){return t=null==t?"":String(t),i.clipboard&&i.clipboard.writeText?i.clipboard.writeText(t).catch(()=>p(t)):p(t)},u.cutText=function(t,i){return this.copyText(t).then(()=>{i&&c(i,"")})},u.copyFromElement=function(t,i){var o=this.format(n(t),i);return o?this.copyText(o):Promise.reject(Error("Nothing to copy."))},u.cutFromElement=function(t,i){var o=this.format(n(t),i);return o?this.cutText(o,t):Promise.reject(Error("Nothing to copy."))},u.pasteText=function(){return i.clipboard&&i.clipboard.readText?i.clipboard.readText():Promise.reject(Error("Paste is not supported here."))},u.pasteToElement=function(t,i){return this.pasteText().then(o=>(o=this.format(o,i),c(t,o),o))},u.attach=function(i){return t?(i=i||"[data-clipx-text],[data-clipx-target],[data-clipx-paste]",this._sel.indexOf(i)<0&&this._sel.push(i),this._fn||t.addEventListener("click",this._fn=t=>{var i=t.target;i&&1!=i.nodeType&&(i=i.parentElement),(i=i&&i.closest&&i.closest(this._sel.join(",")))&&this._run(i)}),this):this},u.detach=function(){return this._fn&&t.removeEventListener("click",this._fn),this._fn=null,this._sel=[],this},u._run=function(i){if(!i.__cx){var o,e,r=t=>i.getAttribute("data-clipx-"+t),s=t=>i.hasAttribute("data-clipx-"+t),n=r("format"),a=s("cut"),c="copy",p=parseInt(r("duration"),10);try{if(r("paste")){if(c="paste",!(e=t.querySelector(r("paste"))))throw Error("Paste target not found");o=this.pasteToElement(e,n)}else if(r("target")){if(!(e=t.querySelector(r("target"))))throw Error("Target not found");c=a?"cut":"copy",o=a?this.cutFromElement(e,n):this.copyFromElement(e,n)}else{if(!s("text"))throw Error("Add data-clipx-target, -text or -paste");if(!(e=this.format(r("text"),n)))throw Error("Nothing to copy.");o=this.copyText(e)}}catch(t){return this.onError(i,t)}i.__cx=1,o.then(()=>this.onSuccess(i,r("msg"),s("toast"),s("disable-msg"),s("disable-toast"),r("toast-position")||"bottom",p>0?p:1500,c),t=>this.onError(i,t)).then(()=>{i.__cx=0})}},u.onSuccess=function(t,i,o,e,r,s,n,c){i=i||("paste"==c?"Pasted!":"Copied!"),o||e||this.disable.msg||(void 0===t.__o&&(t.__o=t.innerHTML),t.textContent=i,clearTimeout(t.__t),t.__t=setTimeout(()=>{t.innerHTML=t.__o,t.__o=void 0},n)),r||this.disable.toast||this._toast(i,"ok",s,n),a(t,"clipx:success",{type:c||"copy"})},u.onError=function(t,i){console.error("ClipX:",i),this.disable.toast||this._toast(i&&"Nothing to copy."==i.message?i.message:"Failed to copy!","err","bottom",1500),a(t,"clipx:error",{error:i})},u._toast=function(i,o,s,n){if(!t.getElementById("clipx-js-styles")){var a=t.createElement("style");a.id="clipx-js-styles",a.textContent=".clipx-toast{font:14px system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;position:fixed;left:50%;transform:translateX(-50%);background:#fff;color:#363636;padding:8px 10px;border-radius:8px;z-index:9999;box-shadow:0 3px 10px rgba(0,0,0,.1),0 3px 3px rgba(0,0,0,.05);opacity:0;transition:opacity .3s;max-width:90%;display:flex;align-items:center;gap:5px;pointer-events:none}.clipx-show{opacity:1}.clipx-toast.top{top:20px}.clipx-toast.bottom{bottom:20px}.clipx-toast.error{background:#f8d7da;color:#721c24}@media(prefers-reduced-motion:reduce){.clipx-toast{transition:none}}",(t.head||t.documentElement).appendChild(a)}s="top"==s?"top":"bottom",r(this.t[s]);var c=t.createElement("div"),p=t.createElement("span");c.className="clipx-toast "+s+("err"==o?" error":""),c.setAttribute("role","err"==o?"alert":"status"),c.innerHTML=e[o],p.textContent=i,c.appendChild(p),c.style.cssText=(this.customStyles.toast||"")+";"+("err"==o&&this.customStyles.error||""),t.body.appendChild(c),this.t[s]=c,setTimeout(()=>c.classList.add("clipx-show"),10),setTimeout(()=>{c.classList.remove("clipx-show"),setTimeout(()=>{r(c),this.t[s]==c&&(this.t[s]=null)},300)},n)},u.setCustomStyles=function(t){return this.customStyles=t||{},this},l.ClipX=l,l}();"object"==typeof module&&module.exports&&(module.exports=t),"undefined"!=typeof window&&(window.clipx=window.ClipX=t)}();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clipxjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "ClipX.js is an ultra-light JavaScript library that simplifies clipboard tasks and enriches user feedback. It offers straightforward copy, cut, and paste capabilities, and built-in toast notifications that you can easily customize, providing a quick and efficient way to handle clipboard and notification needs. ——— The Smarter Clipboard Solution.",
|
|
5
5
|
"main": "src/clipx.js",
|
|
6
6
|
"scripts": {
|
package/src/clipx.js
CHANGED
|
@@ -1,283 +1,229 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
/*! ClipX JS v1.3.0 | MIT | https://clipx.js.org */
|
|
2
|
+
(function (g, f) {
|
|
3
|
+
var c = f();
|
|
4
|
+
if (typeof module == "object" && module.exports) module.exports = c;
|
|
5
|
+
if (typeof window != "undefined") window.clipx = window.ClipX = c;
|
|
6
|
+
})(this, function () {
|
|
7
|
+
"use strict";
|
|
8
|
+
var D = typeof document != "undefined" && document,
|
|
9
|
+
nav = typeof navigator != "undefined" ? navigator : {},
|
|
10
|
+
SEL = "[data-clipx-text],[data-clipx-target],[data-clipx-paste]",
|
|
11
|
+
svg = (fill, d) =>
|
|
12
|
+
'<svg class="clipx-js-svg-icon" viewBox="0 0 24 24" width="16" height="16" fill="' + fill +
|
|
13
|
+
'" aria-hidden="true"><path fill-rule="evenodd" d="' + d + '"/></svg>',
|
|
14
|
+
ICON = {
|
|
15
|
+
ok: svg("#00d241", "M12 2a10 10 0 100 20 10 10 0 000-20zm-1 14.4-4-4 1.4-1.4 2.6 2.6 5.6-5.6L18 9.4z"),
|
|
16
|
+
err: svg("#e70000", "M12 2a10 10 0 100 20 10 10 0 000-20zm1 15h-2v-2h2zm0-4h-2V7h2z"),
|
|
17
|
+
},
|
|
18
|
+
CSS =
|
|
19
|
+
".clipx-toast{font:14px system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;position:fixed;left:50%;transform:translateX(-50%);background:#fff;color:#363636;padding:8px 10px;border-radius:8px;z-index:9999;box-shadow:0 3px 10px rgba(0,0,0,.1),0 3px 3px rgba(0,0,0,.05);opacity:0;transition:opacity .3s;max-width:90%;display:flex;align-items:center;gap:5px;pointer-events:none}" +
|
|
20
|
+
".clipx-show{opacity:1}.clipx-toast.top{top:20px}.clipx-toast.bottom{bottom:20px}.clipx-toast.error{background:#f8d7da;color:#721c24}" +
|
|
21
|
+
"@media(prefers-reduced-motion:reduce){.clipx-toast{transition:none}}",
|
|
22
|
+
rm = (n) => n && n.parentNode && n.parentNode.removeChild(n),
|
|
23
|
+
isV = (e) => /^(INPUT|TEXTAREA|SELECT)$/.test(e.tagName),
|
|
24
|
+
get = (e) => (isV(e) ? e.value : e.textContent),
|
|
25
|
+
fire = (e, n, d) =>
|
|
26
|
+
e.dispatchEvent(d ? new CustomEvent(n, { bubbles: true, detail: d }) : new Event(n, { bubbles: true })),
|
|
27
|
+
set = (e, t) => {
|
|
28
|
+
if (isV(e)) {
|
|
29
|
+
e.value = t;
|
|
30
|
+
fire(e, "input");
|
|
31
|
+
fire(e, "change");
|
|
32
|
+
} else e.textContent = t;
|
|
33
|
+
},
|
|
34
|
+
legacy = (t) =>
|
|
35
|
+
new Promise((ok, no) => {
|
|
36
|
+
var a = D.activeElement, x = D.createElement("textarea"), r = false;
|
|
37
|
+
x.value = t;
|
|
38
|
+
x.readOnly = true;
|
|
39
|
+
x.style.cssText = "position:fixed;top:0;opacity:0";
|
|
40
|
+
D.body.appendChild(x);
|
|
41
|
+
x.select();
|
|
42
|
+
try {
|
|
43
|
+
x.setSelectionRange(0, t.length);
|
|
44
|
+
r = D.execCommand("copy");
|
|
45
|
+
} catch (e) {}
|
|
46
|
+
rm(x);
|
|
47
|
+
a && a.focus && a.focus();
|
|
48
|
+
r ? ok() : no(Error("Copy failed"));
|
|
49
|
+
}),
|
|
50
|
+
FMT = {
|
|
51
|
+
trim: (s) => s.trim(),
|
|
52
|
+
uppercase: (s) => s.toUpperCase(),
|
|
53
|
+
lowercase: (s) => s.toLowerCase(),
|
|
54
|
+
capitalize: (s) => s.charAt(0).toUpperCase() + s.slice(1),
|
|
55
|
+
titlecase: (s) => s.toLowerCase().replace(/(^|\s)\S/g, (c) => c.toUpperCase()),
|
|
56
|
+
collapse: (s) => s.replace(/\s+/g, " "),
|
|
57
|
+
singleline: (s) => s.replace(/\s*[\r\n]+\s*/g, " "),
|
|
58
|
+
striphtml: (s) => s.replace(/<[^>]*>/g, ""),
|
|
17
59
|
};
|
|
18
|
-
|
|
60
|
+
|
|
61
|
+
function clipx() {
|
|
62
|
+
this.disable = { msg: false, toast: false };
|
|
63
|
+
this.customStyles = {};
|
|
64
|
+
this.formatters = Object.assign({}, FMT);
|
|
65
|
+
this._sel = [];
|
|
66
|
+
this._fn = null;
|
|
67
|
+
this._t = {};
|
|
19
68
|
}
|
|
69
|
+
var P = clipx.prototype;
|
|
70
|
+
clipx.version = "1.3.0";
|
|
20
71
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return navigator.clipboard.writeText(text);
|
|
26
|
-
} else if (navigator.permissions) {
|
|
27
|
-
// Check permissions if Clipboard API is not available
|
|
28
|
-
return navigator.permissions
|
|
29
|
-
.query({ name: "clipboard-write" })
|
|
30
|
-
.then(function (permissionStatus) {
|
|
31
|
-
if (
|
|
32
|
-
permissionStatus.state === "granted" ||
|
|
33
|
-
permissionStatus.state === "prompt"
|
|
34
|
-
) {
|
|
35
|
-
return navigator.clipboard.writeText(text);
|
|
36
|
-
} else {
|
|
37
|
-
throw new Error("Clipboard write permission denied.");
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
} else {
|
|
41
|
-
// Fallback to using a temporary textarea element for older browsers
|
|
42
|
-
var textArea = document.createElement("textarea");
|
|
43
|
-
textArea.value = text;
|
|
44
|
-
document.body.appendChild(textArea);
|
|
45
|
-
textArea.select();
|
|
46
|
-
document.execCommand("copy");
|
|
47
|
-
document.body.removeChild(textArea);
|
|
48
|
-
return Promise.resolve();
|
|
49
|
-
}
|
|
72
|
+
P.addFormatter = function (n, f) {
|
|
73
|
+
if (typeof f != "function") throw new TypeError("Formatter must be a function");
|
|
74
|
+
this.formatters[String(n).toLowerCase()] = f;
|
|
75
|
+
return this;
|
|
50
76
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
77
|
+
P.format = function (t, spec) {
|
|
78
|
+
t = t == null ? "" : String(t);
|
|
79
|
+
(Array.isArray(spec) ? spec : String(spec || "").split(",")).forEach((n) => {
|
|
80
|
+
n = String(n).trim().toLowerCase();
|
|
81
|
+
var f = this.formatters[n];
|
|
82
|
+
if (f) t = String(f(t));
|
|
83
|
+
else if (n) console.warn("ClipX: unknown format '" + n + "'");
|
|
59
84
|
});
|
|
85
|
+
return t;
|
|
60
86
|
};
|
|
61
87
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
88
|
+
P.copyText = function (t) {
|
|
89
|
+
t = t == null ? "" : String(t);
|
|
90
|
+
return nav.clipboard && nav.clipboard.writeText
|
|
91
|
+
? nav.clipboard.writeText(t).catch(() => legacy(t))
|
|
92
|
+
: legacy(t);
|
|
66
93
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return this.cutText(text, element);
|
|
94
|
+
P.cutText = function (t, e) {
|
|
95
|
+
return this.copyText(t).then(() => {
|
|
96
|
+
e && set(e, "");
|
|
97
|
+
});
|
|
72
98
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
var toastPosition =
|
|
93
|
-
element.getAttribute("data-clipx-toast-position") || "bottom";
|
|
94
|
-
var contentDuration =
|
|
95
|
-
parseInt(element.getAttribute("data-clipx-duration"), 10) || 1500;
|
|
96
|
-
|
|
97
|
-
var actionPromise;
|
|
98
|
-
|
|
99
|
-
// Determine the action based on attributes
|
|
100
|
-
if (targetSelector) {
|
|
101
|
-
var targetElement = document.querySelector(targetSelector);
|
|
102
|
-
if (targetElement) {
|
|
103
|
-
actionPromise = cut
|
|
104
|
-
? this.cutFromElement(targetElement)
|
|
105
|
-
: this.copyFromElement(targetElement);
|
|
106
|
-
}
|
|
107
|
-
} else if (text) {
|
|
108
|
-
actionPromise = cut ? this.cutText(text) : this.copyText(text);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (actionPromise) {
|
|
112
|
-
actionPromise
|
|
113
|
-
.then(() =>
|
|
114
|
-
this.onSuccess(
|
|
115
|
-
element,
|
|
116
|
-
msgType,
|
|
117
|
-
toastOnly,
|
|
118
|
-
disableMsg,
|
|
119
|
-
disableToast,
|
|
120
|
-
toastPosition,
|
|
121
|
-
contentDuration
|
|
122
|
-
)
|
|
123
|
-
)
|
|
124
|
-
.catch((err) => this.onError(element, err))
|
|
125
|
-
.finally(() => {
|
|
126
|
-
this.isProcessing = false;
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}.bind(this)
|
|
130
|
-
);
|
|
131
|
-
}.bind(this)
|
|
132
|
-
);
|
|
99
|
+
P.copyFromElement = function (e, f) {
|
|
100
|
+
var t = this.format(get(e), f);
|
|
101
|
+
return t ? this.copyText(t) : Promise.reject(Error("Nothing to copy."));
|
|
102
|
+
};
|
|
103
|
+
P.cutFromElement = function (e, f) {
|
|
104
|
+
var t = this.format(get(e), f);
|
|
105
|
+
return t ? this.cutText(t, e) : Promise.reject(Error("Nothing to copy."));
|
|
106
|
+
};
|
|
107
|
+
P.pasteText = function () {
|
|
108
|
+
return nav.clipboard && nav.clipboard.readText
|
|
109
|
+
? nav.clipboard.readText()
|
|
110
|
+
: Promise.reject(Error("Paste is not supported here."));
|
|
111
|
+
};
|
|
112
|
+
P.pasteToElement = function (e, f) {
|
|
113
|
+
return this.pasteText().then((t) => {
|
|
114
|
+
t = this.format(t, f);
|
|
115
|
+
set(e, t);
|
|
116
|
+
return t;
|
|
117
|
+
});
|
|
133
118
|
};
|
|
134
119
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
toastPosition === "top" ? "clipx-toast top" : "clipx-toast bottom";
|
|
149
|
-
|
|
150
|
-
if (!toastOnly && !disableMsg && !this.disable.msg) {
|
|
151
|
-
element.textContent = customMessage; // Update element's text content
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!disableToast && !this.disable.toast) {
|
|
155
|
-
var toast = document.createElement("div");
|
|
156
|
-
toast.className = toastClass;
|
|
157
|
-
// Insert the success SVG icon along with the custom message
|
|
158
|
-
var successSVG = `<svg class="clipx-js-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="rgba(0,210,65,1)" fill="currentColor"><path d="M4 12C4 7.58172 7.58172 4 12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM17.4571 9.45711L16.0429 8.04289L11 13.0858L8.20711 10.2929L6.79289 11.7071L11 15.9142L17.4571 9.45711Z"></path></svg>`;
|
|
159
|
-
toast.innerHTML = successSVG + customMessage;
|
|
160
|
-
toast.setAttribute("role", "alert");
|
|
161
|
-
toast.setAttribute("aria-live", "assertive");
|
|
162
|
-
toast.style.cssText = this.customStyles.toast || ""; // Apply custom styles if any
|
|
163
|
-
|
|
164
|
-
document.body.appendChild(toast);
|
|
165
|
-
|
|
166
|
-
// Fade-in and fade-out animation
|
|
167
|
-
toast.style.opacity = 0;
|
|
168
|
-
setTimeout(() => (toast.style.opacity = 1), 0);
|
|
169
|
-
|
|
170
|
-
setTimeout(
|
|
171
|
-
function () {
|
|
172
|
-
toast.style.opacity = 0;
|
|
173
|
-
setTimeout(() => document.body.removeChild(toast), 500);
|
|
174
|
-
|
|
175
|
-
if (!toastOnly && !disableMsg && !this.disable.msg) {
|
|
176
|
-
element.textContent = originalText; // Restore original text content
|
|
177
|
-
}
|
|
178
|
-
}.bind(this),
|
|
179
|
-
contentDuration
|
|
180
|
-
);
|
|
181
|
-
} else {
|
|
182
|
-
setTimeout(
|
|
183
|
-
function () {
|
|
184
|
-
if (!this.disable.msg) {
|
|
185
|
-
element.textContent = originalText; // Restore original text content
|
|
186
|
-
}
|
|
187
|
-
}.bind(this),
|
|
188
|
-
contentDuration
|
|
120
|
+
P.attach = function (s) {
|
|
121
|
+
if (!D) return this;
|
|
122
|
+
s = s || SEL;
|
|
123
|
+
this._sel.indexOf(s) < 0 && this._sel.push(s);
|
|
124
|
+
this._fn ||
|
|
125
|
+
D.addEventListener(
|
|
126
|
+
"click",
|
|
127
|
+
(this._fn = (e) => {
|
|
128
|
+
var n = e.target;
|
|
129
|
+
n && n.nodeType != 1 && (n = n.parentElement);
|
|
130
|
+
n = n && n.closest && n.closest(this._sel.join(","));
|
|
131
|
+
n && this._run(n);
|
|
132
|
+
})
|
|
189
133
|
);
|
|
190
|
-
|
|
134
|
+
return this;
|
|
191
135
|
};
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
toast.className = "clipx-toast error";
|
|
198
|
-
// Insert the error SVG icon along with the error message
|
|
199
|
-
var errorSVG = `<svg xmlns="http://www.w3.org/2000/svg" class="clipx-js-svg-icon" viewBox="0 0 24 24" width="16" height="16" fill="rgba(231,0,0,1)" fill="currentColor"><path d="M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z"></path></svg>`;
|
|
200
|
-
toast.innerHTML = errorSVG + "Failed to copy!";
|
|
201
|
-
toast.setAttribute("role", "alert");
|
|
202
|
-
toast.setAttribute("aria-live", "assertive");
|
|
203
|
-
toast.style.cssText = this.customStyles.toast || "";
|
|
204
|
-
|
|
205
|
-
document.body.appendChild(toast);
|
|
206
|
-
setTimeout(() => {
|
|
207
|
-
toast.style.opacity = 0;
|
|
208
|
-
setTimeout(() => document.body.removeChild(toast), 500);
|
|
209
|
-
}, 1500);
|
|
136
|
+
P.detach = function () {
|
|
137
|
+
this._fn && D.removeEventListener("click", this._fn);
|
|
138
|
+
this._fn = null;
|
|
139
|
+
this._sel = [];
|
|
140
|
+
return this;
|
|
210
141
|
};
|
|
211
142
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
143
|
+
P._run = function (el) {
|
|
144
|
+
if (el.__cx) return;
|
|
145
|
+
var a = (n) => el.getAttribute("data-clipx-" + n),
|
|
146
|
+
h = (n) => el.hasAttribute("data-clipx-" + n),
|
|
147
|
+
fm = a("format"), cut = h("cut"), ty = "copy", p, s,
|
|
148
|
+
d = parseInt(a("duration"), 10);
|
|
149
|
+
try {
|
|
150
|
+
if (a("paste")) {
|
|
151
|
+
ty = "paste";
|
|
152
|
+
if (!(s = D.querySelector(a("paste")))) throw Error("Paste target not found");
|
|
153
|
+
p = this.pasteToElement(s, fm);
|
|
154
|
+
} else if (a("target")) {
|
|
155
|
+
if (!(s = D.querySelector(a("target")))) throw Error("Target not found");
|
|
156
|
+
ty = cut ? "cut" : "copy";
|
|
157
|
+
p = cut ? this.cutFromElement(s, fm) : this.copyFromElement(s, fm);
|
|
158
|
+
} else if (h("text")) {
|
|
159
|
+
if (!(s = this.format(a("text"), fm))) throw Error("Nothing to copy.");
|
|
160
|
+
p = this.copyText(s);
|
|
161
|
+
} else throw Error("Add data-clipx-target, -text or -paste");
|
|
162
|
+
} catch (err) {
|
|
163
|
+
return this.onError(el, err);
|
|
164
|
+
}
|
|
165
|
+
el.__cx = 1;
|
|
166
|
+
p.then(
|
|
167
|
+
() => this.onSuccess(el, a("msg"), h("toast"), h("disable-msg"), h("disable-toast"), a("toast-position") || "bottom", d > 0 ? d : 1500, ty),
|
|
168
|
+
(err) => this.onError(el, err)
|
|
169
|
+
).then(() => {
|
|
170
|
+
el.__cx = 0;
|
|
171
|
+
});
|
|
215
172
|
};
|
|
216
173
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
transform: translateX(-50%);
|
|
228
|
-
background-color: #fff;
|
|
229
|
-
color: #363636;
|
|
230
|
-
padding: 8px 10px;
|
|
231
|
-
border-radius: 8px;
|
|
232
|
-
z-index: 9999;
|
|
233
|
-
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05);
|
|
234
|
-
font-size: 14px;
|
|
235
|
-
text-align: center;
|
|
236
|
-
opacity: 0;
|
|
237
|
-
animation: fadeIn 0.5s ease forwards;
|
|
238
|
-
transition: opacity 0.5s ease;
|
|
239
|
-
max-width: 90%; /* Ensure it fits well on smaller screens */
|
|
240
|
-
width: auto; /* Ensure the width adjusts based on content */
|
|
241
|
-
display: flex;
|
|
242
|
-
align-items: center;
|
|
243
|
-
gap: 5px;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
.clipx-toast.top {
|
|
247
|
-
top: 20px;
|
|
248
|
-
bottom: auto;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.clipx-toast.bottom {
|
|
252
|
-
bottom: 20px;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.clipx-toast.error {
|
|
256
|
-
background-color: #f8d7da;
|
|
257
|
-
color: #721c24;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
@keyframes fadeIn {
|
|
261
|
-
from {
|
|
262
|
-
opacity: 0;
|
|
263
|
-
transform: translateY(10px) translateX(-50%);
|
|
174
|
+
P.onSuccess = function (el, msg, only, noMsg, noToast, pos, dur, ty) {
|
|
175
|
+
msg = msg || (ty == "paste" ? "Pasted!" : "Copied!");
|
|
176
|
+
if (!only && !noMsg && !this.disable.msg) {
|
|
177
|
+
if (el.__o === undefined) el.__o = el.innerHTML;
|
|
178
|
+
el.textContent = msg;
|
|
179
|
+
clearTimeout(el.__t);
|
|
180
|
+
el.__t = setTimeout(() => {
|
|
181
|
+
el.innerHTML = el.__o;
|
|
182
|
+
el.__o = undefined;
|
|
183
|
+
}, dur);
|
|
264
184
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
185
|
+
noToast || this.disable.toast || this._toast(msg, "ok", pos, dur);
|
|
186
|
+
fire(el, "clipx:success", { type: ty || "copy" });
|
|
187
|
+
};
|
|
188
|
+
P.onError = function (el, e) {
|
|
189
|
+
console.error("ClipX:", e);
|
|
190
|
+
this.disable.toast ||
|
|
191
|
+
this._toast(e && e.message == "Nothing to copy." ? e.message : "Failed to copy!", "err", "bottom", 1500);
|
|
192
|
+
fire(el, "clipx:error", { error: e });
|
|
193
|
+
};
|
|
270
194
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
opacity: 0;
|
|
278
|
-
transform: translateY(10px) translateX(-50%);
|
|
195
|
+
P._toast = function (m, k, pos, dur) {
|
|
196
|
+
if (!D.getElementById("clipx-js-styles")) {
|
|
197
|
+
var s = D.createElement("style");
|
|
198
|
+
s.id = "clipx-js-styles";
|
|
199
|
+
s.textContent = CSS;
|
|
200
|
+
(D.head || D.documentElement).appendChild(s);
|
|
279
201
|
}
|
|
280
|
-
|
|
281
|
-
|
|
202
|
+
pos = pos == "top" ? "top" : "bottom";
|
|
203
|
+
rm(this._t[pos]);
|
|
204
|
+
var t = D.createElement("div"), l = D.createElement("span");
|
|
205
|
+
t.className = "clipx-toast " + pos + (k == "err" ? " error" : "");
|
|
206
|
+
t.setAttribute("role", k == "err" ? "alert" : "status");
|
|
207
|
+
t.innerHTML = ICON[k];
|
|
208
|
+
l.textContent = m;
|
|
209
|
+
t.appendChild(l);
|
|
210
|
+
t.style.cssText = (this.customStyles.toast || "") + ";" + (k == "err" ? this.customStyles.error || "" : "");
|
|
211
|
+
D.body.appendChild(t);
|
|
212
|
+
this._t[pos] = t;
|
|
213
|
+
setTimeout(() => t.classList.add("clipx-show"), 10);
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
t.classList.remove("clipx-show");
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
rm(t);
|
|
218
|
+
if (this._t[pos] == t) this._t[pos] = null;
|
|
219
|
+
}, 300);
|
|
220
|
+
}, dur);
|
|
221
|
+
};
|
|
282
222
|
|
|
283
|
-
|
|
223
|
+
P.setCustomStyles = function (s) {
|
|
224
|
+
this.customStyles = s || {};
|
|
225
|
+
return this;
|
|
226
|
+
};
|
|
227
|
+
clipx.ClipX = clipx;
|
|
228
|
+
return clipx;
|
|
229
|
+
});
|