PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 All 196 releases
← All changes | resources/backend/js/modal.js +152 -99 2.2.03.4.3 View file →
@@ -2,130 +2,183 @@
2 2 * Handles the Insert and Cancel events on TinyMCE and QuickTag Modals
3 3 *
4 4 * @since 1.9.6
5 5 *
6 - * @package ConvertKit
7 6 * @author ConvertKit
8 7 */
9 8
10 -jQuery( document ).ready(
11 - function( $ ) {
9 +document.addEventListener('DOMContentLoaded', function () {
10 + // Cancel.
11 + document.body.addEventListener('click', function (e) {
12 + // Check if a cancel button was clicked.
13 + if (
14 + e.target.matches(
15 + '#convertkit-modal-body div.mce-cancel button, #convertkit-modal-body div.mce-cancel button *, #convertkit-quicktags-modal .media-toolbar .media-toolbar-secondary button.cancel'
16 + )
17 + ) {
18 + // TinyMCE.
19 + if (
20 + typeof tinyMCE !== 'undefined' &&
21 + tinyMCE.activeEditor &&
22 + !tinyMCE.activeEditor.isHidden()
23 + ) {
24 + tinymce.activeEditor.windowManager.close();
25 + return;
26 + }
12 27
13 - // Cancel.
14 - $( 'body' ).on(
15 - 'click',
16 - 'form.convertkit-tinymce-popup button.close',
17 - function( e ) {
28 + // Text Editor.
29 + // Close the QuickTags modal.
30 + convertKitQuickTagsModal.close();
31 + }
32 + });
18 33
19 - // TinyMCE.
20 - if ( typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() ) {
21 - tinymce.activeEditor.windowManager.close();
22 - return;
23 - }
34 + // Insert.
35 + document.body.addEventListener('click', function (e) {
36 + // Check if an insert button was clicked.
37 + if (
38 + e.target.matches(
39 + '#convertkit-modal-body div.mce-insert button, #convertkit-modal-body div.mce-insert button *, #convertkit-quicktags-modal .media-toolbar .media-toolbar-primary button.button-primary'
40 + ) ||
41 + e.target.matches(
42 + 'button.wp-convertkit-refresh-resources, span.dashicons-update'
43 + )
44 + ) {
45 + // Prevent default action.
46 + e.preventDefault();
24 47
25 - // Text Editor.
26 - convertKitQuickTagsModal.close();
27 -
48 + // Don't close the modal if the refresh button was clicked.
49 + if (
50 + e.target.matches(
51 + 'button.wp-convertkit-refresh-resources, span.dashicons-update'
52 + )
53 + ) {
54 + return;
28 55 }
29 - );
30 56
31 - // Insert.
32 - $( 'body' ).on(
33 - 'click',
34 - 'form.convertkit-tinymce-popup div.buttons input[type=button]',
35 - function( e ) {
57 + // Get containing form.
58 + const form = document.querySelector(
59 + 'form.convertkit-tinymce-popup'
60 + );
36 61
37 - // Prevent default action.
38 - e.preventDefault();
62 + // Build Shortcode.
63 + let shortcode =
64 + '[' + form.querySelector('input[name="shortcode"]').value;
65 + const shortcodeClose =
66 + form.querySelector('input[name="close_shortcode"]').value ===
67 + '1';
39 68
40 - // Get containing form.
41 - var form = $( this ).closest( 'form.convertkit-tinymce-popup' );
69 + // Iterate through form fields.
70 + form.querySelectorAll('input, select').forEach(function (element) {
71 + // Skip if no data-shortcode attribute.
72 + if (!element.dataset.shortcode) {
73 + return;
74 + }
42 75
43 - // Build Shortcode.
44 - var shortcode = '[' + $( 'input[name="shortcode"]', $( form ) ).val(),
45 - shortcodeClose = ( $( 'input[name="close_shortcode"]', $( form ) ).val() == '1' ? true : false );
76 + let val = '';
46 77
47 - $( 'input, select', $( form ) ).each(
48 - function( i ) {
49 - // Skip if no data-shortcode attribute.
50 - if ( typeof $( this ).data( 'shortcode' ) === 'undefined' ) {
51 - return true;
52 - }
78 + // If this is a color picker, #000000 will be submitted by the browser as the value
79 + // even if no value / color was selected.
80 + // Check the data-value attribute instead.
81 + switch (element.type) {
82 + case 'color':
83 + val = element.dataset.value;
84 + break;
85 + default:
86 + val = element.value;
87 + break;
88 + }
53 89
54 - // Skip if the value is empty.
55 - if ( ! $( this ).val() ) {
56 - return true;
57 - }
58 - if ( $( this ).val().length == 0 ) {
59 - return true;
60 - }
90 + // Skip if the value is empty.
91 + if (!val) {
92 + return;
93 + }
94 + if (val.length === 0) {
95 + return;
96 + }
61 97
62 - // Get shortcode attribute.
63 - var key = $( this ).data( 'shortcode' ),
64 - trim = ( $( this ).data( 'trim' ) == '0' ? false : true ),
65 - val = $( this ).val();
98 + // Get shortcode attribute.
99 + const key = element.dataset.shortcode;
100 + const trim = element.dataset.trim !== '0';
66 101
67 - // Skip if the shortcode is empty.
68 - if ( ! key.length ) {
69 - return true;
70 - }
102 + // Skip if the shortcode is empty.
103 + if (!key.length) {
104 + return;
105 + }
71 106
72 - // Trim the value, unless the shortcode attribute disables string trimming.
73 - if ( trim ) {
74 - val = val.trim();
75 - }
107 + // Trim the value, unless the shortcode attribute disables string trimming.
108 + if (trim) {
109 + val = val.trim();
110 + }
76 111
77 - // Append attribute and value to shortcode string.
78 - shortcode += ' ' + key.trim() + '="' + val + '"';
79 - }
80 - );
112 + // Append attribute and value to shortcode string.
113 + shortcode += ' ' + key.trim() + '="' + val + '"';
114 + });
81 115
82 - // Close Shortcode.
83 - shortcode += ']';
116 + // Close Shortcode.
117 + shortcode += ']';
84 118
85 - // If the shortcode includes a closing element, append it now.
86 - if ( shortcodeClose ) {
87 - shortcode += '[/' + $( 'input[name="shortcode"]', $( form ) ).val() + ']';
88 - }
119 + // If the shortcode includes a closing element, append it now.
120 + if (shortcodeClose) {
121 + shortcode +=
122 + '[/' +
123 + form.querySelector('input[name="shortcode"]').value +
124 + ']';
125 + }
89 126
90 - // Depending on the editor type, insert the shortcode.
91 - switch ( $( 'input[name="editor_type"]', $( form ) ).val() ) {
92 - case 'tinymce':
93 - // Sanity check that a Visual editor exists and is active.
94 - if ( typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() ) {
95 - // Insert into editor.
96 - tinyMCE.activeEditor.execCommand( 'mceReplaceContent', false, shortcode );
127 + // Depending on the editor type, insert the shortcode.
128 + switch (form.querySelector('input[name="editor_type"]').value) {
129 + case 'tinymce':
130 + // Sanity check that a Visual editor exists and is active.
131 + if (
132 + typeof tinyMCE !== 'undefined' &&
133 + tinyMCE.activeEditor &&
134 + !tinyMCE.activeEditor.isHidden()
135 + ) {
136 + // Insert into editor.
137 + tinyMCE.activeEditor.execCommand(
138 + 'mceReplaceContent',
139 + false,
140 + shortcode
141 + );
97 142
98 - // Close modal.
99 - tinyMCE.activeEditor.windowManager.close();
100 - }
101 - break;
143 + // Close modal.
144 + tinyMCE.activeEditor.windowManager.close();
145 + }
146 + break;
102 147
103 - case 'quicktags':
104 - // Insert into editor.
105 - QTags.insertContent( shortcode );
148 + case 'quicktags':
149 + // Insert into editor.
150 + QTags.insertContent(shortcode);
106 151
107 - // Close modal.
108 - convertKitQuickTagsModal.close();
109 - break;
110 - }
152 + // Close modal.
153 + convertKitQuickTagsModal.close();
154 + break;
111 155 }
112 - );
156 + }
157 + });
158 +});
113 159
114 - }
115 -);
160 +// QuickTags: Setup Backbone Modal and Template.
161 +if (typeof wp !== 'undefined' && typeof wp.media !== 'undefined') {
162 + // Declared globally, as used in this file and quicktags.js.
163 + // Setting this as const or let causes a JS error stating that `convertKitQuickTagsModal` is not defined globally.
164 + // eslint-disable-next-line no-var
165 + var convertKitQuickTagsModal = new wp.media.view.Modal({
166 + controller: { trigger() {} },
167 + className: 'convertkit-quicktags-modal',
168 + });
169 + const convertKitQuickTagsModalContent = wp.Backbone.View.extend({
170 + template: wp.template('convertkit-quicktags-modal'),
171 + });
172 + convertKitQuickTagsModal.content(new convertKitQuickTagsModalContent());
116 173
117 -// QuickTags: Setup Backbone Modal and Template.
118 -if ( typeof wp !== 'undefined' && typeof wp.media !== 'undefined' ) {
119 - var convertKitQuickTagsModal = new wp.media.view.Modal(
120 - {
121 - controller: { trigger: function() {} },
122 - className: 'convertkit-quicktags-modal'
123 - }
124 - );
125 - var convertKitQuickTagsModalContent = wp.Backbone.View.extend(
126 - {
127 - template: wp.template( 'convertkit-quicktags-modal' )
128 - }
129 - );
130 - convertKitQuickTagsModal.content( new convertKitQuickTagsModalContent() );
174 + /**
175 + * Resets the content of the convertKitQuickTagsModal when closing.
176 + *
177 + * If this isn't performed, switching from Text to Visual Editor for the same shortcode results
178 + * code picking up data from the QuickTags modal, not the TinyMCE one, due to this 'stale'
179 + * modal remaining in the DOM, resulting in e.g. the tabbed UI not loading correctly.
180 + */
181 + convertKitQuickTagsModal.on('close', function () {
182 + this.content(new convertKitQuickTagsModalContent());
183 + });
131 184 }