PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 5.8.5
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v5.8.5
6.0.3 6.0.2 6.0.1 6.0.0 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.7.9.2 5.7.9.1 5.7.8 5.7.9 5.7.6 5.7.7 5.7.5 5.7.4 5.7.3 5.7.2 5.7.1 trunk 5.6.0 5.6.1 All 34 releases
automatorwp / assets / js / automatorwp-admin-functions.js

automatorwp-admin-functions.js in AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI 5.8.5, at assets/js/automatorwp-admin-functions.js

1,007 lines 27.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Helper function to initialize select2 on fields
3 *
4 * @since 1.0.0
5 *
6 * @param {Object} $this
7 */
8 function automatorwp_selector( $this ) {
9
10 // Prevent load select2 on widgets lists
11 if( $this.closest('#available-widgets').length ) {
12 return;
13 }
14
15 var select2_args = {
16 theme: 'default automatorwp-select2',
17 placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.selector_placeholder ),
18 allowClear: true,
19 multiple: ( $this[0].hasAttribute('multiple') ),
20 matcher: automatorwp_select2_words_matcher,
21 };
22
23 $this.automatorwp_select2( select2_args );
24
25 }
26
27 /**
28 * Helper function to initialize select2 post selector on fields
29 *
30 * @since 1.0.0
31 *
32 * @param {Object} $this
33 */
34 function automatorwp_post_selector( $this ) {
35
36 // Prevent load select2 on widgets lists
37 if( $this.closest('#available-widgets').length ) {
38 return;
39 }
40
41 var post_types = $this.data('post-type').split(',');
42
43 var select2_args = {
44 ajax: {
45 url: ajaxurl,
46 dataType: 'json',
47 delay: 250,
48 type: 'POST',
49 data: function( params ) {
50 return {
51 q: params.term,
52 page: params.page || 1,
53 action: 'automatorwp_get_posts',
54 nonce: automatorwp_admin_functions.nonce,
55 post_type: post_types,
56 post_type_cb: $this.data('post-type-cb'),
57 option_none: $this.data('option-none'),
58 option_none_value: $this.data('option-none-value'),
59 option_none_label: $this.data('option-none-label'),
60 option_custom: $this.data('option-custom'),
61 option_custom_value: $this.data('option-custom-value'),
62 option_custom_label: $this.data('option-custom-label'),
63 };
64 },
65 processResults: automatorwp_select2_posts_process_results
66 },
67 escapeMarkup: function ( markup ) { return markup; },
68 templateResult: ( post_types.length === 1 ? automatorwp_select2_posts_template_result : automatorwp_select2_post_types_template_result ),
69 theme: 'default automatorwp-select2',
70 placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.post_selector_placeholder ),
71 allowClear: true,
72 multiple: ( $this[0].hasAttribute('multiple') ),
73 matcher: automatorwp_select2_words_matcher,
74 };
75
76 $this.automatorwp_select2( select2_args );
77
78 }
79
80 /**
81 * Helper function to initialize select2 term selector on fields
82 *
83 * @since 1.0.0
84 *
85 * @param {Object} $this
86 */
87 function automatorwp_term_selector( $this ) {
88
89 // Prevent load select2 on widgets lists
90 if( $this.closest('#available-widgets').length ) {
91 return;
92 }
93
94 var select2_args = {
95 ajax: {
96 url: ajaxurl,
97 dataType: 'json',
98 delay: 250,
99 type: 'POST',
100 data: function( params ) {
101 return {
102 q: params.term,
103 page: params.page || 1,
104 action: 'automatorwp_get_terms',
105 nonce: automatorwp_admin_functions.nonce,
106 taxonomy: $this.data('taxonomy'),
107 option_none: $this.data('option-none'),
108 option_none_value: $this.data('option-none-value'),
109 option_none_label: $this.data('option-none-label'),
110 option_custom: $this.data('option-custom'),
111 option_custom_value: $this.data('option-custom-value'),
112 option_custom_label: $this.data('option-custom-label'),
113 };
114 },
115 processResults: automatorwp_select2_terms_process_results
116 },
117 escapeMarkup: function ( markup ) { return markup; },
118 templateResult: automatorwp_select2_terms_template_result,
119 theme: 'default automatorwp-select2',
120 placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.term_selector_placeholder ),
121 allowClear: true,
122 multiple: ( $this[0].hasAttribute('multiple') ),
123 matcher: automatorwp_select2_words_matcher,
124 };
125
126 $this.automatorwp_select2( select2_args );
127
128 }
129
130 /**
131 * Helper function to initialize select2 user selector on fields
132 *
133 * @since 1.0.0
134 *
135 * @param {Object} $this
136 */
137 function automatorwp_user_selector( $this ) {
138
139 // Prevent load select2 on widgets lists
140 if( $this.closest('#available-widgets').length ) {
141 return;
142 }
143
144 var select2_args = {
145 ajax: {
146 url: ajaxurl,
147 dataType: 'json',
148 delay: 250,
149 type: 'POST',
150 data: function( params ) {
151 return {
152 q: params.term,
153 page: params.page || 1,
154 action: 'automatorwp_get_users',
155 nonce: automatorwp_admin_functions.nonce,
156 };
157 },
158 processResults: automatorwp_select2_users_process_results
159 },
160 escapeMarkup: function ( markup ) { return markup; },
161 templateResult: automatorwp_select2_users_template_result,
162 theme: 'default automatorwp-select2',
163 placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.user_selector_placeholder ),
164 allowClear: true,
165 multiple: ( $this[0].hasAttribute('multiple') ),
166 matcher: automatorwp_select2_words_matcher,
167 };
168
169 $this.automatorwp_select2( select2_args );
170
171 }
172
173 /**
174 * Helper function to initialize select2 object selector on fields
175 *
176 * @since 1.0.0
177 *
178 * @param {Object} $this
179 */
180 function automatorwp_object_selector( $this ) {
181
182 // Prevent load select2 on widgets lists
183 if( $this.closest('#available-widgets').length ) {
184 return;
185 }
186
187 var select2_args = {
188 ajax: {
189 url: ajaxurl,
190 dataType: 'json',
191 delay: 250,
192 type: 'POST',
193 data: function( params ) {
194 return {
195 q: params.term,
196 page: params.page || 1,
197 action: 'automatorwp_get_objects',
198 nonce: automatorwp_admin_functions.nonce,
199 table: $this.data('table'),
200 option_none: $this.data('option-none'),
201 option_none_value: $this.data('option-none-value'),
202 option_none_label: $this.data('option-none-label'),
203 option_custom: $this.data('option-custom'),
204 option_custom_value: $this.data('option-custom-value'),
205 option_custom_label: $this.data('option-custom-label'),
206 };
207 },
208 processResults: automatorwp_select2_objects_process_results
209 },
210 escapeMarkup: function ( markup ) { return markup; },
211 templateResult: automatorwp_select2_objects_template_result,
212 theme: 'default automatorwp-select2',
213 placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : automatorwp_admin_functions.object_selector_placeholder ),
214 allowClear: true,
215 multiple: ( $this[0].hasAttribute('multiple') ),
216 matcher: automatorwp_select2_words_matcher,
217 };
218
219 $this.automatorwp_select2( select2_args );
220
221 }
222
223 /**
224 * Helper function to initialize select2 ajax selector on fields
225 *
226 * @since 1.0.0
227 *
228 * @param {Object} $this
229 */
230 function automatorwp_ajax_selector( $this ) {
231
232 // Prevent load select2 on widgets lists
233 if( $this.closest('#available-widgets').length ) {
234 return;
235 }
236
237 var select2_args = {
238 ajax: {
239 url: ajaxurl,
240 dataType: 'json',
241 delay: 250,
242 type: 'POST',
243 data: function( params ) {
244
245 var data = {
246 q: params.term,
247 page: params.page || 1,
248 action: $this.data('action'),
249 nonce: automatorwp_admin_functions.nonce,
250 table: $this.data('table'),
251 option_none: $this.data('option-none'),
252 option_none_value: $this.data('option-none-value'),
253 option_none_label: $this.data('option-none-label'),
254 option_custom: $this.data('option-custom'),
255 option_custom_value: $this.data('option-custom-value'),
256 option_custom_label: $this.data('option-custom-label'),
257 };
258
259 /**
260 * Allow external functions to add their own data
261 *
262 * @since 1.0.0
263 *
264 * @param Object data
265 * @param Node element
266 */
267 $this.trigger( 'automatorwp_ajax_selector_data', [ data, $this ] );
268
269 return data;
270 },
271 processResults: automatorwp_select2_ajax_process_results
272 },
273 escapeMarkup: function ( markup ) { return markup; },
274 templateResult: automatorwp_select2_ajax_template_result,
275 theme: 'default automatorwp-select2',
276 placeholder: ( $this.data('placeholder') ? $this.data('placeholder') : '' ),
277 allowClear: true,
278 multiple: ( $this[0].hasAttribute('multiple') ),
279 matcher: automatorwp_select2_words_matcher,
280 };
281
282 $this.automatorwp_select2( select2_args );
283
284 }
285
286 /**
287 * Custom formatting for posts on select2
288 *
289 * @since 1.0.0
290 *
291 * @param {Object} item
292 *
293 * @return {string}
294 */
295 function automatorwp_select2_posts_template_result( item ) {
296
297 if( item.post_title !== undefined ) {
298 return item.post_title + ( ! isNaN( item.ID ) ? '<span class="result-description align-right">ID: ' + item.ID + '</span>': '' );
299 }
300
301 return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
302
303 }
304
305 /**
306 * Custom formatting for posts on select2 with multiples post types
307 *
308 * @since 1.0.0
309 *
310 * @param {Object} item
311 *
312 * @return {string}
313 */
314 function automatorwp_select2_post_types_template_result( item ) {
315
316 if( item.post_type !== undefined ) {
317
318 var post_type_label = item.post_type;
319
320 if( automatorwp_post_type_exists( item.post_type ) ) {
321 post_type_label = automatorwp_get_post_type_label( item.post_type );
322 }
323
324 return item.post_title
325 + '<span class="result-description">'
326 + post_type_label + '<span class="align-right">' + 'ID: ' + item.ID + '</span>'
327 + '</span>';
328 }
329
330 // Fallback oon posts template result
331 return automatorwp_select2_posts_template_result( item );
332
333 }
334
335 /**
336 * Custom formatting for terms on select2
337 *
338 * @since 1.0.0
339 *
340 * @param {Object} item
341 *
342 * @return {string}
343 */
344 function automatorwp_select2_terms_template_result( item ) {
345
346 if( item.name !== undefined ) {
347 return item.name + ( ! isNaN( item.term_id ) ? '<span class="result-description align-right">ID: ' + item.term_id + '</span>': '' );
348 }
349
350 return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
351
352 }
353
354 /**
355 * Custom results processing for posts on select2
356 *
357 * @since 1.0.0
358 *
359 * @param {Object} response
360 * @param {Object} params
361 *
362 * @return {string}
363 */
364 function automatorwp_select2_posts_process_results( response, params ) {
365
366 if( response === null ) {
367 return { results: [] };
368 }
369
370 var formatted_results = [];
371
372 // Paginated responses will come with results and more_results keys
373 var results = ( response.data.results !== undefined ? response.data.results : response.data );
374
375 results.forEach( function( item ) {
376
377 // Extend select2 keys (id and text) with given keys (ID, post_title and optionally post_type, site_id and site_name)
378 formatted_results.push( jQuery.extend({
379 id: item.ID,
380 //text: item.post_title + ' (ID: ' + item.ID + ')',
381 text: item.post_title,
382 }, item ) );
383
384 } );
385
386 return {
387 results: formatted_results,
388 pagination: {
389 more: ( response.data.more_results !== undefined ? response.data.more_results : false )
390 }
391 };
392
393 }
394
395 /**
396 * Custom results processing for terms on select2
397 *
398 * @since 1.0.0
399 *
400 * @param {Object} response
401 * @param {Object} params
402 *
403 * @return {string}
404 */
405 function automatorwp_select2_terms_process_results( response, params ) {
406
407 if( response === null ) {
408 return { results: [] };
409 }
410
411 var formatted_results = [];
412
413 // Paginated responses will come with results and more_results keys
414 var results = ( response.data.results !== undefined ? response.data.results : response.data );
415
416 results.forEach( function( item ) {
417
418 // Extend select2 keys (id and text) with given keys (ID, post_title and optionally post_type, site_id and site_name)
419 formatted_results.push( jQuery.extend({
420 id: item.term_id,
421 //text: item.post_title + ' (ID: ' + item.ID + ')',
422 text: item.name,
423 }, item ) );
424
425 } );
426
427 return {
428 results: formatted_results,
429 pagination: {
430 more: ( response.data.more_results !== undefined ? response.data.more_results : false )
431 }
432 };
433
434 }
435
436 /**
437 * Custom formatting for users on select2
438 *
439 * @since 1.0.0
440 *
441 * @param {Object} item
442 *
443 * @return {string}
444 */
445 function automatorwp_select2_users_template_result( item ) {
446
447 if( item.display_name !== undefined ) {
448
449 return item.display_name + ( ! isNaN( item.ID ) ? '<span class="result-description align-right">ID: ' + item.ID + '</span>': '' );
450
451 }
452
453 return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
454
455 }
456
457 /**
458 * Custom results processing for users on select2
459 *
460 * @since 1.0.0
461 *
462 * @param {Object} response
463 * @param {Object} params
464 *
465 * @return {string}
466 */
467 function automatorwp_select2_users_process_results( response, params ) {
468
469 if( response === null ) {
470 return { results: [] };
471 }
472
473 var formatted_results = [];
474
475 // Paginated responses will come with results and more_results keys
476 var results = ( response.data.results !== undefined ? response.data.results : response.data );
477
478 results.forEach( function( item ) {
479
480 // Extend select2 keys (id and text) with given keys (ID, post_title and optionally post_type)
481 formatted_results.push( jQuery.extend({
482 id: item.ID,
483 text: item.user_login,
484 //text: item.user_login + ' (#' + item.ID + ')',
485 }, item ) );
486
487 } );
488
489 return {
490 results: formatted_results,
491 pagination: {
492 more: ( response.data.more_results !== undefined ? response.data.more_results : false )
493 }
494 };
495
496 }
497
498 /**
499 * Custom formatting for objects on select2
500 *
501 * @since 1.0.0
502 *
503 * @param {Object} item
504 *
505 * @return {string}
506 */
507 function automatorwp_select2_objects_template_result( item ) {
508
509 return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
510
511 }
512
513 /**
514 * Custom results processing for objects on select2
515 *
516 * @since 1.0.0
517 *
518 * @param {Object} response
519 * @param {Object} params
520 *
521 * @return {string}
522 */
523 function automatorwp_select2_objects_process_results( response, params ) {
524
525 if( response === null ) {
526 return { results: [] };
527 }
528
529 var formatted_results = [];
530
531 // Paginated responses will come with results and more_results keys
532 var results = ( response.data.results !== undefined ? response.data.results : response.data );
533
534 results.forEach( function( item ) {
535
536 // Extend select2 keys (id and text) with given keys (id and text)
537 formatted_results.push( jQuery.extend({
538 id: item.id,
539 text: item.text,
540 }, item ) );
541
542 } );
543
544 return {
545 results: formatted_results,
546 pagination: {
547 more: ( response.data.more_results !== undefined ? response.data.more_results : false )
548 }
549 };
550
551 }
552
553 /**
554 * Custom formatting for objects on select2
555 *
556 * @since 1.0.0
557 *
558 * @param {Object} item
559 *
560 * @return {string}
561 */
562 function automatorwp_select2_ajax_template_result( item ) {
563
564 return item.text + ( ! isNaN( item.id ) ? '<span class="result-description align-right">ID: ' + item.id + '</span>': '' );
565
566 }
567
568 /**
569 * Custom results processing for objects on select2
570 *
571 * @since 1.0.0
572 *
573 * @param {Object} response
574 * @param {Object} params
575 *
576 * @return {string}
577 */
578 function automatorwp_select2_ajax_process_results( response, params ) {
579
580 if( response === null ) {
581 return { results: [] };
582 }
583
584 var formatted_results = [];
585
586 // Paginated responses will come with results and more_results keys
587 var results = ( response.data.results !== undefined ? response.data.results : response.data );
588
589 results.forEach( function( item ) {
590
591 // Extend select2 keys (id and text) with given keys (id and text)
592 formatted_results.push( jQuery.extend({
593 id: item.id,
594 text: item.text,
595 }, item ) );
596
597 } );
598
599 return {
600 results: formatted_results,
601 pagination: {
602 more: ( response.data.more_results !== undefined ? response.data.more_results : false )
603 }
604 };
605
606 }
607
608 /**
609 * Helper function to check if text has any word of a term
610 *
611 * @since 1.0.0
612 *
613 * @param {String} text
614 * @param {String} term
615 *
616 * @return {boolean}
617 */
618 function automatorwp_matches_by_word( text, term ) {
619
620 text = text.toUpperCase();
621 var words = term.toUpperCase().split(" ");
622 var found = true;
623
624 // Check if the text contains the term (separated in words)
625 for (var i =0; i < words.length; i++)
626 found = ( found && text.indexOf( words[i] ) >= 0 );
627
628 return found;
629
630 }
631
632 /**
633 * Select2 search matcher by word
634 *
635 * @since 1.0.0
636 *
637 * @param {Object} params
638 * @param {Object} data
639 *
640 * @return {mixed}
641 */
642 function automatorwp_select2_words_matcher( params, data ) {
643
644 // Always return the object if there is nothing to compare
645 if ( params.term === undefined || params.term.trim() === '' ) return data;
646
647 // Return the object if any word matches
648 if ( automatorwp_matches_by_word( data.text, params.term ) ) return data;
649
650 // If it doesn't contain the term, don't return anything
651 return null;
652
653 }
654
655 /**
656 * Custom search matcher for selects with groups on select2
657 *
658 * @since 1.0.0
659 *
660 * @param {Object} params
661 * @param {Object} data
662 *
663 * @return {mixed}
664 */
665 function automatorwp_select2_optgroup_matcher( params, data ) {
666
667 // Initialize required vars
668 data.parentText = data.parentText || '';
669
670 // Always return the object if there is nothing to compare
671 if ( params.term === undefined || params.term.trim() === '' ) return data;
672
673 // Do a recursive check for options with children
674 if ( data.children && data.children.length > 0 ) {
675
676 // Clone the data object if there are children
677 // This is required as we modify the object to remove any non-matches
678 var match = jQuery.extend( true, {}, data );
679
680 // Check each child of the option
681 for ( var c = data.children.length - 1; c >= 0; c-- ) {
682
683 var child = data.children[c];
684 child.parentText += data.parentText + " " + data.text;
685
686 var matches = automatorwp_select2_optgroup_matcher( params, child );
687
688 // If there wasn't a match, remove the object in the array
689 if (matches == null) {
690 match.children.splice( c, 1 );
691 }
692
693 }
694
695 // If any children matched, return the new object
696 if ( match.children.length > 0 ) {
697 return match;
698 }
699
700 // If there were no matching children, check just the plain object
701 return automatorwp_select2_optgroup_matcher( params, match );
702
703 }
704
705 // Check if term matches with this text or text from parent
706 if ( automatorwp_matches_by_word( ( data.parentText + ' ' + data.text ), params.term ) ) return data;
707
708 // If it doesn't contain the term, don't return anything
709 return null;
710 }
711
712 /**
713 * Check if post type has been registered
714 *
715 * @since 1.0.0
716 *
717 * @param {string} post_type
718 *
719 * @return {boolean}
720 */
721 function automatorwp_post_type_exists( post_type ) {
722 return ( automatorwp_admin_functions.post_type_labels[post_type] !== undefined )
723 }
724
725 /**
726 * Get the post type label (singular name)
727 *
728 * @since 1.0.0
729 *
730 * @param {string} post_type
731 *
732 * @return {string}
733 */
734 function automatorwp_get_post_type_label( post_type ) {
735
736 var label = '';
737
738 if( automatorwp_post_type_exists( post_type ) ) {
739 label = automatorwp_admin_functions.post_type_labels[post_type];
740 }
741
742 return label;
743 }
744
745 /**
746 * Check if taxonomy has been registered
747 *
748 * @since 1.0.0
749 *
750 * @param {string} taxonomy
751 *
752 * @return {boolean}
753 */
754 function automatorwp_taxonomy_exists( taxonomy ) {
755 return ( automatorwp_admin_functions.taxonomy_labels[taxonomy] !== undefined )
756 }
757
758 /**
759 * Get the taxonomy label (singular name)
760 *
761 * @since 1.0.0
762 *
763 * @param {string} taxonomy
764 *
765 * @return {string}
766 */
767 function automatorwp_get_taxonomy_label( taxonomy ) {
768
769 var label = '';
770
771 if( automatorwp_taxonomy_exists( taxonomy ) ) {
772 label = automatorwp_admin_functions.taxonomy_labels[taxonomy];
773 }
774
775 return label;
776 }
777
778 /**
779 * Function to turn an object or a JSON object to a CSV file and force the download (Used on import/export tools)
780 *
781 * @since 1.0.0
782 *
783 * @param {Object} data
784 * @param {string} filename
785 */
786 function automatorwp_download_csv( data, filename ) {
787
788 // Convert JSON to CSV
789 var csv = automatorwp_object_to_csv( data );
790
791 automatorwp_download_file( csv, filename, 'csv' );
792
793 }
794
795 /**
796 * Function to force the download of the given content (Used on import/export tools)
797 *
798 * @since 1.0.0
799 *
800 * @param {string} content
801 * @param {string} filename
802 * @param {string} extension
803 * @param {string} mime_type
804 * @param {string} charset
805 */
806 function automatorwp_download_file( content, filename, extension, mime_type = '', charset = '' ) {
807
808 if( mime_type === undefined || mime_type === '' )
809 mime_type = 'text/' + extension;
810
811 if( charset === undefined || charset === '' )
812 charset = 'utf-8';
813
814 // Setup the file name
815 var file = ( filename.length ? filename + '.' + extension : 'file.' + extension );
816
817 var blob = new Blob( [content], { type: mime_type + ';charset=' + charset + ';' } );
818
819 if (navigator.msSaveBlob) {
820
821 // IE 10+
822 navigator.msSaveBlob( blob, file );
823
824 } else {
825
826 var link = document.createElement("a");
827
828 // Hide the link element
829 link.style.visibility = 'hidden';
830
831 // Check if browser supports HTML5 download attribute
832 if ( link.download !== undefined ) {
833
834 // Build the URL object
835 var url = URL.createObjectURL( blob );
836
837 // Update link attributes
838 link.setAttribute( "href", url );
839 link.setAttribute( "download", file );
840
841 // Append the link element and trigger the click event
842 document.body.appendChild( link );
843
844 link.click(); // NOTE: Is not a jQuery element, so is safe to use click()
845
846 // Finally remove the link element
847 document.body.removeChild( link );
848
849 }
850 }
851
852 }
853
854 /**
855 * Format an object into a CSV line
856 *
857 * @since 1.0.0
858 *
859 * @param {Object} obj
860 *
861 * @return {string}
862 */
863 function automatorwp_object_to_csv( obj ) {
864
865 // Convert JSON to Object
866 var array = typeof obj !== 'object' ? JSON.parse( obj ) : obj;
867 var str = '';
868
869 for ( var i = 0; i < array.length; i++ ) {
870
871 var line = '';
872
873 for ( var index in array[i] ) {
874
875 // Separator
876 if ( line !== '' ) {
877 line += ',';
878 }
879
880 // Build a new line
881 line += '"' + array[i][index] + '"';
882 }
883
884 // Append the line break
885 str += line + '\r\n';
886
887 }
888
889 return str;
890
891 }
892
893 /**
894 * Insert content at caret position
895 *
896 * @since 1.0.0
897 *
898 * @param {Object} input
899 * @param {String} content
900 */
901 function automatorwp_insert_at_caret(input, content) {
902
903 input.each(function() {
904
905 if ( document.selection ) {
906 // Internet Explorer
907
908 this.focus(); // NOTE: Is not a jQuery element, so is safe to use focus()
909 var sel = document.selection.createRange();
910 sel.text = content;
911 this.focus();
912
913 } else if ( this.selectionStart || this.selectionStart == '0' ) {
914 // Firefox/Chrome/Opera
915
916 var startPos = this.selectionStart;
917 var endPos = this.selectionEnd;
918 var scrollTop = this.scrollTop;
919 this.value = this.value.substring(0, startPos) +
920 content + this.value.substring(endPos,this.value.length);
921 this.focus();
922 this.selectionStart = startPos + content.length;
923 this.selectionEnd = startPos + content.length;
924 this.scrollTop = scrollTop;
925
926 } else {
927 // If can't determine browser, only append at the end
928
929 this.value += content;
930 this.focus();
931
932 }
933 });
934
935 }
936
937 /**
938 * Set caret position at the end of the input content
939 *
940 * @since 1.0.0
941 *
942 * @param {Object} input
943 */
944 function automatorwp_set_caret_at_end( input ) {
945
946 // Get the input node
947 input = input[0];
948
949 var length = input.value.length;
950
951 // For IE Only
952 if ( document.selection ) {
953
954 // Set focus
955 input.focus(); // NOTE: Is not a jQuery element, so is safe to use focus()
956
957 // Use IE Ranges
958 var oSel = document.selection.createRange();
959
960 // Reset position to 0 & then set at end
961 oSel.moveStart('character', -length);
962 oSel.moveStart('character', length);
963 oSel.moveEnd('character', 0);
964 oSel.select();
965
966 } else if ( input.selectionStart || input.selectionStart == '0' ) {
967
968 // Firefox/Chrome
969 input.selectionStart = length;
970 input.selectionEnd = length;
971 input.focus(); // NOTE: Is not a jQuery element, so is safe to use focus()
972 }
973
974 }
975
976 /**
977 * Helper function to get a parameter from an URL
978 *
979 * @since 1.0.0
980 *
981 * @param {String} url
982 * @param {String} param
983 * @param default_value
984 *
985 * @return {String}
986 */
987 function automatorwp_get_url_param( url, param, default_value = false ) {
988
989 var results = new RegExp('[\?&]' + param + '=([^&#]*)').exec( url );
990
991 return results[1] || default_value;
992
993 }
994
995 /**
996 * Helper function to check if given URL is a valid one
997 *
998 * @since 1.0.0
999 *
1000 * @param {String} url
1001 *
1002 * @return {boolean}
1003 */
1004 function automatorwp_is_valid_url( url ) {
1005 var result = url.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,10}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
1006 return ( result !== null )
1007 }