clipxjs 1.3.0 → 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/package.json +1 -1
- package/src/clipx.js +229 -0
- package/src/clipx.min.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clipxjs",
|
|
3
|
-
"version": "1.3.
|
|
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
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
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, ""),
|
|
59
|
+
};
|
|
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 = {};
|
|
68
|
+
}
|
|
69
|
+
var P = clipx.prototype;
|
|
70
|
+
clipx.version = "1.3.0";
|
|
71
|
+
|
|
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;
|
|
76
|
+
};
|
|
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 + "'");
|
|
84
|
+
});
|
|
85
|
+
return t;
|
|
86
|
+
};
|
|
87
|
+
|
|
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);
|
|
93
|
+
};
|
|
94
|
+
P.cutText = function (t, e) {
|
|
95
|
+
return this.copyText(t).then(() => {
|
|
96
|
+
e && set(e, "");
|
|
97
|
+
});
|
|
98
|
+
};
|
|
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
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
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
|
+
})
|
|
133
|
+
);
|
|
134
|
+
return this;
|
|
135
|
+
};
|
|
136
|
+
P.detach = function () {
|
|
137
|
+
this._fn && D.removeEventListener("click", this._fn);
|
|
138
|
+
this._fn = null;
|
|
139
|
+
this._sel = [];
|
|
140
|
+
return this;
|
|
141
|
+
};
|
|
142
|
+
|
|
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
|
+
});
|
|
172
|
+
};
|
|
173
|
+
|
|
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);
|
|
184
|
+
}
|
|
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
|
+
};
|
|
194
|
+
|
|
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);
|
|
201
|
+
}
|
|
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
|
+
};
|
|
222
|
+
|
|
223
|
+
P.setCustomStyles = function (s) {
|
|
224
|
+
this.customStyles = s || {};
|
|
225
|
+
return this;
|
|
226
|
+
};
|
|
227
|
+
clipx.ClipX = clipx;
|
|
228
|
+
return clipx;
|
|
229
|
+
});
|
package/src/clipx.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(t,e){var o=e();"object"==typeof module&&module.exports&&(module.exports=o),"undefined"!=typeof window&&(window.clipx=window.ClipX=o)})(0,function(){"use strict";function t(){this.disable={msg:!1,toast:!1},this.customStyles={},this.formatters=Object.assign({},h),this._sel=[],this._fn=null,this._t={}}var e="undefined"!=typeof document&&document,o="undefined"!=typeof navigator?navigator:{},r="[data-clipx-text],[data-clipx-target],[data-clipx-paste]",s=(t,e)=>'<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="'+e+'"/></svg>',i={ok:s("#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:s("#e70000","M12 2a10 10 0 100 20 10 10 0 000-20zm1 15h-2v-2h2zm0-4h-2V7h2z")},n=".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}}",a=t=>t&&t.parentNode&&t.parentNode.removeChild(t),c=t=>/^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName),l=t=>c(t)?t.value:t.textContent,p=(t,e,o)=>t.dispatchEvent(o?new CustomEvent(e,{bubbles:!0,detail:o}):new Event(e,{bubbles:!0})),d=(t,e)=>{c(t)?(t.value=e,p(t,"input"),p(t,"change")):t.textContent=e},u=t=>new Promise((o,r)=>{var s=e.activeElement,i=e.createElement("textarea"),n=!1;i.value=t,i.readOnly=!0,i.style.cssText="position:fixed;top:0;opacity:0",e.body.appendChild(i),i.select();try{i.setSelectionRange(0,t.length),n=e.execCommand("copy")}catch(t){}a(i),s&&s.focus&&s.focus(),n?o():r(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,"")},m=t.prototype;return t.version="1.3.0",m.addFormatter=function(t,e){if("function"!=typeof e)throw new TypeError("Formatter must be a function");return this.formatters[String(t).toLowerCase()]=e,this},m.format=function(t,e){return t=null==t?"":String(t),(Array.isArray(e)?e:String(e||"").split(",")).forEach(e=>{e=String(e).trim().toLowerCase();var o=this.formatters[e];o?t=String(o(t)):e&&console.warn("ClipX: unknown format '"+e+"'")}),t},m.copyText=function(t){return t=null==t?"":String(t),o.clipboard&&o.clipboard.writeText?o.clipboard.writeText(t).catch(()=>u(t)):u(t)},m.cutText=function(t,e){return this.copyText(t).then(()=>{e&&d(e,"")})},m.copyFromElement=function(t,e){var o=this.format(l(t),e);return o?this.copyText(o):Promise.reject(Error("Nothing to copy."))},m.cutFromElement=function(t,e){var o=this.format(l(t),e);return o?this.cutText(o,t):Promise.reject(Error("Nothing to copy."))},m.pasteText=function(){return o.clipboard&&o.clipboard.readText?o.clipboard.readText():Promise.reject(Error("Paste is not supported here."))},m.pasteToElement=function(t,e){return this.pasteText().then(o=>(o=this.format(o,e),d(t,o),o))},m.attach=function(t){return e?(t=t||r,this._sel.indexOf(t)<0&&this._sel.push(t),this._fn||e.addEventListener("click",this._fn=(t=>{var e=t.target;e&&1!=e.nodeType&&(e=e.parentElement),e=e&&e.closest&&e.closest(this._sel.join(",")),e&&this._run(e)})),this):this},m.detach=function(){return this._fn&&e.removeEventListener("click",this._fn),this._fn=null,this._sel=[],this},m._run=function(t){if(!t.__cx){var o,r,s=e=>t.getAttribute("data-clipx-"+e),i=e=>t.hasAttribute("data-clipx-"+e),n=s("format"),a=i("cut"),c="copy",l=parseInt(s("duration"),10);try{if(s("paste")){if(c="paste",!(r=e.querySelector(s("paste"))))throw Error("Paste target not found");o=this.pasteToElement(r,n)}else if(s("target")){if(!(r=e.querySelector(s("target"))))throw Error("Target not found");c=a?"cut":"copy",o=a?this.cutFromElement(r,n):this.copyFromElement(r,n)}else{if(!i("text"))throw Error("Add data-clipx-target, -text or -paste");if(!(r=this.format(s("text"),n)))throw Error("Nothing to copy.");o=this.copyText(r)}}catch(e){return this.onError(t,e)}t.__cx=1,o.then(()=>this.onSuccess(t,s("msg"),i("toast"),i("disable-msg"),i("disable-toast"),s("toast-position")||"bottom",l>0?l:1500,c),e=>this.onError(t,e)).then(()=>{t.__cx=0})}},m.onSuccess=function(t,e,o,r,s,i,n,a){e=e||("paste"==a?"Pasted!":"Copied!"),o||r||this.disable.msg||(void 0===t.__o&&(t.__o=t.innerHTML),t.textContent=e,clearTimeout(t.__t),t.__t=setTimeout(()=>{t.innerHTML=t.__o,t.__o=void 0},n)),s||this.disable.toast||this._toast(e,"ok",i,n),p(t,"clipx:success",{type:a||"copy"})},m.onError=function(t,e){console.error("ClipX:",e),this.disable.toast||this._toast(e&&"Nothing to copy."==e.message?e.message:"Failed to copy!","err","bottom",1500),p(t,"clipx:error",{error:e})},m._toast=function(t,o,r,s){if(!e.getElementById("clipx-js-styles")){var c=e.createElement("style");c.id="clipx-js-styles",c.textContent=n,(e.head||e.documentElement).appendChild(c)}r="top"==r?"top":"bottom",a(this._t[r]);var l=e.createElement("div"),p=e.createElement("span");l.className="clipx-toast "+r+("err"==o?" error":""),l.setAttribute("role","err"==o?"alert":"status"),l.innerHTML=i[o],p.textContent=t,l.appendChild(p),l.style.cssText=(this.customStyles.toast||"")+";"+("err"==o&&this.customStyles.error||""),e.body.appendChild(l),this._t[r]=l,setTimeout(()=>l.classList.add("clipx-show"),10),setTimeout(()=>{l.classList.remove("clipx-show"),setTimeout(()=>{a(l),this._t[r]==l&&(this._t[r]=null)},300)},s)},m.setCustomStyles=function(t){return this.customStyles=t||{},this},t.ClipX=t,t});
|