update domain in click to refresh message
[namibia] / public / js / vendor / bootstrap-wysiwyg.js
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.activeToolbarClass) {
28                                         $(options.toolbarSelector).find(toolbarBtnSelector).each(function () {
29                                                 var command = $(this).data(options.commandRole);
30                                                 if (document.queryCommandState(command)) {
31                                                         $(this).addClass(options.activeToolbarClass);
32                                                 } else {
33                                                         $(this).removeClass(options.activeToolbarClass);
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) {
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                 activeToolbarClass: '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); }
199         };
200 }(window.jQuery));