PluginProbe
Copy Anything to Clipboard for WordPress – Copy Button, Copy Text & Copy Code / 5.5.3
Copy Anything to Clipboard for WordPress – Copy Button, Copy Text & Copy Code v5.5.3
5.5.3 3.1.0 3.2.0 3.2.1 3.3.0 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.6.0 3.7.0 3.8.0 3.8.1 3.8.2 3.8.3 4.0.0 4.0.2 4.0.3 4.0.4 4.0.5 4.1.0 4.1.1 All 78 releases
copy-the-code / assets / js / copy-the-code.js

copy-the-code.js in Copy Anything to Clipboard for WordPress – Copy Button, Copy Text & Copy Code 5.5.3, at assets/js/copy-the-code.js

526 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 window.CopyTheCodeToClipboard = (function (window, document, navigator) {
2 var textArea,
3 copy;
4
5 function isOS() {
6 return navigator.userAgent.match( /ipad|iphone/i );
7 }
8
9 function createTextArea(text) {
10 textArea = document.createElement( 'textArea' );
11 textArea.value = text;
12 document.body.appendChild( textArea );
13 }
14
15 function selectText() {
16 var range,
17 selection;
18
19 if (isOS()) {
20 range = document.createRange();
21 range.selectNodeContents( textArea );
22 selection = window.getSelection();
23 selection.removeAllRanges();
24 selection.addRange( range );
25 textArea.setSelectionRange( 0, 999999 );
26 } else {
27 textArea.select();
28 }
29 }
30
31 function copyToClipboard() {
32 document.execCommand( 'copy' );
33 document.body.removeChild( textArea );
34
35 // Redirect to page.
36 if ( copyTheCode.redirect_url ) {
37 window.location.href = copyTheCode.redirect_url;
38 }
39 }
40
41 copy = function (text) {
42 createTextArea( text );
43 selectText();
44 copyToClipboard();
45 };
46
47 return {
48 copy: copy
49 };
50 })( window, document, navigator );
51
52 (function ($) {
53
54 CopyTheCode = {
55
56 selector: copyTheCode.settings.selector || copyTheCode.selector || 'pre',
57 button_position: copyTheCode.settings['button-position'] || 'inside',
58
59 /**
60 * Init
61 */
62 init: function () {
63 this._bind();
64 this._initialize();
65 },
66
67 /**
68 * Binds events
69 */
70 _bind: function () {
71 $( document ).on( 'click', '.copy-the-code-button', CopyTheCode.copyCode );
72 $( document ).on( 'click', '.copy-the-code-shortcode', CopyTheCode.copyShortcode );
73 },
74
75 /**
76 * Initialize the Button
77 */
78 _initialize: function () {
79 if ( ! $( copyTheCode.selectors ).length) {
80 return;
81 }
82
83 $( copyTheCode.selectors ).each(
84 function (index, el) {
85 var button_copy_text = el['button_copy_text'] || '';
86 var button_position = el['button_position'] || '';
87 var button_text = el['button_text'] || '';
88 var button_title = el['button_title'] || '';
89 var selector = el['selector'] || '';
90 var style = el['style'] || '';
91 var copy_format = el['copy_format'] || '';
92
93 $( selector ).each(
94 function (index, single_selector) {
95
96 var buttonMarkup = CopyTheCode._getButtonMarkup( button_title, button_text, style );
97
98 $( single_selector ).addClass( 'copy-the-code-target' );
99
100 if ('cover' !== style && 'outside' === button_position) {
101 $( single_selector ).wrap( '<span data-copy-format="' + copy_format + '" data-button-text="' + button_text + '" data-button-position="' + button_position + '" data-button-copy-text="' + button_copy_text + '" data-style="' + style + '" data-button-title="' + button_title + '" data-selector="' + selector + '" class="copy-the-code-wrap copy-the-code-style-' + style + ' copy-the-code-outside-wrap"></span>' );
102 $( single_selector ).parent().prepend( '<div class="copy-the-code-outside">' + buttonMarkup + '</div>' );
103 } else {
104 $( single_selector ).wrap( '<span data-copy-format="' + copy_format + '" data-button-text="' + button_text + '" data-button-position="' + button_position + '" data-button-copy-text="' + button_copy_text + '" data-style="' + style + '" data-button-title="' + button_title + '" data-selector="' + selector + '" class="copy-the-code-wrap copy-the-code-style-' + style + ' copy-the-code-inside-wrap"></span>' );
105 $( single_selector ).append( buttonMarkup );
106 }
107
108 switch (style) {
109 case 'svg-icon':
110 $( single_selector ).find( '.copy-the-code-button' ).html( copyTheCode.buttonSvg );
111 break;
112 case 'cover':
113 case 'button':
114 default:
115 $( single_selector ).find( '.copy-the-code-button' ).html( button_text );
116 break;
117 }
118
119 }
120 );
121 }
122 );
123
124 },
125
126 /**
127 * Get Copy Button Markup
128 */
129 _getButtonMarkup: function (button_title, button_text, style) {
130 if ('svg-icon' === style) {
131 button_text = copyTheCode.buttonSvg;
132 }
133
134 return '<button class="copy-the-code-button" data-style="' + style + '" title="' + button_title + '">' + button_text + '</button>';
135 },
136
137 format: function (html) {
138 var tab = '\t';
139 var result = '';
140 var indent = '';
141
142 html.split( />\s*</ ).forEach(
143 function (element) {
144 if (element.match( /^\/\w/ )) {
145 indent = indent.substring( tab.length );
146 }
147
148 result += indent + '<' + element + '>\r\n';
149
150 if (element.match( /^<?\w[^>]*[^\/]$/ ) && ! element.startsWith( "input" )) {
151 indent += tab;
152 }
153 }
154 );
155
156 return result.substring( 1, result.length - 3 );
157 },
158
159 /**
160 * Copy to Clipboard
161 */
162 copyShortcode: function (event) {
163 event.preventDefault();
164
165 var btn = $( this ),
166 oldText = btn.html(),
167 target = btn.attr( 'data-target' ) || '',
168 copy_content_as = btn.attr( 'data-copy-as' ) || copyTheCode.copy_content_as,
169 button_copy_text = btn.attr( 'data-button-copy-text' ) || '',
170 content = btn.attr( 'data-content' ) || '',
171 link = btn.attr( 'data-link' ) || '';
172
173 // Copy the secrate content.
174 if (content) {
175 CopyTheCodeToClipboard.copy( content );
176 // Copied!
177 btn.text( button_copy_text );
178 setTimeout(
179 function () {
180 btn.html( oldText );
181
182 if ( link ) {
183 window.open( link, '_blank' ).focus()
184 }
185 },
186 1000
187 );
188 return;
189 }
190
191 var source = $( target );
192
193 if ( ! source.length) {
194 btn.text( 'Not found!' );
195 setTimeout(
196 function () {
197 btn.text( oldText );
198 },
199 1000
200 );
201 return;
202 }
203
204 var html = source.html();
205
206 html = CopyTheCode.format( html );
207
208 if ('html' !== copy_content_as) {
209
210 // Convert the <br/> tags into new line.
211 var brRegex = /<br\s*[\/]?>/gi;
212 html = html.replace( brRegex, "\n" );
213
214 // Convert the <div> tags into new line.
215 var divRegex = /<div\s*[\/]?>/gi;
216 html = html.replace( divRegex, "\n" );
217
218 // Convert the <p> tags into new line.
219 var pRegex = /<p\s*[\/]?>/gi;
220 html = html.replace( pRegex, "\n" );
221
222 // Convert the <li> tags into new line.
223 var pRegex = /<li\s*[\/]?>/gi;
224 html = html.replace( pRegex, "\n" );
225
226 // Remove all tags.
227 html = html.replace( /(<([^>]+)>)/ig, '' );
228 }
229
230 if ('html' !== copy_content_as) {
231 html = html.replace( /[\t\n]+/gm, ' ' ).trim();
232 } else {
233 var reWhiteSpace = new RegExp( "/^\s+$/" );
234 html = html.replace( reWhiteSpace, "" );
235 }
236
237 var tempElement = $( "<div id='temp-element'></div>" );
238 $( "body" ).append( tempElement );
239 html = $.trim( html );
240 $( '#temp-element' ).html( html );
241 var html = $( '#temp-element' ).html();
242 $( '#temp-element' ).remove();
243
244 var tempHTML = html;
245
246 // Copy the Code.
247 var tempPre = $( "<textarea id='temp-pre'>" ),
248 temp = $( "<textarea>" );
249
250 // Append temporary elements to DOM.
251 $( "body" ).append( temp );
252 $( "body" ).append( tempPre );
253
254 // Set temporary HTML markup.
255 tempPre.html( tempHTML );
256
257 var content = tempPre.text();
258
259 content = content.trim();
260
261 if ( copyTheCode.trim_lines ) {
262 content = content.replace( /^(?=\n)$|\s*$|\n\n+/gm,"" );
263 if ( content ) {
264 content = content.split( '\n' );
265 content = content.map(
266 item => {
267 return item.trim();
268 }
269 );
270 content = content.join( '\n' );
271 }
272 }
273
274 // Format the HTML markup.
275 temp.val( content ).select();
276
277 // Support for IOS devices too.
278 CopyTheCodeToClipboard.copy( content.trim() );
279
280 // Remove temporary elements.
281 temp.remove();
282 tempPre.remove();
283
284 // Copied!
285 btn.text( button_copy_text );
286 setTimeout(
287 function () {
288 btn.text( oldText );
289 },
290 1000
291 );
292 },
293
294 /**
295 * Copy to Clipboard
296 */
297 copyCode: function (event) {
298 event.preventDefault();
299
300 var btn = $( this ),
301 oldText = btn.text(),
302 parent = btn.parents( '.copy-the-code-wrap' ),
303 selector = parent.attr( 'data-selector' ) || '',
304 button_text = parent.attr( 'data-button-text' ) || '',
305 button_position = parent.attr( 'data-button-position' ) || '',
306 button_copy_text = parent.attr( 'data-button-copy-text' ) || '',
307 button_title = parent.attr( 'data-button-title' ) || '',
308 style = parent.attr( 'data-style' ) || ''
309 copy_format = parent.attr( 'data-copy-format' ) || '';
310
311 // Fix: nested selectors e.g. `.entry-content pre`
312 if (selector.indexOf( ' ' ) >= 0) {
313 var source = btn.parents( '.copy-the-code-wrap' );
314 } else {
315 var source = btn.parents( '.copy-the-code-wrap' ).find( selector );
316 }
317
318 if ( 'google-docs' === copy_format ) {
319 // Hide button temporary.
320 if ( 'inside' === button_position ) {
321 $( '.copy-the-code-button' ).hide();
322 }
323
324 var range = document.createRange();
325 range.selectNode( source[0] );
326 var selection = window.getSelection();
327 selection.removeAllRanges();
328 selection.addRange( range );
329
330 // Get selected text content
331 var selectedText = selection.toString() || source[0].textContent || '';
332
333 // Use modern Clipboard API (iOS 26+ compatible)
334 if ( navigator.clipboard && navigator.clipboard.writeText ) {
335 navigator.clipboard.writeText( selectedText ).then(
336 function() {
337 // Clear selection.
338 if (window.getSelection) {
339 if (window.getSelection().empty) { // Chrome
340 window.getSelection().empty();
341 } else if (window.getSelection().removeAllRanges) { // Firefox
342 window.getSelection().removeAllRanges();
343 }
344 } else if (document.selection) { // IE?
345 document.selection.empty();
346 }
347
348 // Show button again.
349 if ( 'inside' === button_position ) {
350 $( '.copy-the-code-button' ).show();
351 }
352 }
353 ).catch(
354 function() {
355 // Fallback to legacy method if Clipboard API fails
356 document.execCommand( 'copy' );
357
358 // Clear selection.
359 if (window.getSelection) {
360 if (window.getSelection().empty) { // Chrome
361 window.getSelection().empty();
362 } else if (window.getSelection().removeAllRanges) { // Firefox
363 window.getSelection().removeAllRanges();
364 }
365 } else if (document.selection) { // IE?
366 document.selection.empty();
367 }
368
369 // Show button again.
370 if ( 'inside' === button_position ) {
371 $( '.copy-the-code-button' ).show();
372 }
373 }
374 );
375 } else {
376 // Fallback for older browsers
377 document.execCommand( 'copy' );
378
379 // Clear selection.
380 if (window.getSelection) {
381 if (window.getSelection().empty) { // Chrome
382 window.getSelection().empty();
383 } else if (window.getSelection().removeAllRanges) { // Firefox
384 window.getSelection().removeAllRanges();
385 }
386 } else if (document.selection) { // IE?
387 document.selection.empty();
388 }
389
390 // Show button again.
391 if ( 'inside' === button_position ) {
392 $( '.copy-the-code-button' ).show();
393 }
394 }
395
396 } else {
397
398 var html = source.html();
399
400 var buttonMarkup = CopyTheCode._getButtonMarkup( button_title, button_text, style );
401
402 // Remove the <copy> button.
403 html = html.replace( buttonMarkup, '' );
404
405 // Emojis.
406 let allEmojis = CopyTheCode._getImages( html );
407
408 if ( allEmojis ) {
409 allEmojis.map(
410 function(image) {
411 let alt = CopyTheCode._getAlt( image );
412 if ( alt ) {
413 let cleanAlt = alt[0];
414 cleanAlt = cleanAlt.replaceAll( '"', '' );
415 cleanAlt = cleanAlt.replaceAll( "'", '' );
416 cleanAlt = cleanAlt.replaceAll( 'alt=', '' );
417 html = html.replaceAll( image, cleanAlt );
418 }
419 }
420 );
421
422 }
423
424 // Remove all duplicate empty lines.
425 if ( copyTheCode.remove_spaces ) {
426 html = html.replace( /^(?=\n)$|\s*$|\n\n+/gm,"" );
427 }
428
429 if ('html' !== copyTheCode.copy_content_as) {
430 // Convert the <br/> tags into new line.
431 var brRegex = /<br\s*[\/]?>/gi;
432 html = html.replace( brRegex, "\n" );
433
434 // Convert the <div> tags into new line.
435 var divRegex = /<div\s*[\/]?>/gi;
436 html = html.replace( divRegex, "\n" );
437
438 // Convert the <p> tags into new line.
439 var pRegex = /<p\s*[\/]?>/gi;
440 html = html.replace( pRegex, "\n" );
441
442 // Convert the <li> tags into new line.
443 var pRegex = /<li\s*[\/]?>/gi;
444 html = html.replace( pRegex, "\n" );
445
446 // Remove all tags.
447 html = html.replace( /(<([^>]+)>)/ig, '' );
448 }
449
450 // Remove white spaces.
451 var reWhiteSpace = new RegExp( "/^\s+$/" );
452 html = html.replace( reWhiteSpace, "" );
453
454 var tempElement = $( "<div id='temp-element'></div>" );
455 $( "body" ).append( tempElement );
456 html = $.trim( html );
457 $( '#temp-element' ).html( html );
458 var html = $( '#temp-element' ).html();
459 $( '#temp-element' ).remove();
460
461 var tempHTML = html;
462 var reWhiteSpace = new RegExp( "/^\s+$/" );
463 tempHTML = tempHTML.replace( reWhiteSpace, "" );
464
465 // Remove button text.
466 tempHTML = tempHTML.replace( button_text, '' );
467
468 // Copy the Code.
469 var tempPre = $( "<textarea id='temp-pre'>" ),
470 temp = $( "<textarea>" );
471
472 // Append temporary elements to DOM.
473 $( "body" ).append( temp );
474 $( "body" ).append( tempPre );
475
476 // Set temporary HTML markup.
477 var content = tempPre.html( tempHTML ).text();
478
479 content = $.trim( content );
480
481 // Format the HTML markup.
482 temp.val( content ).select();
483
484 // Support for IOS devices too.
485 CopyTheCodeToClipboard.copy( content );
486
487 // Remove temporary elements.
488 temp.remove();
489 tempPre.remove();
490 }
491
492 // Copied!
493 btn.text( button_copy_text );
494 setTimeout(
495 function () {
496 if ('svg-icon' === style) {
497 btn.html( copyTheCode.buttonSvg );
498 } else {
499 btn.text( oldText );
500 }
501 },
502 1000
503 );
504 },
505
506 _getImages( content ) {
507 return content.match( /<img\s+[^>]*?src=("|')([^"']+)">/gi );
508 },
509
510 _getAlt( img ) {
511 return img.match( /alt=("|')([^"']+)"|'/gi );
512 }
513
514 };
515
516 /**
517 * Initialization
518 */
519 $(
520 function () {
521 CopyTheCode.init();
522 }
523 );
524
525 })( jQuery );
526