Completed
Push — release-2.1 ( 754615...c3ff7f )
by Mathias
13s
created

sceditor.formats.bbcode.set(ꞌattachꞌ).html   D

Complexity

Conditions 19
Paths 224

Size

Total Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
nc 224
nop 3
dl 0
loc 47
rs 4.082
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like sceditor.formats.bbcode.set(ꞌattachꞌ).html often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/**
2
 * Simple Machines Forum (SMF)
3
 *
4
 * @package SMF
5
 * @author Simple Machines http://www.simplemachines.org
6
 * @copyright 2018 Simple Machines and individual contributors
7
 * @license http://www.simplemachines.org/about/smf/license.php BSD
8
 *
9
 * @version 2.1 Beta 4
10
 */
11
12
(function ($) {
13
	var extensionMethods = {
14
		InsertText: function (text, bClear) {
15
			var bIsSource = this.inSourceMode();
16
17
			// @TODO make it put the quote close to the current selection
18
19
			if (!bIsSource)
20
				this.toggleSourceMode();
21
22
			var current_value = bClear ? text : this.getSourceEditorValue(false) + text;
23
			this.setSourceEditorValue(current_value);
24
25
			if (!bIsSource)
26
				this.toggleSourceMode();
27
28
		},
29
		getText: function (filter) {
30
			var current_value = '';
31
32
			if (this.inSourceMode())
33
				current_value = this.getSourceEditorValue(false);
34
			else
35
				current_value = this.getWysiwygEditorValue(filter);
36
37
			return current_value;
38
		},
39
		appendEmoticon: function (code, emoticon) {
40
			if (emoticon == '')
41
				line.append($('<br>'));
42
			else
43
				line.append($('<img>')
44
					.attr({
45
						src: emoticon,
46
						alt: code,
47
					})
48
					.click(function (e) {
49
						var	start = '', end = '';
50
51
						if (base.opts.emoticonsCompat)
52
						{
53
							start = '<span> ';
54
							end = ' </span>';
55
						}
56
57
						if (base.inSourceMode())
58
							base.sourceEditorInsertText(' ' + $(this).attr('alt') + ' ');
59
						else
60
							base.wysiwygEditorInsertHtml(start + '<img src="' + $(this).attr("src") + '" data-sceditor-emoticon="' + $(this).attr('alt') + '">' + end);
61
62
						e.preventDefault();
63
					})
64
				);
65
		},
66
		createPermanentDropDown: function () {
67
			var emoticons = $.extend({}, this.opts.emoticons.dropdown);
68
			var popup_exists = false;
69
			content = $('<div class="sceditor-insertemoticon">');
0 ignored issues
show
Bug introduced by
The variable content seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.content.
Loading history...
70
			line = $('<div>');
0 ignored issues
show
Bug introduced by
The variable line seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.line.
Loading history...
71
			base = this;
0 ignored issues
show
Bug introduced by
The variable base seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.base.
Loading history...
72
73
			for (smiley_popup in this.opts.emoticons.popup)
0 ignored issues
show
Bug introduced by
The variable smiley_popup seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.smiley_popup.
Loading history...
74
			{
75
				popup_exists = true;
76
				break;
77
			}
78
			if (popup_exists)
79
			{
80
				base.opts.emoticons.more = base.opts.emoticons.popup;
81
				moreButton = $('<div class="sceditor-more-button sceditor-more button">').text(this._('More')).click(function () {
0 ignored issues
show
Bug introduced by
The variable moreButton seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.moreButton.
Loading history...
82
					if ($(".sceditor-smileyPopup").length > 0)
83
					{
84
						$(".sceditor-smileyPopup").fadeIn('fast');
85
					}
86
					else
87
					{
88
						var emoticons = $.extend({}, base.opts.emoticons.popup);
89
						var popup_position;
0 ignored issues
show
Unused Code introduced by
The variable popup_position seems to be never used. Consider removing it.
Loading history...
90
						var titlebar = $('<div class="catbg sceditor-popup-grip"/>');
91
						popupContent = $('<div id="sceditor-popup"/>');
0 ignored issues
show
Bug introduced by
The variable popupContent seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.popupContent.
Loading history...
92
						allowHide = true;
0 ignored issues
show
Bug introduced by
The variable allowHide seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.allowHide.
Loading history...
93
						line = $('<div id="sceditor-popup-smiley"/>');
0 ignored issues
show
Bug introduced by
The variable line seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.line.
Loading history...
94
						adjheight = 0;
0 ignored issues
show
Bug introduced by
The variable adjheight seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.adjheight.
Loading history...
95
96
						popupContent.append(titlebar);
97
						closeButton = $('<span class="button">').text(base._('Close')).click(function () {
0 ignored issues
show
Bug introduced by
The variable closeButton seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.closeButton.
Loading history...
98
							$(".sceditor-smileyPopup").fadeOut('fast');
99
						});
100
101
						$.each(emoticons, base.appendEmoticon);
102
103
						if (line.children().length > 0)
104
							popupContent.append(line);
105
						if (typeof closeButton !== "undefined")
106
							popupContent.append(closeButton);
107
108
						// IE needs unselectable attr to stop it from unselecting the text in the editor.
109
						// The editor can cope if IE does unselect the text it's just not nice.
110
						if (base.ieUnselectable !== false) {
111
							content = $(content);
0 ignored issues
show
Bug introduced by
The variable content seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.content.
Loading history...
112
							content.find(':not(input,textarea)').filter(function () { return this.nodeType===1; }).attr('unselectable', 'on');
113
						}
114
115
						dropdownIgnoreLastClick = true;
0 ignored issues
show
Bug introduced by
The variable dropdownIgnoreLastClick seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.dropdownIgnoreLastClick.
Loading history...
116
						adjheight = closeButton.height() + titlebar.height();
0 ignored issues
show
Bug introduced by
The variable adjheight seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.adjheight.
Loading history...
117
						$dropdown = $('<div class="centerbox sceditor-smileyPopup">')
0 ignored issues
show
Bug introduced by
The variable $dropdown seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.$dropdown.
Loading history...
118
							.append(popupContent)
119
							.appendTo($('.sceditor-container'));
120
121
						$('.sceditor-smileyPopup').animaDrag({
122
							speed: 150,
123
							interval: 120,
124
							during: function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
125
								$(this).height(this.startheight);
126
								$(this).width(this.startwidth);
127
							},
128
							before: function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
129
								this.startheight = $(this).innerHeight();
130
								this.startwidth = $(this).innerWidth();
131
							},
132
							grip: '.sceditor-popup-grip'
133
						});
134
						// stop clicks within the dropdown from being handled
135
						$dropdown.click(function (e) {
136
							e.stopPropagation();
137
						});
138
					}
139
				});
140
			}
141
			$.each(emoticons, base.appendEmoticon);
142
			if (line.children().length > 0)
143
				content.append(line);
144
			$(".sceditor-toolbar").append(content);
145
			if (typeof moreButton !== "undefined")
0 ignored issues
show
Bug introduced by
The variable moreButton does not seem to be initialized in case popup_exists on line 78 is false. Are you sure this can never be the case?
Loading history...
146
				content.append($('<center/>').append(moreButton));
147
		}
148
	};
149
150
	var createFn = sceditor.create;
151
	var isPatched = false;
152
153
	sceditor.create = function (textarea, options) {
154
		// Call the original create function
155
		createFn(textarea, options);
156
157
		// Constructor isn't exposed so get reference to it when
158
		// creating the first instance and extend it then
159
		var instance = sceditor.instance(textarea);
160
		if (!isPatched && instance) {
161
			$.extend(true, instance.constructor.prototype, extensionMethods);
162
			isPatched = true;
163
		}
164
	};
165
})(jQuery);
166
167
sceditor.command.set(
168
	'pre', {
169
		txtExec: ["[pre]", "[/pre]"],
170
		exec: function () {
171
			this.wysiwygEditorInsertHtml('<pre>', '</pre>');
172
		}
173
	}
174
);
175
sceditor.command.set(
176
	'email', {
177
		txtExec: function (caller, selected) {
178
			var	display = selected && selected.indexOf('@') > -1 ? null : selected,
179
				email	= prompt(this._("Enter the e-mail address:"), (display ? '' : selected));
180
			if (email)
181
			{
182
				var text	= prompt(this._("Enter the displayed text:"), display || email) || email;
183
				this.insertText("[email=" + email + "]" + text + "[/email]");
184
			}
185
		}
186
	}
187
);
188
sceditor.command.set(
189
	'link', {
190
		txtExec: function (caller, selected) {
191
			var	display = selected && selected.indexOf('http://') > -1 ? null : selected,
192
				url	= prompt(this._("Enter URL:"), (display ? 'http://' : selected));
193
			if (url)
194
			{
195
				var text	= prompt(this._("Enter the displayed text:"), display || url) || url;
196
				this.insertText("[url=\"" + url + "\"]" + text + "[/url]");
197
			}
198
		},
199
		exec: function (caller) {
200
			var editor = this;
201
202
			editor.commands.link._dropDown(editor, caller, function (url, text) {
203
				// needed for IE to restore the last range
204
				editor.focus();
205
206
				// If there is no selected text then must set the URL as
207
				// the text. Most browsers do this automatically, sadly
208
				// IE doesn't.
209
				if (!editor.getRangeHelper().selectedHtml() || text) {
210
					text = text || url;
211
212
					editor.wysiwygEditorInsertHtml(
213
						'<a target="_blank" rel="noopener" href="' + url + '">' + text + '</a>'
214
					);
215
				} else {
216
					editor.execCommand('createlink', url);
217
				}
218
			});
219
		}
220
	}
221
);
222
223
sceditor.command.set(
224
	'bulletlist', {
225
		txtExec: function (caller, selected) {
226
			if (selected)
227
			{
228
				var content = '';
229
230
				each(selected.split(/\r?\n/), function () {
231
					content += (content ? '\n' : '') + '[li]' + this + '[/li]';
232
				});
233
234
				this.insertText('[list]\n' + content + '\n[/list]');
235
			}
236
			else
237
				this.insertText('[list]\n[li]', '[/li]\n[li][/li]\n[/list]');
238
		}
239
	}
240
);
241
242
sceditor.command.set(
243
	'orderedlist', {
244
		txtExec: function (caller, selected) {
245
			if (selected)
246
			{
247
				var content = '';
248
249
				each(selected.split(/\r?\n/), function () {
250
					content += (content ? '\n' : '') + '[li]' + this + '[/li]';
251
				});
252
253
				this.insertText('[list type=decimal]\n' + content + '\n[/list]');
254
			}
255
			else
256
				this.insertText('[list type=decimal]\n[li]', '[/li]\n[li][/li]\n[/list]');
257
		}
258
	}
259
);
260
261
sceditor.command.set(
262
	'table', {
263
		txtExec: ["[table]\n[tr]\n[td]", "[/td]\n[/tr]\n[/table]"]
264
	}
265
);
266
267
sceditor.command.set(
268
	'floatleft', {
269
		txtExec: ["[float=left max=45%]", "[/float]"],
270
		exec: function () {
271
			this.wysiwygEditorInsertHtml('<div class="floatleft">', '</div>');
272
		}
273
	}
274
);
275
276
sceditor.command.set(
277
	'floatright', {
278
		txtExec: ["[float=right max=45%]", "[/float]"],
279
		exec: function () {
280
			this.wysiwygEditorInsertHtml('<div class="floatright">', '</div>');
281
		}
282
	}
283
);
284
285
sceditor.command.set(
286
	'youtube', {
287
		exec: function (caller) {
288
			var editor = this;
289
290
			editor.commands.youtube._dropDown(editor, caller, function (id, time) {
291
				editor.wysiwygEditorInsertHtml('<div class="videocontainer"><div><iframe frameborder="0" allowfullscreen src="https://www.youtube.com/embed/' + id + '?wmode=opaque&start=' + time + '" data-youtube-id="' + id + '"></iframe></div></div>');
292
			});
293
		}
294
	}
295
);
296
297
sceditor.formats.bbcode.set(
298
	'abbr', {
299
		tags: {
300
			abbr: {
301
				title: null
302
			}
303
		},
304
		format: function (element, content) {
305
			return '[abbr=' + $(element).attr('title') + ']' + content + '[/abbr]';
306
		},
307
		html: function (element, attrs, content) {
308
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
309
				return content;
310
311
			return '<abbr title="' + attrs.defaultattr + '">' + content + '</abbr>';
312
		}
313
	}
314
);
315
316
sceditor.formats.bbcode.set(
317
	'list', {
318
		breakStart: true,
319
		isInline: false,
320
		// allowedChildren: ['*', 'li'], // Disabled for SCE 2.1.2 because it triggers a bug with inserting extra line breaks
321
		html: function (element, attrs, content) {
322
			var style = '';
323
			var code = 'ul';
324
			var olTypes = new Array('decimal', 'decimal-leading-zero', 'lower-roman', 'upper-roman', 'lower-alpha', 'upper-alpha', 'lower-greek', 'upper-greek', 'lower-latin', 'upper-latin', 'hebrew', 'armenian', 'georgian', 'cjk-ideographic', 'hiragana', 'katakana', 'hiragana-iroha', 'katakana-iroha');
325
326
			if (attrs.type) {
327
				style = ' style="list-style-type: ' + attrs.type + '"';
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
328
329
				if (olTypes.indexOf(attrs.type) > -1)
330
					code = 'ol';
331
			}
332
			else
333
				style = ' style="list-style-type: disc"';
334
335
			return '<' + code + style + '>' + content + '</' + code + '>';
336
		}
337
	}
338
);
339
340
sceditor.formats.bbcode.set(
341
	'ul', {
342
		tags: {
343
			ul: null
344
		},
345
		breakStart: true,
346
		isInline: false,
347
		html: '<ul>{0}</ul>',
348
		format: function (element, content) {
349
			if ($(element).css('list-style-type') == 'disc')
350
				return '[list]' + content + '[/list]';
351
			else
352
				return '[list type=' + $(element).css('list-style-type') + ']' + content + '[/list]';
353
		}
354
	}
355
);
356
357
sceditor.formats.bbcode.set(
358
	'ol', {
359
		tags: {
360
			ol: null
361
		},
362
		breakStart: true,
363
		isInline: false,
364
		html: '<ol>{0}</ol>',
365
		format: function (element, content) {
366
			if ($(element).css('list-style-type') == 'none')
367
				return '[list type=decimal]' + content + '[/list]';
368
			else
369
				return '[list type=' + $(element).css('list-style-type') + ']' + content + '[/list]';
370
		}
371
	}
372
);
373
374
sceditor.formats.bbcode.set(
375
	'img', {
376
		tags: {
377
			img: {
378
				src: null
379
			}
380
		},
381
		allowsEmpty: true,
382
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
383
		format: function (element, content) {
384
			var	element = $(element),
385
				attribs = '',
386
				style = function (name) {
387
					return element.style ? element.style[name] : null;
388
				};
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
389
390
			// check if this is an emoticon image
391
			if (typeof element.attr('data-sceditor-emoticon') !== "undefined")
392
				return content;
393
394
			// only add width and height if one is specified
395
			if (element.attr('width') || style('width'))
396
				attribs += " width=" + element.width();
397
			if (element.attr('height') || style('height'))
398
				attribs += " height=" + element.height();
399
			if (element.attr('alt'))
400
				attribs += " alt=" + element.attr('alt');
401
402
			// Is this an attachment?
403
			if (element.attr('data-attachment'))
404
			{
405
				if (element.attr('title'))
406
					attribs += ' name=' + element.attr('title');
407
				if (element.attr('data-type'))
408
					attribs += ' type=' + 	element.attr('data-type');
409
410
				return '[attach' + attribs + ']' + element.attr('data-attachment') + '[/attach]';
411
			}
412
			else if (element.attr('title'))
413
				attribs += " title=" + element.attr('title');
414
415
			return '[img' + attribs + ']' + element.attr('src') + '[/img]';
416
		},
417
		html: function (token, attrs, content) {
418
			var	parts,
0 ignored issues
show
Unused Code introduced by
The variable parts seems to be never used. Consider removing it.
Loading history...
419
				attribs = '';
420
421
			// handle [img width=340 height=240]url[/img]
422
			if (typeof attrs.width !== "undefined")
423
				attribs += ' width="' + attrs.width + '"';
424
			if (typeof attrs.height !== "undefined")
425
				attribs += ' height="' + attrs.height + '"';
426
			if (typeof attrs.alt !== "undefined")
427
				attribs += ' alt="' + attrs.alt + '"';
428
			if (typeof attrs.title !== "undefined")
429
				attribs += ' title="' + attrs.title + '"';
430
431
			return '<img' + attribs + ' src="' + content + '">';
432
		}
433
	}
434
);
435
436
sceditor.formats.bbcode.set(
437
	'attach', {
438
		tags: {
439
			attach: {
440
				src: null
441
			}
442
		},
443
		allowsEmpty: true,
444
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
445
		format: function (element, content) {
446
			var	element = $(element),
447
				attribs = '',
448
				style = function (name) {
449
					return element.style ? element.style[name] : null;
450
				};
451
452
			// only add width and height if one is specified
453
			if (element.attr('width') || style('width'))
454
				attribs += " width=" + $(element).width();
455
			if (element.attr('height') || style('height'))
456
				attribs += " height=" + $(element).height();
457
			if (element.attr('alt'))
458
				attribs += " alt=" + element.attr('alt');
459
			if (element.attr('title'))
460
				attribs += " name=" + element.attr('title');
461
			if (element.attr('data-type'))
462
				attribs += " type=" + element.attr('data-type');
463
464
			return '[attach' + attribs + ']' + (element.attr('data-attachment') ? element.attr('data-attachment') : content) + '[/attach]';
465
		},
466
		html: function (token, attrs, id) {
467
			var parts,
0 ignored issues
show
Unused Code introduced by
The variable parts seems to be never used. Consider removing it.
Loading history...
468
				attribs = '';
469
470
			// If id is not an integer, bail out
471
			if (!$.isNumeric(id) || Math.floor(id) != +id || +id <= 0) {
472
473
				if (typeof attrs.width !== "undefined")
474
					attribs += ' width=' + attrs.width;
475
				if (typeof attrs.height !== "undefined")
476
					attribs += ' height=' + attrs.height;
477
				if (typeof attrs.alt !== "undefined")
478
					attribs += ' alt=' + attrs.alt;
479
				if (typeof attrs.name !== "undefined")
480
					attribs += ' name=' + attrs.name;
481
				if (typeof attrs.type !== "undefined")
482
					attribs += ' type=' + attrs.type;
483
484
				return '[attach' + attribs + ']' + id + '[/attach]';
485
			}
486
487
			attribs += ' data-attachment="' + id + '"'
488
			if (typeof attrs.width !== "undefined")
489
				attribs += ' width="' + attrs.width + '"';
490
			if (typeof attrs.height !== "undefined")
491
				attribs += ' height="' + attrs.height + '"';
492
			if (typeof attrs.alt !== "undefined")
493
				attribs += ' alt="' + attrs.alt + '"';
494
			if (typeof attrs.type !== "undefined")
495
				attribs += ' data-type="' + attrs.type + '"';
496
			if (typeof attrs.name !== "undefined")
497
				attribs += ' title="' + attrs.name + '"';
498
499
			// Is this an image?
500
			if ((typeof attrs.type !== "undefined" && attrs.type.indexOf("image") === 0)) {
501
				var contentUrl = smf_scripturl +'?action=dlattach;attach='+ id + ';type=preview;thumb';
502
				contentIMG = new Image();
0 ignored issues
show
Bug introduced by
The variable contentIMG seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.contentIMG.
Loading history...
503
					contentIMG.src = contentUrl;
504
			}
505
506
			// If not an image, show a boring ol' link
507
			if (typeof contentUrl === "undefined" || contentIMG.getAttribute('width') == 0)
0 ignored issues
show
Bug introduced by
The variable contentUrl does not seem to be initialized in case typeof attrs.type !== "....indexOf("image") === 0 on line 500 is false. Are you sure this can never be the case?
Loading history...
Bug introduced by
The variable contentIMG does not seem to be initialized in case typeof attrs.type !== "....indexOf("image") === 0 on line 500 is false. Are you sure this can never be the case?
Loading history...
508
				return '<a href="' + smf_scripturl + '?action=dlattach;attach=' + id + ';type=preview;file"' + attribs + '>' + (typeof attrs.name !== "undefined" ? attrs.name : id) + '</a>';
509
			// Show our purdy li'l picture
510
			else
511
				return '<img' + attribs + ' src="' + contentUrl + '">';
512
		}
513
	}
514
);
515
516
sceditor.formats.bbcode.set(
517
	'url', {
518
		allowsEmpty: true,
519
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
520
		tags: {
521
			a: {
522
				href: null
523
			}
524
		},
525
		format: function (element, content) {
526
			var element = $(element),
527
				url = element.attr('href');
528
529
			// make sure this link is not an e-mail, if it is return e-mail BBCode
530
			if (url.substr(0, 7) === 'mailto:')
531
				return '[email=' + url.substr(7) + ']' + content + '[/email]';
532
533
			if (typeof element.attr('target') !== "undefined")
534
				return '[url=\"' + decodeURI(url) + '\"]' + content + '[/url]';
535
536
			// A mention?
537
			else if (typeof element.attr('data-mention') !== "undefined")
538
			{
539
				return '[member='+ element.attr('data-mention') +']'+ content.replace('@','') +'[/member]';
540
			}
541
542
			// Is this an attachment?
543
			else if (typeof element.attr('data-attachment') !== "undefined")
544
			{
545
				var attribs = '';
546
				if (typeof element.attr('title') !== "undefined")
547
					attribs += ' name=' + element.attr('title');
548
				if (typeof element.attr('data-type') !== "undefined")
549
					attribs += ' type=' + element.attr("data-type");
550
551
				return '[attach' + attribs + ']' + element.attr('data-attachment') + '[/attach]';
552
			}
553
554
			else
555
				return '[iurl=\"' + decodeURI(url) + '\"]' + content + '[/iurl]';
556
		},
557
		html: function (token, attrs, content) {
558
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
559
				attrs.defaultattr = content;
560
561
			return '<a target="_blank" rel="noopener" href="' + encodeURI(attrs.defaultattr) + '">' + content + '</a>';
562
		}
563
	}
564
);
565
566
sceditor.formats.bbcode.set(
567
	'iurl', {
568
		allowsEmpty: true,
569
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
570
		html: function (token, attrs, content) {
571
572
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
573
				attrs.defaultattr = content;
574
575
			return '<a href="' + encodeURI(attrs.defaultattr) + '">' + content + '</a>';
576
		}
577
	}
578
);
579
580
sceditor.formats.bbcode.set(
581
	'pre', {
582
		tags: {
583
			pre: null
584
		},
585
		isBlock: true,
586
		format: "[pre]{0}[/pre]",
587
		html: "<pre>{0}</pre>\n"
588
	}
589
);
590
591
sceditor.formats.bbcode.set(
592
	'php', {
593
		isInline: false,
594
		format: "[php]{0}[/php]",
595
		html: '<code class="php">{0}</code>'
596
	}
597
);
598
599
sceditor.formats.bbcode.set(
600
	'code', {
601
		tags: {
602
			code: null
603
		},
604
		isInline: false,
605
		allowedChildren: ['#', '#newline'],
606
		format: function (element, content) {
607
			if ($(element).hasClass('php'))
608
				return '[php]' + content.replace('&#91;', '[') + '[/php]';
609
610
			var from = '';
611
			if ($(element).children("cite:first").length === 1)
612
			{
613
				from = $(element).children("cite:first").text();
614
615
				$(element).attr({'from': from.php_htmlspecialchars()});
616
617
				from = '=' + from;
618
				content = '';
0 ignored issues
show
Unused Code introduced by
The assignment to variable content seems to be never used. Consider removing it.
Loading history...
619
				$(element).children("cite:first").remove();
620
				content = this.elementToBbcode($(element));
621
			}
622
			else
623
			{
624
				if (typeof $(element).attr('from') != 'undefined')
625
				{
626
					from = '=' + $(element).attr('from').php_unhtmlspecialchars();
627
				}
628
			}
629
630
			return '[code' + from + ']' + content.replace('&#91;', '[') + '[/code]';
631
632
		},
633
		html: function (element, attrs, content) {
634
			var from = '';
635
			if (typeof attrs.defaultattr !== "undefined")
636
				from = '<cite>' + attrs.defaultattr + '</cite>';
637
638
			return '<code>' + from + content.replace('[', '&#91;') + '</code>'
639
		}
640
	}
641
);
642
643
sceditor.formats.bbcode.set(
644
	'quote', {
645
		tags: {
646
			blockquote: null,
647
			cite: null
648
		},
649
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
650
		breakBefore: false,
651
		isInline: false,
652
		format: function (element, content) {
653
			var element = $(element);
654
			var author = '';
655
			var date = '';
656
			var link = '';
657
658
			// The <cite> contains only the graphic for the quote, so we can skip it
659
			if (element[0].tagName.toLowerCase() === 'cite')
660
				return '';
661
662
			if (element.attr('author'))
663
				author = ' author=' + element.attr('author').php_unhtmlspecialchars();
664
			if (element.attr('link'))
665
				link = ' link=' + element.attr('link');
666
			if (element.attr('date'))
667
				date = ' date=' + element.attr('date');
668
669
			return '[quote' + author + link + date + ']' + content + '[/quote]';
670
		},
671
		html: function (element, attrs, content) {
672
			var attr_author = '', author = '';
673
			var attr_date = '', sDate = '';
674
			var attr_link = '', link = '';
675
676
			if (typeof attrs.author !== "undefined" && attrs.author)
677
			{
678
				attr_author = attrs.author;
679
				author = bbc_quote_from + ': ' + attr_author;
680
			}
681
682
			// Links could be in the form: link=topic=71.msg201#msg201 that would fool javascript, so we need a workaround
683
			// Probably no more necessary
684
			for (var key in attrs)
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
685
			{
686
				if (key.substr(0, 4) == 'link' && attrs.hasOwnProperty(key))
687
				{
688
					var attr_link = key.length > 4 ? key.substr(5) + '=' + attrs[key] : attrs[key];
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable attr_link already seems to be declared on line 674. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
689
690
					link = attr_link.substr(0, 7) == 'http://' ? attr_link : smf_scripturl + '?' + attr_link;
691
					author = author == '' ? '<a href="' + link + '">' + bbc_quote_from + ': ' + link + '</a>' : '<a href="' + link + '">' + author + '</a>';
692
				}
693
			}
694
695
			if (typeof attrs.date !== "undefined" && attrs.date)
696
			{
697
				attr_date = attrs.date;
698
				tDate = new Date(attr_date * 1000);
0 ignored issues
show
Bug introduced by
The variable tDate seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.tDate.
Loading history...
699
				sDate_string = tDate.toLocaleString();
0 ignored issues
show
Bug introduced by
The variable sDate_string seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.sDate_string.
Loading history...
700
				sDate = '<date timestamp="' + attr_date + '">' + sDate_string + '</date>';
701
			}
702
703
			if (author == '' && sDate == '')
704
				author = bbc_quote;
705
			else if (author == '' && sDate != '')
706
				author += ' ' + bbc_search_on;
707
708
			content = '<blockquote author="' + attr_author + '" date="' + attr_date + '" link="' + attr_link + '"><cite>' + author + ' ' + sDate + '</cite>' + content + '</blockquote>';
709
710
			return content;
711
		}
712
	}
713
);
714
715
sceditor.formats.bbcode.set('font', {
716
	format: function (element, content) {
717
		var element = $(element);
718
		var font;
719
720
		// Get the raw font value from the DOM
721
		if (!element.is('font') || !(font = element.attr('face'))) {
722
			font = element.css('font-family');
723
		}
724
725
		// Strip all quotes
726
		font = font.replace(/['"]/g, '');
727
728
		return '[font=' + font + ']' + content + '[/font]';
729
	}
730
});
731
732
sceditor.formats.bbcode.set(
733
	'member', {
734
		isInline: true,
735
		format: function (element, content) {
736
			return '[member='+ $(element).attr('data-mention') +']'+ content.replace('@','') +'[/member]';
737
		},
738
		html: function (token, attrs, content) {
739
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
740
				attrs.defaultattr = content;
741
742
			return '<a href="' + smf_scripturl +'?action=profile;u='+ attrs.defaultattr + '" class="mention" data-mention="'+ attrs.defaultattr + '">@'+ content.replace('@','') +'</a>';
743
		}
744
	}
745
);
746
747
sceditor.formats.bbcode.set(
748
	'float', {
749
		tags: {
750
			div: {
751
				"class": ["floatleft", "floatright"],
752
			},
753
		},
754
		isInline: false,
755
		skipLastLineBreak: true,
756
		format: function (element, content) {
757
			var element = $(element);
758
			if (!element.css('float'))
759
				return content;
760
761
			side = (element.css('float').indexOf('left') == 0 ? 'left' : 'right');
0 ignored issues
show
Bug introduced by
The variable side seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.side.
Loading history...
762
			max = ' max=' + (element.css('max-width') != "none" ? element.css('max-width') : '45%');
0 ignored issues
show
Bug introduced by
The variable max seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.max.
Loading history...
763
764
			return '[float=' + side + max + ']' + content + '[/float]';
765
		},
766
		html: function (token, attrs, content) {
767
			if (typeof attrs.defaultattr === "undefined")
768
				return content;
769
770
			floatclass = attrs.defaultattr.indexOf('left') == 0 ? 'floatleft' : 'floatright';
0 ignored issues
show
Bug introduced by
The variable floatclass seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.floatclass.
Loading history...
771
			style = typeof attrs.max !== "undefined" ? ' style="max-width:' + attrs.max + (+attrs.max === parseInt(attrs.max) ? 'px' : '') + ';"' : '';
0 ignored issues
show
Bug introduced by
The variable style seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.style.
Loading history...
772
773
			return '<div class="' + floatclass + '"' + style + '>' + content + '</div>';
774
		}
775
	}
776
);
777
778
sceditor.formats.bbcode.set(
779
	'youtube', {
780
		allowsEmpty: true,
781
		tags: {
782
			div: {
783
				class: 'videocontainer'
784
			}
785
		},
786
		format: function (element, content) {
787
			youtube_id = $(element).find('iframe').data('youtube-id');
0 ignored issues
show
Bug introduced by
The variable youtube_id seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.youtube_id.
Loading history...
788
789
			if (typeof youtube_id !== "undefined")
790
				return '[youtube]' + youtube_id + '[/youtube]';
791
			else
792
				return content;
793
		},
794
		html: '<div class="videocontainer"><div><iframe frameborder="0" src="https://www.youtube.com/embed/{0}?wmode=opaque" data-youtube-id="{0}" allowfullscreen></iframe></div></div>'
795
	}
796
);
797