Passed
Push — master ( 33081a...0dd98d )
by Paul
05:28
created

+/scripts/admin/shortcode.js   B

Complexity

Conditions 1
Paths 8

Size

Total Lines 239

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
nc 8
nop 3
dl 0
loc 239
rs 8.2857
c 1
b 0
f 0

20 Functions

Rating   Name   Duplication   Size   Complexity  
A Shortcode.destroy_ 0 7 2
A Shortcode.normalizeHide_ 0 9 4
A Shortcode.request_ 0 7 1
A Shortcode.onTrigger_ 0 14 3
A Shortcode.response_ 0 16 4
A Shortcode.normalize_ 0 11 3
A Shortcode.normalizeCount_ 0 5 3
A Shortcode.initTinymceEditor_ 0 3 1
A Shortcode.open_ 0 4 1
A Shortcode.initQuicktagsEditor_ 0 15 2
A Shortcode.onToggle_ 0 9 2
A Shortcode.responsePopup_ 0 11 1
A Shortcode.onClose_ 0 4 2
A Shortcode.normalizeId_ 0 5 2
A Shortcode.close_ 0 4 1
A Shortcode.init_ 0 7 1
A Shortcode.sendToEditor_ 0 10 4
B Shortcode.validateAttributes_ 0 15 5
A Shortcode.responseButtons_ 0 14 1
A shortcode.js ➔ Shortcode 0 19 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
			this.request_({
18
				action: 'mce-shortcode',
19
				nonce: GLSR.mce_nonce,
20
				shortcode: this.current,
21
			});
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] )) {
92
				this.attributes[key] = '';
93
			}
94
		},
95
96
		/** @return void */
97
		normalizeHide_: function( key ) {
98
			if( !GLSR.hidden_keys.hasOwnProperty( this.current ))return;
99
			var value = key.substring('hide_'.length);
100
			if( GLSR.hidden_keys[this.current].indexOf( value ) === -1 )return;
101
			if( this.attributes[key] ) {
102
				this.hiddenKeys_.push( value );
103
			}
104
			delete this.attributes[key];
105
		},
106
107
		/** @return void */
108
		normalizeId_: function( key ) {
109
			if( key === 'id' ) {
110
				this.attributes[key] = (+new Date()).toString(36);
111
			}
112
		},
113
114
		/** @return void */
115
		onClose_: function( ev ) {
116
			if( x( ev.target ).closest( x( this.el )).length )return;
117
			this.close_();
118
		},
119
120
		/** @return void */
121
		onToggle_: function( ev ) {
122
			ev.preventDefault();
123
			if( ev.target.classList.contains( 'active' )) {
124
				this.close_();
125
			}
126
			else {
127
				this.open_();
128
			}
129
		},
130
131
		/** @return void */
132
		onTrigger_: function( ev ) {
133
			ev.preventDefault();
134
			this.current = ev.target.dataset.shortcode;
135
			if( !this.current )return;
136
			if( tinymce.get( window.wpActiveEditor )) {
137
				this.initTinymceEditor_();
138
			}
139
			else {
140
				this.initQuicktagsEditor_();
141
			}
142
			setTimeout( function() {
143
				this.close_();
144
			}.bind( this ), 100 );
145
		},
146
147
		/** @return void */
148
		open_: function() {
149
			x( this.button ).addClass( 'active' );
150
			x( this.el ).find( '.glsr-mce-menu' ).show();
151
		},
152
153
		/** @return void */
154
		request_: function( request ) {
155
			var data = {
156
				action: GLSR.action,
157
				request: request,
158
			};
159
			x.post( GLSR.ajaxurl, data, this.response_.bind( this ));
160
		},
161
162
		/** @return void */
163
		response_: function( response ) {
164
			if( !response.body )return;
165
			if( response.body.length === 0 ) {
166
				window.send_to_editor( '[' + response.shortcode + ']' );
167
				this.destroy_();
168
				return;
169
			}
170
			var popup = this.responsePopup_( response );
171
			// Change the buttons if server-side validation failed
172
			if( response.ok.constructor === Array ) {
173
				popup.buttons[0].text = response.ok[0];
174
				popup.buttons[0].onclick = 'close';
175
				delete popup.buttons[1];
176
			}
177
			this.editor.windowManager.open( popup );
178
		},
179
180
		/** @return array */
181
		responseButtons_: function( response ) {
182
			return [{
183
				text: response.ok,
184
				classes: 'btn glsr-btn primary',
185
				onclick: function() {
186
					var currentWindow = this.editor.windowManager.getWindows()[0];
187
					if( !this.validateAttributes_( currentWindow ) )return;
188
					currentWindow.submit();
189
				}.bind( this ),
190
			},{
191
				text: response.close,
192
				onclick: 'close'
193
			}];
194
		},
195
196
		/** @return object */
197
		responsePopup_: function( response ) {
198
			return {
199
				title: response.title,
200
				body: response.body,
201
				classes: 'glsr-mce-popup',
202
				minWidth: 320,
203
				buttons: this.responseButtons_( response ),
204
				onsubmit: this.sendToEditor_.bind( this, response ),
205
				onclose: this.destroy_.bind( this ),
206
			};
207
		},
208
209
		/** @return void */
210
		sendToEditor_: function( response, ev ) {
211
			var attributes = '';
212
			this.normalize_( ev.data );
213
			for( var key in this.attributes ) {
214
				if( this.attributes.hasOwnProperty( key ) && this.attributes[key] !== '' ) {
215
					attributes += ' ' + key + '="' + this.attributes[key] + '"';
216
				}
217
			}
218
			window.send_to_editor( '[' + response.shortcode + attributes + ']' );
219
		},
220
221
		/** @return bool */
222
		validateAttributes_: function( currentWindow ) {
223
			var field;
224
			var is_valid = true;
225
			var requiredAttributes = GLSR.shortcodes[this.current];
226
			for( var id in requiredAttributes ) {
227
				if( !requiredAttributes.hasOwnProperty( id ))continue;
228
				field = currentWindow.find( '#' + id )[0];
229
				if( typeof field !== 'undefined' && field.state.data.value === '' ) {
230
					is_valid = false;
231
					alert( requiredAttributes[id] );
232
					break;
233
				}
234
			}
235
			return is_valid;
236
		},
237
	};
238
239
	GLSR.Shortcode = Shortcode;
240
})( window.editor, window.tinymce, jQuery );
241