Completed
Pull Request — release-2.1 (#4823)
by
unknown
08:48
created

Themes/default/scripts/jquery.sceditor.smf.js (25 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
		getText: function (filter) {
29
			var current_value = '';
30
31
			if (this.inSourceMode())
32
				current_value = this.getSourceEditorValue(false);
33
			else
34
				current_value = this.getWysiwygEditorValue(filter);
35
36
			return current_value;
37
		},
38
		appendEmoticon: function (code, emoticon, description) {
39
			if (emoticon == '')
40
				line.append($('<br>'));
41
			else
42
				line.append($('<img>')
43
					.attr({
44
						src: emoticon,
45
						alt: code,
46
						title: description,
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
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
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
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
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
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;
90
						var titlebar = $('<div class="catbg sceditor-popup-grip"/>');
91
						popupContent = $('<div id="sceditor-popup"/>');
0 ignored issues
show
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
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
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
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
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, function( code, emoticon ) {
102
							base.appendEmoticon(code, emoticon, base.opts.emoticonsDescriptions[code]);
103
						});
104
105
						if (line.children().length > 0)
106
							popupContent.append(line);
107
						if (typeof closeButton !== "undefined")
108
							popupContent.append(closeButton);
109
110
						// IE needs unselectable attr to stop it from unselecting the text in the editor.
111
						// The editor can cope if IE does unselect the text it's just not nice.
112
						if (base.ieUnselectable !== false) {
113
							content = $(content);
0 ignored issues
show
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...
114
							content.find(':not(input,textarea)').filter(function () { return this.nodeType===1; }).attr('unselectable', 'on');
115
						}
116
117
						dropdownIgnoreLastClick = true;
0 ignored issues
show
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...
118
						adjheight = closeButton.height() + titlebar.height();
0 ignored issues
show
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...
119
						$dropdown = $('<div class="centerbox sceditor-smileyPopup">')
0 ignored issues
show
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...
120
							.append(popupContent)
121
							.appendTo($('.sceditor-container'));
122
123
						$('.sceditor-smileyPopup').animaDrag({
124
							speed: 150,
125
							interval: 120,
126
							during: function (e) {
127
								$(this).height(this.startheight);
128
								$(this).width(this.startwidth);
129
							},
130
							before: function (e) {
131
								this.startheight = $(this).innerHeight();
132
								this.startwidth = $(this).innerWidth();
133
							},
134
							grip: '.sceditor-popup-grip'
135
						});
136
						// stop clicks within the dropdown from being handled
137
						$dropdown.click(function (e) {
138
							e.stopPropagation();
139
						});
140
					}
141
				});
142
			}
143
			$.each(emoticons, function( code, emoticon ) {
144
				base.appendEmoticon(code, emoticon, base.opts.emoticonsDescriptions[code]);
145
			});
146
			if (line.children().length > 0)
147
				content.append(line);
148
			$(".sceditor-toolbar").append(content);
149
			if (typeof moreButton !== "undefined")
0 ignored issues
show
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...
150
				content.append($('<center/>').append(moreButton));
151
		}
152
	};
153
154
	var createFn = sceditor.create;
155
	var isPatched = false;
156
157
	sceditor.create = function (textarea, options) {
158
		// Call the original create function
159
		createFn(textarea, options);
160
161
		// Constructor isn't exposed so get reference to it when
162
		// creating the first instance and extend it then
163
		var instance = sceditor.instance(textarea);
164
		if (!isPatched && instance) {
165
			$.extend(true, instance.constructor.prototype, extensionMethods);
166
			isPatched = true;
167
		}
168
	};
169
})(jQuery);
170
171
sceditor.command.set(
172
	'pre', {
173
		txtExec: ["[pre]", "[/pre]"],
174
		exec: function () {
175
			this.wysiwygEditorInsertHtml('<pre>', '</pre>');
176
		}
177
	}
178
);
179
sceditor.command.set(
180
	'email', {
181
		txtExec: function (caller, selected) {
182
			var	display = selected && selected.indexOf('@') > -1 ? null : selected,
183
				email	= prompt(this._("Enter the e-mail address:"), (display ? '' : selected));
184
			if (email)
185
			{
186
				var text	= prompt(this._("Enter the displayed text:"), display || email) || email;
187
				this.insertText("[email=" + email + "]" + text + "[/email]");
188
			}
189
		}
190
	}
191
);
192
sceditor.command.set(
193
	'link', {
194
		txtExec: function (caller, selected) {
195
			var	display = selected && selected.indexOf('http://') > -1 ? null : selected,
196
				url	= prompt(this._("Enter URL:"), (display ? 'http://' : selected));
197
			if (url)
198
			{
199
				var text	= prompt(this._("Enter the displayed text:"), display || url) || url;
200
				this.insertText("[url=\"" + url + "\"]" + text + "[/url]");
201
			}
202
		},
203
		exec: function (caller) {
204
			var editor = this;
205
206
			editor.commands.link._dropDown(editor, caller, function (url, text) {
207
				// needed for IE to restore the last range
208
				editor.focus();
209
210
				// If there is no selected text then must set the URL as
211
				// the text. Most browsers do this automatically, sadly
212
				// IE doesn't.
213
				if (!editor.getRangeHelper().selectedHtml() || text) {
214
					text = text || url;
215
216
					editor.wysiwygEditorInsertHtml(
217
						'<a target="_blank" rel="noopener" href="' + url + '">' + text + '</a>'
218
					);
219
				} else {
220
					// Can't just use `editor.execCommand('createlink', url)`
221
					// because we need to set the target attribute.
222
					editor.wysiwygEditorInsertHtml(
223
						'<a target="_blank" rel="noopener" href="' + url + '">', '</a>'
224
					);
225
				}
226
			});
227
		}
228
	}
229
);
230
231
sceditor.command.set(
232
	'bulletlist', {
233
		txtExec: function (caller, selected) {
234
			if (selected)
235
			{
236
				var content = '';
237
238
				each(selected.split(/\r?\n/), function () {
239
					content += (content ? '\n' : '') + '[li]' + this + '[/li]';
240
				});
241
242
				this.insertText('[list]\n' + content + '\n[/list]');
243
			}
244
			else
245
				this.insertText('[list]\n[li]', '[/li]\n[li][/li]\n[/list]');
246
		}
247
	}
248
);
249
250
sceditor.command.set(
251
	'orderedlist', {
252
		txtExec: function (caller, selected) {
253
			if (selected)
254
			{
255
				var content = '';
256
257
				each(selected.split(/\r?\n/), function () {
258
					content += (content ? '\n' : '') + '[li]' + this + '[/li]';
259
				});
260
261
				this.insertText('[list type=decimal]\n' + content + '\n[/list]');
262
			}
263
			else
264
				this.insertText('[list type=decimal]\n[li]', '[/li]\n[li][/li]\n[/list]');
265
		}
266
	}
267
);
268
269
sceditor.command.set(
270
	'table', {
271
		txtExec: ["[table]\n[tr]\n[td]", "[/td]\n[/tr]\n[/table]"]
272
	}
273
);
274
275
sceditor.command.set(
276
	'floatleft', {
277
		txtExec: ["[float=left max=45%]", "[/float]"],
278
		exec: function () {
279
			this.wysiwygEditorInsertHtml('<div class="floatleft">', '</div>');
280
		}
281
	}
282
);
283
284
sceditor.command.set(
285
	'floatright', {
286
		txtExec: ["[float=right max=45%]", "[/float]"],
287
		exec: function () {
288
			this.wysiwygEditorInsertHtml('<div class="floatright">', '</div>');
289
		}
290
	}
291
);
292
293
sceditor.command.set(
294
	'youtube', {
295
		exec: function (caller) {
296
			var editor = this;
297
298
			editor.commands.youtube._dropDown(editor, caller, function (id, time) {
299
				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>');
300
			});
301
		}
302
	}
303
);
304
305
sceditor.formats.bbcode.set(
306
	'abbr', {
307
		tags: {
308
			abbr: {
309
				title: null
310
			}
311
		},
312
		format: function (element, content) {
313
			return '[abbr=' + $(element).attr('title') + ']' + content + '[/abbr]';
314
		},
315
		html: function (element, attrs, content) {
316
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
317
				return content;
318
319
			return '<abbr title="' + attrs.defaultattr + '">' + content + '</abbr>';
320
		}
321
	}
322
);
323
324
sceditor.formats.bbcode.set(
325
	'list', {
326
		breakStart: true,
327
		isInline: false,
328
		// allowedChildren: ['*', 'li'], // Disabled for SCE 2.1.2 because it triggers a bug with inserting extra line breaks
329
		html: function (element, attrs, content) {
330
			var style = '';
331
			var code = 'ul';
332
			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');
333
334
			if (attrs.type) {
335
				style = ' style="list-style-type: ' + attrs.type + '"';
336
337
				if (olTypes.indexOf(attrs.type) > -1)
338
					code = 'ol';
339
			}
340
			else
341
				style = ' style="list-style-type: disc"';
342
343
			return '<' + code + style + '>' + content + '</' + code + '>';
344
		}
345
	}
346
);
347
348
sceditor.formats.bbcode.set(
349
	'ul', {
350
		tags: {
351
			ul: null
352
		},
353
		breakStart: true,
354
		isInline: false,
355
		html: '<ul>{0}</ul>',
356
		format: function (element, content) {
357
			if ($(element).css('list-style-type') == 'disc')
358
				return '[list]' + content + '[/list]';
359
			else
360
				return '[list type=' + $(element).css('list-style-type') + ']' + content + '[/list]';
361
		}
362
	}
363
);
364
365
sceditor.formats.bbcode.set(
366
	'ol', {
367
		tags: {
368
			ol: null
369
		},
370
		breakStart: true,
371
		isInline: false,
372
		html: '<ol>{0}</ol>',
373
		format: function (element, content) {
374
			if ($(element).css('list-style-type') == 'none')
375
				return '[list type=decimal]' + content + '[/list]';
376
			else
377
				return '[list type=' + $(element).css('list-style-type') + ']' + content + '[/list]';
378
		}
379
	}
380
);
381
382
sceditor.formats.bbcode.set(
383
	'img', {
384
		tags: {
385
			img: {
386
				src: null
387
			}
388
		},
389
		allowsEmpty: true,
390
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
391
		format: function (element, content) {
392
			var	element = $(element),
393
				attribs = '',
394
				style = function (name) {
395
					return element.style ? element.style[name] : null;
396
				};
397
398
			// check if this is an emoticon image
399
			if (typeof element.attr('data-sceditor-emoticon') !== "undefined")
400
				return content;
401
402
			// only add width and height if one is specified
403
			if (element.attr('width') || style('width'))
404
				attribs += " width=" + element.width();
405
			if (element.attr('height') || style('height'))
406
				attribs += " height=" + element.height();
407
			if (element.attr('alt'))
408
				attribs += " alt=" + element.attr('alt');
409
410
			// Is this an attachment?
411
			if (element.attr('data-attachment'))
412
			{
413
				if (element.attr('title'))
414
					attribs += ' name=' + element.attr('title');
415
				if (element.attr('data-type'))
416
					attribs += ' type=' + 	element.attr('data-type');
417
418
				return '[attach' + attribs + ']' + element.attr('data-attachment') + '[/attach]';
419
			}
420
			else if (element.attr('title'))
421
				attribs += " title=" + element.attr('title');
422
423
			return '[img' + attribs + ']' + element.attr('src') + '[/img]';
424
		},
425
		html: function (token, attrs, content) {
426
			var	parts,
427
				attribs = '';
428
429
			// handle [img width=340 height=240]url[/img]
430
			if (typeof attrs.width !== "undefined")
431
				attribs += ' width="' + attrs.width + '"';
432
			if (typeof attrs.height !== "undefined")
433
				attribs += ' height="' + attrs.height + '"';
434
			if (typeof attrs.alt !== "undefined")
435
				attribs += ' alt="' + attrs.alt + '"';
436
			if (typeof attrs.title !== "undefined")
437
				attribs += ' title="' + attrs.title + '"';
438
439
			return '<img' + attribs + ' src="' + content + '">';
440
		}
441
	}
442
);
443
444
sceditor.formats.bbcode.set(
445
	'attach', {
446
		tags: {
447
			attach: {
448
				src: null
449
			}
450
		},
451
		allowsEmpty: true,
452
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
453
		format: function (element, content) {
454
			var	element = $(element),
455
				attribs = '',
456
				style = function (name) {
457
					return element.style ? element.style[name] : null;
458
				};
459
460
			// only add width and height if one is specified
461
			if (element.attr('width') || style('width'))
462
				attribs += " width=" + $(element).width();
463
			if (element.attr('height') || style('height'))
464
				attribs += " height=" + $(element).height();
465
			if (element.attr('alt'))
466
				attribs += " alt=" + element.attr('alt');
467
			if (element.attr('title'))
468
				attribs += " name=" + element.attr('title');
469
			if (element.attr('data-type'))
470
				attribs += " type=" + element.attr('data-type');
471
472
			return '[attach' + attribs + ']' + (element.attr('data-attachment') ? element.attr('data-attachment') : content) + '[/attach]';
473
		},
474
		html: function (token, attrs, id) {
475
			var parts,
476
				attribs = '';
477
478
			// If id is not an integer, bail out
479
			if (!$.isNumeric(id) || Math.floor(id) != +id || +id <= 0) {
480
481
				if (typeof attrs.width !== "undefined")
482
					attribs += ' width=' + attrs.width;
483
				if (typeof attrs.height !== "undefined")
484
					attribs += ' height=' + attrs.height;
485
				if (typeof attrs.alt !== "undefined")
486
					attribs += ' alt=' + attrs.alt;
487
				if (typeof attrs.name !== "undefined")
488
					attribs += ' name=' + attrs.name;
489
				if (typeof attrs.type !== "undefined")
490
					attribs += ' type=' + attrs.type;
491
492
				return '[attach' + attribs + ']' + id + '[/attach]';
493
			}
494
495
			attribs += ' data-attachment="' + id + '"'
496
			if (typeof attrs.width !== "undefined")
497
				attribs += ' width="' + attrs.width + '"';
498
			if (typeof attrs.height !== "undefined")
499
				attribs += ' height="' + attrs.height + '"';
500
			if (typeof attrs.alt !== "undefined")
501
				attribs += ' alt="' + attrs.alt + '"';
502
			if (typeof attrs.type !== "undefined")
503
				attribs += ' data-type="' + attrs.type + '"';
504
			if (typeof attrs.name !== "undefined")
505
				attribs += ' title="' + attrs.name + '"';
506
507
			// Is this an image?
508
			if ((typeof attrs.type !== "undefined" && attrs.type.indexOf("image") === 0)) {
509
				var contentUrl = smf_scripturl +'?action=dlattach;attach='+ id + ';type=preview;thumb';
510
				contentIMG = new Image();
0 ignored issues
show
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...
511
					contentIMG.src = contentUrl;
512
			}
513
514
			// If not an image, show a boring ol' link
515
			if (typeof contentUrl === "undefined" || contentIMG.getAttribute('width') == 0)
0 ignored issues
show
The variable contentIMG does not seem to be initialized in case typeof attrs.type !== "....indexOf("image") === 0 on line 508 is false. Are you sure this can never be the case?
Loading history...
The variable contentUrl does not seem to be initialized in case typeof attrs.type !== "....indexOf("image") === 0 on line 508 is false. Are you sure this can never be the case?
Loading history...
516
				return '<a href="' + smf_scripturl + '?action=dlattach;attach=' + id + ';type=preview;file"' + attribs + '>' + (typeof attrs.name !== "undefined" ? attrs.name : id) + '</a>';
517
			// Show our purdy li'l picture
518
			else
519
				return '<img' + attribs + ' src="' + contentUrl + '">';
520
		}
521
	}
522
);
523
524
sceditor.formats.bbcode.set(
525
	'url', {
526
		allowsEmpty: true,
527
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
528
		tags: {
529
			a: {
530
				href: null
531
			}
532
		},
533
		format: function (element, content) {
534
			var element = $(element),
535
				url = element.attr('href');
536
537
			// make sure this link is not an e-mail, if it is return e-mail BBCode
538
			if (url.substr(0, 7) === 'mailto:')
539
				return '[email=' + url.substr(7) + ']' + content + '[/email]';
540
541
			if (typeof element.attr('target') !== "undefined")
542
				return '[url=\"' + decodeURI(url) + '\"]' + content + '[/url]';
543
544
			// A mention?
545
			else if (typeof element.attr('data-mention') !== "undefined")
546
			{
547
				return '[member='+ element.attr('data-mention') +']'+ content.replace('@','') +'[/member]';
548
			}
549
550
			// Is this an attachment?
551
			else if (typeof element.attr('data-attachment') !== "undefined")
552
			{
553
				var attribs = '';
554
				if (typeof element.attr('title') !== "undefined")
555
					attribs += ' name=' + element.attr('title');
556
				if (typeof element.attr('data-type') !== "undefined")
557
					attribs += ' type=' + element.attr("data-type");
558
559
				return '[attach' + attribs + ']' + element.attr('data-attachment') + '[/attach]';
560
			}
561
562
			else
563
				return '[iurl=\"' + decodeURI(url) + '\"]' + content + '[/iurl]';
564
		},
565
		html: function (token, attrs, content) {
566
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
567
				attrs.defaultattr = content;
568
569
			return '<a target="_blank" rel="noopener" href="' + encodeURI(attrs.defaultattr) + '">' + content + '</a>';
570
		}
571
	}
572
);
573
574
sceditor.formats.bbcode.set(
575
	'iurl', {
576
		allowsEmpty: true,
577
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
578
		html: function (token, attrs, content) {
579
580
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
581
				attrs.defaultattr = content;
582
583
			return '<a href="' + encodeURI(attrs.defaultattr) + '">' + content + '</a>';
584
		}
585
	}
586
);
587
588
sceditor.formats.bbcode.set(
589
	'pre', {
590
		tags: {
591
			pre: null
592
		},
593
		isBlock: true,
594
		format: "[pre]{0}[/pre]",
595
		html: "<pre>{0}</pre>\n"
596
	}
597
);
598
599
sceditor.formats.bbcode.set(
600
	'php', {
601
		isInline: false,
602
		format: "[php]{0}[/php]",
603
		html: '<code class="php">{0}</code>'
604
	}
605
);
606
607
sceditor.formats.bbcode.set(
608
	'code', {
609
		tags: {
610
			code: null
611
		},
612
		isInline: false,
613
		allowedChildren: ['#', '#newline'],
614
		format: function (element, content) {
615
			if ($(element).hasClass('php'))
616
				return '[php]' + content.replace('&#91;', '[') + '[/php]';
617
618
			var from = '';
619
			if ($(element).children("cite:first").length === 1)
620
			{
621
				from = $(element).children("cite:first").text();
622
623
				$(element).attr({'from': from.php_htmlspecialchars()});
624
625
				from = '=' + from;
626
				content = '';
627
				$(element).children("cite:first").remove();
628
				content = this.elementToBbcode($(element));
629
			}
630
			else
631
			{
632
				if (typeof $(element).attr('from') != 'undefined')
633
				{
634
					from = '=' + $(element).attr('from').php_unhtmlspecialchars();
635
				}
636
			}
637
638
			return '[code' + from + ']' + content.replace('&#91;', '[') + '[/code]';
639
		},
640
		html: function (element, attrs, content) {
641
			var from = '';
642
			if (typeof attrs.defaultattr !== "undefined")
643
				from = '<cite>' + attrs.defaultattr + '</cite>';
644
645
			return '<code>' + from + content.replace('[', '&#91;') + '</code>'
646
		}
647
	}
648
);
649
650
sceditor.formats.bbcode.set(
651
	'quote', {
652
		tags: {
653
			blockquote: null,
654
			cite: null
655
		},
656
		quoteType: $.sceditor.BBCodeParser.QuoteType.never,
657
		breakBefore: false,
658
		isInline: false,
659
		format: function (element, content) {
660
			var element = $(element);
661
			var author = '';
662
			var date = '';
663
			var link = '';
664
665
			// The <cite> contains only the graphic for the quote, so we can skip it
666
			if (element[0].tagName.toLowerCase() === 'cite')
667
				return '';
668
669
			if (element.attr('author'))
670
				author = ' author=' + element.attr('author').php_unhtmlspecialchars();
671
			if (element.attr('link'))
672
				link = ' link=' + element.attr('link');
673
			if (element.attr('date'))
674
				date = ' date=' + element.attr('date');
675
676
			return '[quote' + author + link + date + ']' + content + '[/quote]';
677
		},
678
		html: function (element, attrs, content) {
679
			var attr_author = '', author = '';
680
			var attr_date = '', sDate = '';
681
			var attr_link = '', link = '';
682
683
			if (typeof attrs.author !== "undefined" && attrs.author)
684
			{
685
				attr_author = attrs.author;
686
				author = bbc_quote_from + ': ' + attr_author;
687
			}
688
689
			// Links could be in the form: link=topic=71.msg201#msg201 that would fool javascript, so we need a workaround
690
			// Probably no more necessary
691
			for (var key in attrs)
692
			{
693
				if (key.substr(0, 4) == 'link' && attrs.hasOwnProperty(key))
694
				{
695
					var attr_link = key.length > 4 ? key.substr(5) + '=' + attrs[key] : attrs[key];
696
697
					link = attr_link.substr(0, 7) == 'http://' ? attr_link : smf_scripturl + '?' + attr_link;
698
					author = author == '' ? '<a href="' + link + '">' + bbc_quote_from + ': ' + link + '</a>' : '<a href="' + link + '">' + author + '</a>';
699
				}
700
			}
701
702
			if (typeof attrs.date !== "undefined" && attrs.date)
703
			{
704
				attr_date = attrs.date;
705
				tDate = new Date(attr_date * 1000);
0 ignored issues
show
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...
706
				sDate_string = tDate.toLocaleString();
0 ignored issues
show
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...
707
				sDate = '<date timestamp="' + attr_date + '">' + sDate_string + '</date>';
708
			}
709
710
			if (author == '' && sDate == '')
711
				author = bbc_quote;
712
			else if (author == '' && sDate != '')
713
				author += ' ' + bbc_search_on;
714
715
			content = '<blockquote author="' + attr_author + '" date="' + attr_date + '" link="' + attr_link + '"><cite>' + author + ' ' + sDate + '</cite>' + content + '</blockquote>';
716
717
			return content;
718
		}
719
	}
720
);
721
722
sceditor.formats.bbcode.set('font', {
723
	format: function (element, content) {
724
		var element = $(element);
725
		var font;
726
727
		// Get the raw font value from the DOM
728
		if (!element.is('font') || !(font = element.attr('face'))) {
729
			font = element.css('font-family');
730
		}
731
732
		// Strip all quotes
733
		font = font.replace(/['"]/g, '');
734
735
		return '[font=' + font + ']' + content + '[/font]';
736
	}
737
});
738
739
sceditor.formats.bbcode.set(
740
	'member', {
741
		isInline: true,
742
		format: function (element, content) {
743
			return '[member='+ $(element).attr('data-mention') +']'+ content.replace('@','') +'[/member]';
744
		},
745
		html: function (token, attrs, content) {
746
			if (typeof attrs.defaultattr === "undefined" || attrs.defaultattr.length === 0)
747
				attrs.defaultattr = content;
748
749
			return '<a href="' + smf_scripturl +'?action=profile;u='+ attrs.defaultattr + '" class="mention" data-mention="'+ attrs.defaultattr + '">@'+ content.replace('@','') +'</a>';
750
		}
751
	}
752
);
753
754
sceditor.formats.bbcode.set(
755
	'float', {
756
		tags: {
757
			div: {
758
				"class": ["floatleft", "floatright"],
759
			},
760
		},
761
		isInline: false,
762
		skipLastLineBreak: true,
763
		format: function (element, content) {
764
			var element = $(element);
765
			if (!element.css('float'))
766
				return content;
767
768
			side = (element.css('float').indexOf('left') == 0 ? 'left' : 'right');
0 ignored issues
show
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...
769
			max = ' max=' + (element.css('max-width') != "none" ? element.css('max-width') : '45%');
0 ignored issues
show
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...
770
771
			return '[float=' + side + max + ']' + content + '[/float]';
772
		},
773
		html: function (token, attrs, content) {
774
			if (typeof attrs.defaultattr === "undefined")
775
				return content;
776
777
			floatclass = attrs.defaultattr.indexOf('left') == 0 ? 'floatleft' : 'floatright';
0 ignored issues
show
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...
778
			style = typeof attrs.max !== "undefined" ? ' style="max-width:' + attrs.max + (+attrs.max === parseInt(attrs.max) ? 'px' : '') + ';"' : '';
0 ignored issues
show
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...
779
780
			return '<div class="' + floatclass + '"' + style + '>' + content + '</div>';
781
		}
782
	}
783
);
784
785
sceditor.formats.bbcode.set(
786
	'youtube', {
787
		allowsEmpty: true,
788
		tags: {
789
			div: {
790
				class: 'videocontainer'
791
			}
792
		},
793
		format: function (element, content) {
794
			youtube_id = $(element).find('iframe').data('youtube-id');
0 ignored issues
show
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...
795
796
			if (typeof youtube_id !== "undefined")
797
				return '[youtube]' + youtube_id + '[/youtube]';
798
			else
799
				return content;
800
		},
801
		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>'
802
	}
803
);
804