Issues (4542)

js/editor/bootstrap-wysiwyg.js (2 issues)

1
/* http://github.com/mindmup/bootstrap-wysiwyg */
2
/*global jQuery, $, FileReader*/
3
/*jslint browser:true*/
4
(function ($) {
5
	'use strict';
6
	var readFileIntoDataUrl = function (fileInfo) {
7
		var loader = $.Deferred(),
8
			fReader = new FileReader();
9
		fReader.onload = function (e) {
10
			loader.resolve(e.target.result);
11
		};
12
		fReader.onerror = loader.reject;
13
		fReader.onprogress = loader.notify;
14
		fReader.readAsDataURL(fileInfo);
15
		return loader.promise();
16
	};
17
	$.fn.cleanHtml = function () {
18
		var html = $(this).html();
19
		return html && html.replace(/(<br>|\s|<div><br><\/div>|&nbsp;)*$/, '');
20
	};
21
	$.fn.wysiwyg = function (userOptions) {
22
		var editor = this,
23
			selectedRange,
24
			options,
25
			toolbarBtnSelector,
26
			updateToolbar = function () {
27
				if (options.AktifToolbarClass) {
28
					$(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
29
						var command = $(this).data(options.commandRole);
30
						if (document.queryCommandState(command)) {
31
							$(this).addClass(options.AktifToolbarClass);
32
						} else {
33
							$(this).removeClass(options.AktifToolbarClass);
34
						}
35
					});
36
				}
37
			},
38
			execCommand = function (commandWithArgs, valueArg) {
39
				var commandArr = commandWithArgs.split(' '),
40
					command = commandArr.shift(),
41
					args = commandArr.join(' ') + (valueArg || '');
42
				document.execCommand(command, 0, args);
43
				updateToolbar();
44
			},
45
			bindHotkeys = function (hotKeys) {
46
				$.each(hotKeys, function (hotkey, command) {
47
					editor.keydown(hotkey, function (e) {
48
						if (editor.attr('contenteditable') && editor.is(':visible')) {
49
							e.preventDefault();
50
							e.stopPropagation();
51
							execCommand(command);
52
						}
53
					}).keyup(hotkey, function (e) {
54
						if (editor.attr('contenteditable') && editor.is(':visible')) {
55
							e.preventDefault();
56
							e.stopPropagation();
57
						}
58
					});
59
				});
60
			},
61
			getCurrentRange = function () {
62
				var sel = window.getSelection();
63
				if (sel.getRangeAt && sel.rangeCount) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if sel.getRangeAt && sel.rangeCount is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
64
					return sel.getRangeAt(0);
65
				}
66
			},
67
			saveSelection = function () {
68
				selectedRange = getCurrentRange();
69
			},
70
			restoreSelection = function () {
71
				var selection = window.getSelection();
72
				if (selectedRange) {
73
					try {
74
						selection.removeAllRanges();
75
					} catch (ex) {
76
						document.body.createTextRange().select();
77
						document.selection.empty();
78
					}
79
80
					selection.addRange(selectedRange);
81
				}
82
			},
83
			insertFiles = function (files) {
84
				editor.focus();
85
				$.each(files, function (idx, fileInfo) {
86
					if (/^image\//.test(fileInfo.type)) {
87
						$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
88
							execCommand('insertimage', dataUrl);
89
						}).fail(function (e) {
90
							options.fileUploadError("file-reader", e);
91
						});
92
					} else {
93
						options.fileUploadError("unsupported-file-type", fileInfo.type);
94
					}
95
				});
96
			},
97
			markSelection = function (input, color) {
98
				restoreSelection();
99
				if (document.queryCommandSupported('hiliteColor')) {
100
					document.execCommand('hiliteColor', 0, color || 'transparent');
101
				}
102
				saveSelection();
103
				input.data(options.selectionMarker, color);
104
			},
105
			bindToolbar = function (toolbar, options) {
106
				toolbar.find(toolbarBtnSelector).click(function () {
107
					restoreSelection();
108
					editor.focus();
109
					execCommand($(this).data(options.commandRole));
110
					saveSelection();
111
				});
112
				toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
113
114
				toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
115
					var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
116
					this.value = '';
117
					restoreSelection();
118
					if (newValue) {
119
						editor.focus();
120
						execCommand($(this).data(options.commandRole), newValue);
121
					}
122
					saveSelection();
123
				}).on('focus', function () {
124
					var input = $(this);
125
					if (!input.data(options.selectionMarker)) {
126
						markSelection(input, options.selectionColor);
127
						input.focus();
128
					}
129
				}).on('blur', function () {
130
					var input = $(this);
131
					if (input.data(options.selectionMarker)) {
132
						markSelection(input, false);
133
					}
134
				});
135
				toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
136
					restoreSelection();
137
					if (this.type === 'file' && this.files && this.files.length > 0) {
138
						insertFiles(this.files);
139
					}
140
					saveSelection();
141
					this.value = '';
142
				});
143
			},
144
			initFileDrops = function () {
145
				editor.on('dragenter dragover', false)
146
					.on('drop', function (e) {
147
						var dataTransfer = e.originalEvent.dataTransfer;
148
						e.stopPropagation();
149
						e.preventDefault();
150
						if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
151
							insertFiles(dataTransfer.files);
152
						}
153
					});
154
			};
155
		options = $.extend({}, $.fn.wysiwyg.defaults, userOptions);
156
		toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
157
		bindHotkeys(options.hotKeys);
158
		if (options.dragAndDropImages) {
159
			initFileDrops();
160
		}
161
		bindToolbar($(options.toolbarSelector), options);
162
		editor.attr('contenteditable', true)
163
			.on('mouseup keyup mouseout', function () {
164
				saveSelection();
165
				updateToolbar();
166
			});
167
		$(window).bind('touchend', function (e) {
168
			var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
169
				currentRange = getCurrentRange(),
170
				clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
171
			if (!clear || isInside) {
172
				saveSelection();
173
				updateToolbar();
174
			}
175
		});
176
		return this;
177
	};
178
	$.fn.wysiwyg.defaults = {
179
		hotKeys: {
180
			'ctrl+b meta+b': 'bold',
181
			'ctrl+i meta+i': 'italic',
182
			'ctrl+u meta+u': 'underline',
183
			'ctrl+z meta+z': 'undo',
184
			'ctrl+y meta+y meta+shift+z': 'redo',
185
			'ctrl+l meta+l': 'justifyleft',
186
			'ctrl+r meta+r': 'justifyright',
187
			'ctrl+e meta+e': 'justifycenter',
188
			'ctrl+j meta+j': 'justifyfull',
189
			'shift+tab': 'outdent',
190
			'tab': 'indent'
191
		},
192
		toolbarSelector: '[data-role=editor-toolbar]',
193
		commandRole: 'edit',
194
		AktifToolbarClass: 'btn-info',
195
		selectionMarker: 'edit-focus-marker',
196
		selectionColor: 'darkgrey',
197
		dragAndDropImages: true,
198
		fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
199
	};
200
}(window.jQuery));
201