clipxjs 1.2.1 → 1.2.2

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/src/clipx.js CHANGED
@@ -1,275 +1,283 @@
1
- (function (global) {
2
- // Constructor for the clipx object
3
- function clipx() {
4
- this.attach = this.attach.bind(this); // Bind the attach method to the instance
5
- this.isProcessing = false; // Flag to prevent multiple executions
6
- // Global flags to disable specific features
7
- this.disable = {
8
- msg: false,
9
- toast: false,
10
- };
11
- this.customStyles = {}; // Store custom styles for the toast notifications
12
- }
13
-
14
- // Method to copy text to clipboard
15
- clipx.prototype.copyText = function (text) {
16
- if (navigator.clipboard) {
17
- // Use the Clipboard API if available
18
- return navigator.clipboard.writeText(text);
19
- } else if (navigator.permissions) {
20
- // Check permissions if Clipboard API is not available
21
- return navigator.permissions
22
- .query({ name: "clipboard-write" })
23
- .then(function (permissionStatus) {
24
- if (
25
- permissionStatus.state === "granted" ||
26
- permissionStatus.state === "prompt"
27
- ) {
28
- return navigator.clipboard.writeText(text);
29
- } else {
30
- throw new Error("Clipboard write permission denied.");
31
- }
32
- });
33
- } else {
34
- // Fallback to using a temporary textarea element for older browsers
35
- var textArea = document.createElement("textarea");
36
- textArea.value = text;
37
- document.body.appendChild(textArea);
38
- textArea.select();
39
- document.execCommand("copy");
40
- document.body.removeChild(textArea);
41
- return Promise.resolve();
42
- }
43
- };
44
-
45
- // Method to cut (copy and then clear) text from an element
46
- clipx.prototype.cutText = function (text, element) {
47
- return this.copyText(text).then(function () {
48
- if (element) {
49
- element.value = ""; // Clear value for input elements
50
- element.textContent = ""; // Clear text content for non-input elements
51
- }
52
- });
53
- };
54
-
55
- // Method to copy text from an element
56
- clipx.prototype.copyFromElement = function (element) {
57
- var text = element.value || element.textContent; // Get text from input or non-input element
58
- return this.copyText(text);
59
- };
60
-
61
- // Method to cut (copy and then clear) text from an element
62
- clipx.prototype.cutFromElement = function (element) {
63
- var text = element.value || element.textContent; // Get text from input or non-input element
64
- return this.cutText(text, element);
65
- };
66
-
67
- // Method to attach event listeners to elements matching the selector
68
- clipx.prototype.attach = function (selector) {
69
- var elements = document.querySelectorAll(selector);
70
- elements.forEach(
71
- function (element) {
72
- element.addEventListener(
73
- "click",
74
- function () {
75
- if (this.isProcessing) return; // Prevent multiple executions
76
- this.isProcessing = true;
77
-
78
- var targetSelector = element.getAttribute("data-clipx-target");
79
- var text = element.getAttribute("data-clipx-text");
80
- var cut = element.hasAttribute("data-clipx-cut");
81
- var msgType = element.getAttribute("data-clipx-msg");
82
- var toastOnly = element.hasAttribute("data-clipx-toast");
83
- var disableMsg = element.hasAttribute("data-clipx-disable-msg");
84
- var disableToast = element.hasAttribute("data-clipx-disable-toast");
85
- var toastPosition =
86
- element.getAttribute("data-clipx-toast-position") || "bottom";
87
- var contentDuration =
88
- parseInt(element.getAttribute("data-clipx-duration"), 10) || 1500;
89
-
90
- var actionPromise;
91
-
92
- // Determine the action based on attributes
93
- if (targetSelector) {
94
- var targetElement = document.querySelector(targetSelector);
95
- if (targetElement) {
96
- actionPromise = cut
97
- ? this.cutFromElement(targetElement)
98
- : this.copyFromElement(targetElement);
99
- }
100
- } else if (text) {
101
- actionPromise = cut ? this.cutText(text) : this.copyText(text);
102
- }
103
-
104
- if (actionPromise) {
105
- actionPromise
106
- .then(() =>
107
- this.onSuccess(
108
- element,
109
- msgType,
110
- toastOnly,
111
- disableMsg,
112
- disableToast,
113
- toastPosition,
114
- contentDuration
115
- )
116
- )
117
- .catch((err) => this.onError(element, err))
118
- .finally(() => {
119
- this.isProcessing = false;
120
- });
121
- }
122
- }.bind(this)
123
- );
124
- }.bind(this)
125
- );
126
- };
127
-
128
- // Handle successful copy/cut operation
129
- clipx.prototype.onSuccess = function (
130
- element,
131
- msgType,
132
- toastOnly,
133
- disableMsg,
134
- disableToast,
135
- toastPosition,
136
- contentDuration
137
- ) {
138
- var originalText = element.textContent; // Store original text content
139
- var customMessage = msgType || "Copied !"; // Use provided message or default to "Copied!"
140
- var toastClass =
141
- toastPosition === "top" ? "clipx-toast top" : "clipx-toast bottom";
142
-
143
- if (!toastOnly && !disableMsg && !this.disable.msg) {
144
- element.textContent = customMessage; // Update element's text content
145
- }
146
-
147
- if (!disableToast && !this.disable.toast) {
148
- var toast = document.createElement("div");
149
- toast.className = toastClass;
150
- // Insert the success SVG icon along with the custom message
151
- 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>`;
152
- toast.innerHTML = successSVG + customMessage;
153
- toast.setAttribute("role", "alert");
154
- toast.setAttribute("aria-live", "assertive");
155
- toast.style.cssText = this.customStyles.toast || ""; // Apply custom styles if any
156
-
157
- document.body.appendChild(toast);
158
-
159
- // Fade-in and fade-out animation
160
- toast.style.opacity = 0;
161
- setTimeout(() => (toast.style.opacity = 1), 0);
162
-
163
- setTimeout(
164
- function () {
165
- toast.style.opacity = 0;
166
- setTimeout(() => document.body.removeChild(toast), 500);
167
-
168
- if (!toastOnly && !disableMsg && !this.disable.msg) {
169
- element.textContent = originalText; // Restore original text content
170
- }
171
- }.bind(this),
172
- contentDuration
173
- );
174
- } else {
175
- setTimeout(
176
- function () {
177
- if (!this.disable.msg) {
178
- element.textContent = originalText; // Restore original text content
179
- }
180
- }.bind(this),
181
- contentDuration
182
- );
183
- }
184
- };
185
-
186
- // Handle errors during copy/cut operation
187
- clipx.prototype.onError = function (element, err) {
188
- console.error("Failed to cut/copy text: ", err);
189
- var toast = document.createElement("div");
190
- toast.className = "clipx-toast error";
191
- // Insert the error SVG icon along with the error message
192
- 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>`;
193
- toast.innerHTML = errorSVG + "Failed to copy!";
194
- toast.setAttribute("role", "alert");
195
- toast.setAttribute("aria-live", "assertive");
196
- toast.style.cssText = this.customStyles.toast || "";
197
-
198
- document.body.appendChild(toast);
199
- setTimeout(() => {
200
- toast.style.opacity = 0;
201
- setTimeout(() => document.body.removeChild(toast), 500);
202
- }, 1500);
203
- };
204
-
205
- // Method to set custom styles for toast notifications
206
- clipx.prototype.setCustomStyles = function (styles) {
207
- this.customStyles = styles;
208
- };
209
-
210
- // Expose the clipx constructor to the global object
211
- global.clipx = clipx;
212
-
213
- // Add default styles for toast notifications
214
- var style = document.createElement("style");
215
- style.textContent = `
216
- .clipx-toast {
217
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
218
- position: fixed;
219
- left: 50%;
220
- transform: translateX(-50%);
221
- background-color: #fff;
222
- color: #363636;
223
- padding: 8px 10px;
224
- border-radius: 8px;
225
- z-index: 9999;
226
- box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1), 0 3px 3px rgba(0, 0, 0, 0.05);
227
- font-size: 14px;
228
- text-align: center;
229
- opacity: 0;
230
- animation: fadeIn 0.5s ease forwards;
231
- transition: opacity 0.5s ease;
232
- max-width: 90%; /* Ensure it fits well on smaller screens */
233
- width: auto; /* Ensure the width adjusts based on content */
234
- display: flex;
235
- align-items: center;
236
- gap: 5px;
237
- }
238
-
239
- .clipx-toast.top {
240
- top: 20px;
241
- bottom: auto;
242
- }
243
-
244
- .clipx-toast.bottom {
245
- bottom: 20px;
246
- }
247
-
248
- .clipx-toast.error {
249
- background-color: #f8d7da;
250
- color: #721c24;
251
- }
252
-
253
- @keyframes fadeIn {
254
- from {
255
- opacity: 0;
256
- transform: translateY(10px) translateX(-50%);
257
- }
258
- to {
259
- opacity: 1;
260
- transform: translateY(0) translateX(-50%);
261
- }
262
- }
263
-
264
- @keyframes fadeOut {
265
- from {
266
- opacity: 1;
267
- transform: translateY(0) translateX(-50%);
268
- }
269
- to {
270
- opacity: 0;
271
- transform: translateY(10px) translateX(-50%);
272
- }
273
- }`;
274
- document.head.appendChild(style);
275
- })(this);
1
+ /*
2
+ ClipX JS
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 (global) {
9
+ // Constructor for the clipx object
10
+ function clipx() {
11
+ this.attach = this.attach.bind(this); // Bind the attach method to the instance
12
+ this.isProcessing = false; // Flag to prevent multiple executions
13
+ // Global flags to disable specific features
14
+ this.disable = {
15
+ msg: false,
16
+ toast: false,
17
+ };
18
+ this.customStyles = {}; // Store custom styles for the toast notifications
19
+ }
20
+
21
+ // Method to copy text to clipboard
22
+ clipx.prototype.copyText = function (text) {
23
+ if (navigator.clipboard) {
24
+ // Use the Clipboard API if available
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
+ }
50
+ };
51
+
52
+ // Method to cut (copy and then clear) text from an element
53
+ clipx.prototype.cutText = function (text, element) {
54
+ return this.copyText(text).then(function () {
55
+ if (element) {
56
+ element.value = ""; // Clear value for input elements
57
+ element.textContent = ""; // Clear text content for non-input elements
58
+ }
59
+ });
60
+ };
61
+
62
+ // Method to copy text from an element
63
+ clipx.prototype.copyFromElement = function (element) {
64
+ var text = element.value || element.textContent; // Get text from input or non-input element
65
+ return this.copyText(text);
66
+ };
67
+
68
+ // Method to cut (copy and then clear) text from an element
69
+ clipx.prototype.cutFromElement = function (element) {
70
+ var text = element.value || element.textContent; // Get text from input or non-input element
71
+ return this.cutText(text, element);
72
+ };
73
+
74
+ // Method to attach event listeners to elements matching the selector
75
+ clipx.prototype.attach = function (selector) {
76
+ var elements = document.querySelectorAll(selector);
77
+ elements.forEach(
78
+ function (element) {
79
+ element.addEventListener(
80
+ "click",
81
+ function () {
82
+ if (this.isProcessing) return; // Prevent multiple executions
83
+ this.isProcessing = true;
84
+
85
+ var targetSelector = element.getAttribute("data-clipx-target");
86
+ var text = element.getAttribute("data-clipx-text");
87
+ var cut = element.hasAttribute("data-clipx-cut");
88
+ var msgType = element.getAttribute("data-clipx-msg");
89
+ var toastOnly = element.hasAttribute("data-clipx-toast");
90
+ var disableMsg = element.hasAttribute("data-clipx-disable-msg");
91
+ var disableToast = element.hasAttribute("data-clipx-disable-toast");
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
+ );
133
+ };
134
+
135
+ // Handle successful copy/cut operation
136
+ clipx.prototype.onSuccess = function (
137
+ element,
138
+ msgType,
139
+ toastOnly,
140
+ disableMsg,
141
+ disableToast,
142
+ toastPosition,
143
+ contentDuration
144
+ ) {
145
+ var originalText = element.textContent; // Store original text content
146
+ var customMessage = msgType || "Copied !"; // Use provided message or default to "Copied!"
147
+ var toastClass =
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
189
+ );
190
+ }
191
+ };
192
+
193
+ // Handle errors during copy/cut operation
194
+ clipx.prototype.onError = function (element, err) {
195
+ console.error("Failed to cut/copy text: ", err);
196
+ var toast = document.createElement("div");
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);
210
+ };
211
+
212
+ // Method to set custom styles for toast notifications
213
+ clipx.prototype.setCustomStyles = function (styles) {
214
+ this.customStyles = styles;
215
+ };
216
+
217
+ // Expose the clipx constructor to the global object
218
+ global.clipx = clipx;
219
+
220
+ // Add default styles for toast notifications
221
+ var style = document.createElement("style");
222
+ style.textContent = `
223
+ .clipx-toast {
224
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
225
+ position: fixed;
226
+ left: 50%;
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%);
264
+ }
265
+ to {
266
+ opacity: 1;
267
+ transform: translateY(0) translateX(-50%);
268
+ }
269
+ }
270
+
271
+ @keyframes fadeOut {
272
+ from {
273
+ opacity: 1;
274
+ transform: translateY(0) translateX(-50%);
275
+ }
276
+ to {
277
+ opacity: 0;
278
+ transform: translateY(10px) translateX(-50%);
279
+ }
280
+ }`;
281
+ document.head.appendChild(style);
282
+
283
+ })(this);