1 if (!RedactorPlugins
) var RedactorPlugins
= {};
4 * Provides utility methods extending $.Redactor
6 * @author Alexander Ebert
7 * @copyright 2001-2014 WoltLab GmbH
8 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
10 RedactorPlugins
.wutil
= {
12 * autosave worker process
13 * @var WCF.PeriodicalExecuter
15 _autosaveWorker
: null,
18 * Initializes the RedactorPlugins.wutil plugin.
21 // convert HTML to BBCode upon submit
22 this.$source
.parents('form').submit($.proxy(this.submit
, this));
24 if (this.getOption('wautosave').active
) {
25 this.autosaveEnable();
27 if (this.getOption('wautosave').saveOnInit
|| this.$source
.data('saveOnInit')) {
28 this._saveTextToStorage();
31 this.autosaveRestore();
35 // prevent Redactor's own autosave
36 this.setOption('autosave', false);
38 // disable autosave on destroy
39 var $mpDestroy
= this.destroy
;
41 this.destroy = function() {
42 self
.autosaveDisable();
43 $mpDestroy
.call(self
);
48 * Allows inserting of text contents in Redactor's source area.
50 * @param string string
53 insertAtCaret: function(string
) {
54 if (this.opts
.visual
) {
55 console
.debug("insertAtCaret() failed: Editor is in WYSIWYG-mode.");
60 var $position
= this.$source
.getCaret();
61 if ($position
== -1) {
62 console
.debug("insertAtCaret() failed: Source is not input[type=text], input[type=password] or textarea.");
65 var $content
= this.$source
.val();
66 $content
= $content
.substr(0, $position
) + string
+ $content
.substr($position
);
67 this.$source
.val($content
);
73 * Inserts content into the editor depending if it is in wysiwyg or plain mode. If 'plainValue' is
74 * null or undefined, the value from 'html' will be taken instead.
77 * @param string plainValue
79 insertDynamic: function(html
, plainValue
) {
80 if (this.inWysiwygMode()) {
81 this.insertHtml(html
);
84 if (plainValue
=== undefined || plainValue
=== null) {
88 this.insertAtCaret(plainValue
);
93 * Sets an option value after initialization.
98 setOption: function(key
, value
) {
99 this.opts
[key
] = value
;
103 * Reads an option value, returns null if key is unknown.
108 getOption: function(key
) {
109 if (this.opts
[key
]) {
110 return this.opts
[key
];
117 * Returns true if editor is in source mode.
121 inPlainMode: function() {
122 return !this.opts
.visual
;
126 * Returns true if editor is in WYSIWYG mode.
130 inWysiwygMode: function() {
131 return (this.opts
.visual
);
135 * Replaces all ranges from the current selection with the provided one.
137 * @param DOMRange range
139 replaceRangesWith: function(range
) {
140 getSelection().removeAllRanges();
141 getSelection().addRange(range
);
145 * Returns text using BBCodes.
149 getText: function() {
150 if (this.inWysiwygMode()) {
153 var $content
= this.$source
.val();
159 return this.$source
.val();
163 * Converts HTML to BBCode upon submit.
166 if (this.inWysiwygMode()) {
169 var $content
= this.$source
.val();
173 this.$source
.val($content
);
176 this.autosavePurge();
180 * Resets the editor's contents.
183 if (this.inWysiwygMode()) {
184 this.$editor
.empty();
188 this.$source
.val('');
193 * Enables automatic saving every minute.
197 autosaveEnable: function(key
) {
198 if (!this.getOption('wautosave').active
) {
199 this.setOption('wautosave', {
205 if (this._autosaveWorker
=== null) {
207 this._autosaveWorker
= new WCF
.PeriodicalExecuter($.proxy(this._saveTextToStorage
, this), 60 * 1000);
214 * Saves current editor text to local browser storage.
216 _saveTextToStorage: function() {
217 localStorage
.setItem(this.getOption('wautosave').key
, this.getText());
221 * Disables automatic saving.
223 autosaveDisable: function() {
224 if (!this.getOption('wautosave').active
) {
228 this._autosaveWorker
.stop();
229 this._autosaveWorker
= null;
231 this.setOption('wautosave', {
240 * Attempts to purge saved text.
244 autosavePurge: function() {
245 localStorage
.removeItem(this.getOption('wautosave').key
);
249 * Attempts to restore a saved text.
251 autosaveRestore: function() {
252 var $options
= this.getOption('wautosave');
253 var $text
= localStorage
.getItem($options
.key
);
254 if ($text
!== null) {
255 if (this.inWysiwygMode()) {
257 this.$source
.val($text
);
262 this.$source
.val($text
);
272 * Replaces one button with a new one.
274 * @param string target
276 * @param string title
277 * @param object callback
278 * @param object dropdown
281 buttonReplace: function(target
, key
, title
, callback
, dropdown
) {
282 var $target
= this.buttonGet(target
);
284 var $button
= this.buttonAddAfter(target
, key
, title
, callback
, dropdown
);
285 if ($target
.parent().hasClass('separator')) {
286 $button
.parent().addClass('separator');
289 $target
.parent().remove();
295 * Removes the unicode zero-width space (0x200B).
297 * @param string string
300 removeZeroWidthSpace: function(string
) {
303 for (var $i
= 0, $length
= string
.length
; $i
< $length
; $i
++) {
304 var $byte = string
.charCodeAt($i
).toString(16);
305 if ($byte != '200b') {
306 $string
+= string
[$i
];