Passed
Push — master ( 32d871...06bde6 )
by Paul
06:00
created

Shortcode.submitShortcode_   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
/** global: GLSR, jQuery */
2
;(function( editor, tinymce, x ) {
3
4
	'use strict';
5
6
	var Shortcode = function( selector ) {
7
		this.el = document.querySelector( selector );
8
		if( !this.el )return;
9
		this.current = null; // this.current is used by scForm to trigger the correct popup
10
		this.editor = null;
11
		this.button = this.el.querySelector( 'button' );
12
		this.menuItems = this.el.querySelectorAll( '.mce-menu-item' );
13
		if( !this.button || !this.menuItems.length )return;
14
		this.create = function( editor_id ) {
15
			this.editor = tinymce.get( editor_id );
16
			if( !this.editor )return;
17
			GLSR.Ajax.post({
18
				action: 'mce-shortcode',
19
				nonce: GLSR.mce_nonce,
20
				shortcode: this.current,
21
			}, this.response_.bind( this ));
22
		};
23
		this.init_();
24
	};
25
26
	Shortcode.prototype = {
27
		attributes_: {},
28
		hiddenKeys_: [],
29
30
		/** @return void */
31
		init_: function() {
32
			document.addEventListener( 'click', this.onClose_.bind( this ));
33
			this.button.addEventListener( 'click', this.onToggle_.bind( this ));
34
			this.menuItems.forEach( function( item ) {
35
				item.addEventListener( 'click', this.onTrigger_.bind( this ));
36
			}.bind( this ));
37
		},
38
39
		/** @return void */
40
		initTinymceEditor_: function() {
41
			tinymce.execCommand( 'GLSR_Shortcode' );
42
		},
43
44
		/** @return void */
45
		initQuicktagsEditor_: function() {
46
			if( x( '#scTemp' ).length ) {
47
				this.initTinymceEditor_();
48
				return;
49
			}
50
			x( 'body' ).append( '<textarea id="scTemp" style="display:none;"/>' );
51
			tinymce.init({
52
				elements: 'scTemp',
53
				mode: 'exact',
54
				plugins: ['glsr_shortcode', 'wplink'],
55
			});
56
			setTimeout( function() {
57
				this.initTinymceEditor_();
58
			}, 200 );
59
		},
60
61
		/** @return void */
62
		close_: function() {
63
			x( this.button ).removeClass( 'active' );
64
			x( this.el ).find( '.glsr-mce-menu' ).hide();
65
		},
66
67
		/** @return void */
68
		destroy_: function() {
69
			var tmp = x( '#scTemp' );
70
			if( tmp.length ) {
71
				tinymce.get( 'scTemp' ).remove();
72
				tmp.remove();
73
			}
74
		},
75
76
		/** @return void */
77
		normalize_: function( attributes ) {
78
			this.attributes_ = attributes;
79
			this.hiddenKeys_ = [];
80
			for( var key in attributes ) {
81
				if( !attributes.hasOwnProperty( key ))continue;
82
				this.normalizeCount_( key );
83
				this.normalizeHide_( key );
84
				this.normalizeId_( key );
85
			}
86
			this.attributes_.hide = this.hiddenKeys_.join( ',' );
87
		},
88
89
		/** @return void */
90
		normalizeCount_: function( key ) {
91
			if( key !== 'count' || x.isNumeric( this.attributes_[key] ))return;
92
			this.attributes_[key] = '';
93
		},
94
95
		/** @return void */
96
		normalizeHide_: function( key ) {
97
			if( !GLSR.hidden_keys.hasOwnProperty( this.current ))return;
98
			var value = key.substring('hide_'.length);
99
			if( GLSR.hidden_keys[this.current].indexOf( value ) === -1 )return;
100
			if( this.attributes_[key] ) {
101
				this.hiddenKeys_.push( value );
102
			}
103
			delete this.attributes_[key];
104
		},
105
106
		/** @return void */
107
		normalizeId_: function( key ) {
108
			if( key !== 'id' )return;
109
			this.attributes_[key] = (+new Date()).toString(36);
110
		},
111
112
		/** @return void */
113
		onClose_: function( ev ) {
114
			if( x( ev.target ).closest( x( this.el )).length )return;
115
			this.close_();
116
		},
117
118
		/** @return void */
119
		onToggle_: function( ev ) {
120
			ev.preventDefault();
121
			if( ev.target.classList.contains( 'active' )) {
122
				this.close_();
123
			}
124
			else {
125
				this.open_();
126
			}
127
		},
128
129
		/** @return void */
130
		onTrigger_: function( ev ) {
131
			ev.preventDefault();
132
			this.current = ev.target.dataset.shortcode;
133
			if( !this.current )return;
134
			if( tinymce.get( window.wpActiveEditor )) {
135
				this.initTinymceEditor_();
136
			}
137
			else {
138
				this.initQuicktagsEditor_();
139
			}
140
			setTimeout( function() {
141
				this.close_();
142
			}.bind( this ), 100 );
143
		},
144
145
		/** @return void */
146
		open_: function() {
147
			x( this.button ).addClass( 'active' );
148
			x( this.el ).find( '.glsr-mce-menu' ).show();
149
		},
150
151
		/** @return void */
152
		response_: function( response ) {
153
			if( !response.body )return;
154
			if( response.body.length === 0 ) {
155
				window.send_to_editor( '[' + response.shortcode + ']' );
156
				this.destroy_();
157
				return;
158
			}
159
			var popup = this.responsePopup_( response );
160
			// Change the buttons if server-side validation failed
161
			if( response.ok.constructor === Array ) {
162
				popup.buttons[0].text = response.ok[0];
163
				popup.buttons[0].onclick = 'close';
164
				delete popup.buttons[1];
165
			}
166
			this.editor.windowManager.open( popup );
167
		},
168
169
		/** @return array */
170
		responseButtons_: function( response ) {
171
			return [{
172
				classes: 'btn glsr-btn primary',
173
				onclick: this.submitShortcode_.bind( this ),
174
				text: response.ok,
175
			},{
176
				onclick: 'close',
177
				text: response.close,
178
			}];
179
		},
180
181
		/** @return object */
182
		responsePopup_: function( response ) {
183
			return {
184
				title: response.title,
185
				body: response.body,
186
				classes: 'glsr-mce-popup',
187
				minWidth: 320,
188
				buttons: this.responseButtons_( response ),
189
				onsubmit: this.sendToEditor_.bind( this, response ),
190
				onclose: this.destroy_.bind( this ),
191
			};
192
		},
193
194
		/** @return void */
195
		sendToEditor_: function( response, ev ) {
196
			var attributes = '';
197
			this.normalize_( ev.data );
198
			for( var key in this.attributes_ ) {
199
				if( this.attributes_.hasOwnProperty( key ) && this.attributes_[key] !== '' ) {
200
					attributes += ' ' + key + '="' + this.attributes_[key] + '"';
201
				}
202
			}
203
			window.send_to_editor( '[' + response.shortcode + attributes + ']' );
204
		},
205
206
		/** @return void */
207
		submitShortcode_: function() {
208
			var currentWindow = this.editor.windowManager.getWindows()[0];
209
			if( !this.validateAttributes_( currentWindow ))return;
210
			currentWindow.submit();
211
		},
212
213
		/** @return bool */
214
		validateAttributes_: function( currentWindow ) {
215
			var field;
216
			var is_valid = true;
217
			var requiredAttributes = GLSR.shortcodes[this.current];
218
			for( var id in requiredAttributes ) {
219
				if( !requiredAttributes.hasOwnProperty( id ))continue;
220
				field = currentWindow.find( '#' + id )[0];
221
				if( typeof field !== 'undefined' && field.state.data.value === '' ) {
222
					is_valid = false;
223
					alert( requiredAttributes[id] );
224
					break;
225
				}
226
			}
227
			return is_valid;
228
		},
229
	};
230
231
	GLSR.Shortcode = Shortcode;
232
})( window.editor, window.tinymce, jQuery );
233