diff --git a/vendor/assets/javascripts/redactor-rails/redactor.js b/vendor/assets/javascripts/redactor-rails/redactor.js
old mode 100644
new mode 100755
index ca1d943f..9bb202c9
--- a/vendor/assets/javascripts/redactor-rails/redactor.js
+++ b/vendor/assets/javascripts/redactor-rails/redactor.js
@@ -1,10 +1,10 @@
/*
- Redactor v10.0.4
- Updated: November 10, 2014
+ Redactor v10.1.3
+ Updated: June 4, 2015
http://imperavi.com/redactor/
- Copyright (c) 2009-2014, Imperavi LLC.
+ Copyright (c) 2009-2015, Imperavi LLC.
License: http://imperavi.com/redactor/license/
Usage: $('#content').redactor();
@@ -28,9 +28,6 @@
var uuid = 0;
- var reUrlYoutube = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig;
- var reUrlVimeo = /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/;
-
// Plugin
$.fn.redactor = function(options)
{
@@ -94,13 +91,13 @@
// Functionality
$.Redactor = Redactor;
- $.Redactor.VERSION = '10.0.4';
+ $.Redactor.VERSION = '10.1.3';
$.Redactor.modules = ['alignment', 'autosave', 'block', 'buffer', 'build', 'button',
'caret', 'clean', 'code', 'core', 'dropdown', 'file', 'focus',
'image', 'indent', 'inline', 'insert', 'keydown', 'keyup',
'lang', 'line', 'link', 'list', 'modal', 'observe', 'paragraphize',
'paste', 'placeholder', 'progress', 'selection', 'shortcuts',
- 'tabifier', 'tidy', 'toolbar', 'upload', 'utils'];
+ 'tabifier', 'tidy', 'toolbar', 'upload', 'utils', 'linkify'];
$.Redactor.opts = {
@@ -135,6 +132,7 @@
autosaveName: false,
autosaveInterval: 60, // seconds
autosaveOnChange: false,
+ autosaveFields: false,
linkTooltip: true,
linkProtocol: 'http',
@@ -147,14 +145,14 @@
imageFloatMargin: '10px',
imageResizable: true,
- imageUpload: false,
+ imageUpload: null,
imageUploadParam: 'file',
uploadImageField: false,
dragImageUpload: true,
- fileUpload: false,
+ fileUpload: null,
fileUploadParam: 'file',
dragFileUpload: true,
@@ -168,7 +166,7 @@
preSpaces: 4, // or false
tabAsSpaces: false, // true or number of spaces
- tabFocus: true,
+ tabKey: true,
scrollTarget: false,
@@ -179,7 +177,7 @@
toolbarExternal: false, // ID selector
toolbarOverflow: false,
- buttonSource: false,
+ source: true,
buttons: ['html', 'formatting', 'bold', 'italic', 'deleted', 'unorderedlist', 'orderedlist',
'outdent', 'indent', 'image', 'file', 'link', 'alignment', 'horizontalrule'], // + 'underline'
@@ -191,12 +189,17 @@
tabifier: true,
- deniedTags: ['html', 'head', 'link', 'body', 'meta', 'script', 'style', 'applet'],
+ deniedTags: ['script', 'style'],
allowedTags: false, // or array
-
+
+ paragraphizeBlocks: ['table', 'div', 'pre', 'form', 'ul', 'ol', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'dl', 'blockquote', 'figcaption',
+ 'address', 'section', 'header', 'footer', 'aside', 'article', 'object', 'style', 'script', 'iframe', 'select', 'input', 'textarea',
+ 'button', 'option', 'map', 'area', 'math', 'hr', 'fieldset', 'legend', 'hgroup', 'nav', 'figure', 'details', 'menu', 'summary', 'p'],
+
removeComments: false,
replaceTags: [
- ['strike', 'del']
+ ['strike', 'del'],
+ ['b', 'strong']
],
replaceStyles: [
['font-weight:\\s?bold', "strong"],
@@ -323,9 +326,22 @@
underline: 'Underline',
alignment: 'Alignment',
filename: 'Name (optional)',
- edit: 'Edit'
+ edit: 'Edit',
+ upload_label: 'Drop file here or '
+
}
- }
+ },
+
+ linkify: {
+ regexps: {
+ youtube: /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig,
+ vimeo: /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,
+ image: /((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/ig,
+ url: /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/ig,
+ }
+ },
+
+ codemirror: false
};
// Functionality
@@ -343,6 +359,7 @@
META: 91,
SHIFT: 16,
ALT: 18,
+ RIGHT: 39,
LEFT: 37,
LEFT_WIN: 91
},
@@ -370,6 +387,16 @@
// setup allowed and denied tags
this.tidy.setupAllowed();
+ // setup denied tags
+ if (this.opts.deniedTags !== false)
+ {
+ var tags = ['html', 'head', 'link', 'body', 'meta', 'applet'];
+ for (var i = 0; i < tags.length; i++)
+ {
+ this.opts.deniedTags.push(tags[i]);
+ }
+ }
+
// load lang
this.lang.load();
@@ -446,92 +473,130 @@
},
set: function(type)
{
+ // focus
if (!this.utils.browser('msie')) this.$editor.focus();
this.buffer.set();
this.selection.save();
+ // get blocks
this.alignment.blocks = this.selection.getBlocks();
- if (this.opts.linebreaks && this.alignment.blocks[0] === false)
+ this.alignment.type = type;
+
+ // set alignment
+ if (this.alignment.isLinebreaksOrNoBlocks())
{
- this.alignment.setText(type);
+ this.alignment.setText();
}
else
{
- this.alignment.setBlocks(type);
+ this.alignment.setBlocks();
}
+ // sync
this.selection.restore();
this.code.sync();
},
- setText: function(type)
+ setText: function()
{
var wrapper = this.selection.wrap('div');
- $(wrapper).attr('data-tagblock', 'redactor');
- $(wrapper).css('text-align', type);
+ $(wrapper).attr('data-tagblock', 'redactor').css('text-align', this.alignment.type);
},
- setBlocks: function(type)
+ setBlocks: function()
{
$.each(this.alignment.blocks, $.proxy(function(i, el)
{
var $el = this.utils.getAlignmentElement(el);
-
if (!$el) return;
- if (type === '' && typeof($el.data('tagblock')) !== 'undefined')
+ if (this.alignment.isNeedReplaceElement($el))
{
- $el.replaceWith($el.html());
+ this.alignment.replaceElement($el);
}
else
{
- $el.css('text-align', type);
- this.utils.removeEmptyAttr($el, 'style');
+ this.alignment.alignElement($el);
}
-
}, this));
+ },
+ isLinebreaksOrNoBlocks: function()
+ {
+ return (this.opts.linebreaks && this.alignment.blocks[0] === false);
+ },
+ isNeedReplaceElement: function($el)
+ {
+ return (this.alignment.type === '' && typeof($el.data('tagblock')) !== 'undefined');
+ },
+ replaceElement: function($el)
+ {
+ $el.replaceWith($el.html());
+ },
+ alignElement: function($el)
+ {
+ $el.css('text-align', this.alignment.type);
+ this.utils.removeEmptyAttr($el, 'style');
}
};
},
autosave: function()
{
return {
+ html: false,
enable: function()
{
if (!this.opts.autosave) return;
- this.autosave.html = false;
this.autosave.name = (this.opts.autosaveName) ? this.opts.autosaveName : this.$textarea.attr('name');
- if (!this.opts.autosaveOnChange)
- {
- this.autosaveInterval = setInterval($.proxy(this.autosave.load, this), this.opts.autosaveInterval * 1000);
- }
+ if (this.opts.autosaveOnChange) return;
+ this.autosaveInterval = setInterval(this.autosave.load, this.opts.autosaveInterval * 1000);
},
onChange: function()
{
if (!this.opts.autosaveOnChange) return;
-
this.autosave.load();
},
load: function()
{
- var html = this.code.get();
- if (this.autosave.html === html) return;
- if (this.utils.isEmpty(html)) return;
+ this.autosave.source = this.code.get();
+
+ if (this.autosave.html === this.autosave.source) return;
+ //if (this.utils.isEmpty(this.autosave.source)) return;
- $.ajax({
+ // data
+ var data = {};
+ data['name'] = this.autosave.name;
+ data[this.autosave.name] = this.autosave.source;
+ data = this.autosave.getHiddenFields(data);
+
+ // ajax
+ var jsxhr = $.ajax({
url: this.opts.autosave,
type: 'post',
- data: 'name=' + this.autosave.name + '&' + this.autosave.name + '=' + escape(encodeURIComponent(html)),
- success: $.proxy(function(data)
- {
- this.autosave.success(data, html);
-
- }, this)
+ data: data
});
+
+ jsxhr.done(this.autosave.success);
+ },
+ getHiddenFields: function(data)
+ {
+ if (this.opts.autosaveFields === false || typeof this.opts.autosaveFields !== 'object')
+ {
+ return data;
+ }
+
+ $.each(this.opts.autosaveFields, $.proxy(function(k, v)
+ {
+ if (v !== null && v.toString().indexOf('#') === 0) v = $(v).val();
+ data[k] = v;
+
+ }, this));
+
+ return data;
+
},
- success: function(data, html)
+ success: function(data)
{
var json;
try
@@ -547,7 +612,7 @@
var callbackName = (typeof json.error == 'undefined') ? 'autosave' : 'autosaveError';
this.core.setCallback(callbackName, this.autosave.name, json);
- this.autosave.html = html;
+ this.autosave.html = this.autosave.source;
},
disable: function()
{
@@ -560,11 +625,17 @@
return {
formatting: function(name)
{
+ this.block.clearStyle = false;
var type, value;
if (typeof this.formatting[name].data != 'undefined') type = 'data';
else if (typeof this.formatting[name].attr != 'undefined') type = 'attr';
- else if (typeof this.formatting[name].class != 'undefined') type = 'class';
+ else if (typeof this.formatting[name]['class'] != 'undefined') type = 'class';
+
+ if (typeof this.formatting[name].clear != 'undefined')
+ {
+ this.block.clearStyle = true;
+ }
if (type) value = this.formatting[name][type];
@@ -674,6 +745,11 @@
this.block.toggle($(block));
}
+ if (typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
+ {
+ $(block).removeAttr('class').removeAttr('style');
+ }
+
},
setMultiple: function(tag)
{
@@ -749,14 +825,20 @@
{
$.each(this.block.blocks, $.proxy(function(i,s)
{
+ var $formatted = false;
if (this.opts.linebreaks)
{
$(s).prepend('
').append('
');
- this.utils.replaceWithContents(s);
+ $formatted = this.utils.replaceWithContents(s);
}
else
{
- this.utils.replaceToTag(s, 'p');
+ $formatted = this.utils.replaceToTag(s, 'p');
+ }
+
+ if ($formatted && typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
+ {
+ $formatted.removeAttr('class').removeAttr('style');
}
}, this));
@@ -775,7 +857,7 @@
if (this.block.type == 'class')
{
toggleType = 'toggle';
- classSize = $(this.block.blocks).filter('.' + this.block.value).size();
+ classSize = $(this.block.blocks).filter('.' + this.block.value).length;
if (this.block.blocksSize == classSize) toggleType = 'toggle';
else if (this.block.blocksSize > classSize) toggleType = 'set';
@@ -794,7 +876,7 @@
{
if (toggleType == 'toggle') this.block.toggle($formatted);
else if (toggleType == 'remove') this.block.remove($formatted);
- else if (toggleType == 'set') this.block.set2($formatted);
+ else if (toggleType == 'set') this.block.setForce($formatted);
}
else this.block.toggle($formatted);
@@ -802,13 +884,43 @@
if (this.block.isRemoveInline) this.utils.removeInlineTags($formatted);
if (tag == 'p' || this.block.headTag) $formatted.find('p').contents().unwrap();
+ if (typeof this.block.type == 'undefined' && typeof this.block.value == 'undefined')
+ {
+ $formatted.removeAttr('class').removeAttr('style');
+ }
+
}, this));
}
}
},
+ setForce: function($el)
+ {
+ // remove style and class if the specified setting
+ if (this.block.clearStyle)
+ {
+ $el.removeAttr('class').removeAttr('style');
+ }
+
+ if (this.block.type == 'class')
+ {
+ $el.addClass(this.block.value);
+ return;
+ }
+ else if (this.block.type == 'attr' || this.block.type == 'data')
+ {
+ $el.attr(this.block.value.name, this.block.value.value);
+ return;
+ }
+ },
toggle: function($el)
{
+ // remove style and class if the specified setting
+ if (this.block.clearStyle)
+ {
+ $el.removeAttr('class').removeAttr('style');
+ }
+
if (this.block.type == 'class')
{
$el.toggleClass(this.block.value);
@@ -839,7 +951,7 @@
},
formatListToBlockquote: function()
{
- var block = $(this.block.blocks[0]).closest('ul, ol');
+ var block = $(this.block.blocks[0]).closest('ul, ol', this.$editor[0]);
$(block).find('ul, ol').contents().unwrap();
$(block).find('li').append($('
')).contents().unwrap();
@@ -902,7 +1014,7 @@
{
$elements.append('
');
}
-
+
$elements.contents().unwrap();
if (tag != 'p' && tag != 'blockquote') $formatted.find('img').remove();
@@ -932,10 +1044,10 @@
},
formatTableWrapping: function($formatted)
{
- if ($formatted.closest('table').size() === 0) return;
+ if ($formatted.closest('table', this.$editor[0]).length === 0) return;
- if ($formatted.closest('tr').size() === 0) $formatted.wrap('
');
- if ($formatted.closest('td').size() === 0 && $formatted.closest('th').size() === 0)
+ if ($formatted.closest('tr', this.$editor[0]).length === 0) $formatted.wrap('
');
+ if ($formatted.closest('td', this.$editor[0]).length === 0 && $formatted.closest('th').length === 0)
{
$formatted.wrap('');
}
@@ -1090,13 +1202,11 @@
return {
run: function()
{
-
this.build.createContainerBox();
this.build.loadContent();
this.build.loadEditor();
this.build.enableEditor();
this.build.setCodeAndCall();
-
},
isTextarea: function()
{
@@ -1112,13 +1222,7 @@
},
getTextareaName: function()
{
- var name = this.$element.attr('id');
- if (typeof(name) == 'undefined')
- {
- name = 'content-' + this.uuid;
- }
-
- return name;
+ return ((typeof(name) == 'undefined')) ? 'content-' + this.uuid : this.$element.attr('id');
},
loadContent: function()
{
@@ -1161,14 +1265,13 @@
this.build.callEditor();
// code mode
- if (!this.opts.visual)
- {
- setTimeout($.proxy(this.code.showCode, this), 200);
- }
+ if (this.opts.visual) return;
+ setTimeout($.proxy(this.code.showCode, this), 200);
},
callEditor: function()
{
this.build.disableMozillaEditing();
+ this.build.disableIeLinks();
this.build.setEvents();
this.build.setHelpers();
@@ -1204,6 +1307,21 @@
if (this.opts.maxHeight) this.$editor.css('maxHeight', this.opts.maxHeight);
},
+ setEventDropUpload: function(e)
+ {
+ e.preventDefault();
+
+ if (!this.opts.dragImageUpload || !this.opts.dragFileUpload) return;
+
+ var files = e.dataTransfer.files;
+ this.upload.directUpload(files[0], e);
+ },
+ setEventDrop: function(e)
+ {
+ this.code.sync();
+ setTimeout(this.clean.clearUnverified, 1);
+ this.core.setCallback('drop', e);
+ },
setEvents: function()
{
// drop
@@ -1213,28 +1331,16 @@
if (window.FormData === undefined || !e.dataTransfer) return true;
- var length = e.dataTransfer.files.length;
- if (length === 0)
+ if (e.dataTransfer.files.length === 0)
{
- this.code.sync();
- setTimeout($.proxy(this.clean.clearUnverified, this), 1);
- this.core.setCallback('drop', e);
-
- return true;
+ return this.build.setEventDrop(e);
}
else
{
- e.preventDefault();
-
- if (this.opts.dragImageUpload || this.opts.dragFileUpload)
- {
- var files = e.dataTransfer.files;
- this.upload.directUpload(files[0], e);
- }
+ this.build.setEventDropUpload(e);
}
- setTimeout($.proxy(this.clean.clearUnverified, this), 1);
-
+ setTimeout(this.clean.clearUnverified, 1);
this.core.setCallback('drop', e);
}, this));
@@ -1243,11 +1349,8 @@
// click
this.$editor.on('click.redactor', $.proxy(function(e)
{
- var type = 'click';
- if ((this.core.getEvent() == 'click' || this.core.getEvent() == 'arrow'))
- {
- type = false;
- }
+ var event = this.core.getEvent();
+ var type = (event == 'click' || event == 'arrow') ? false : 'click';
this.core.addEvent(type);
this.utils.disableSelectAll();
@@ -1258,12 +1361,15 @@
// paste
this.$editor.on('paste.redactor', $.proxy(this.paste.init, this));
+ // cut
+ this.$editor.on('cut.redactor', $.proxy(this.code.sync, this));
+
// keydown
this.$editor.on('keydown.redactor', $.proxy(this.keydown.init, this));
// keyup
this.$editor.on('keyup.redactor', $.proxy(this.keyup.init, this));
-
+
// textarea keydown
if ($.isFunction(this.opts.codeKeydownCallback))
{
@@ -1283,34 +1389,39 @@
}
var clickedElement;
- $(document).on('mousedown', function(e) {
- clickedElement = $(e.target);
- });
+ $(document).on('mousedown', function(e) { clickedElement = e.target; });
// blur
this.$editor.on('blur.redactor', $.proxy(function(e)
{
if (this.rtePaste) return;
+ if (!this.build.isBlured(clickedElement)) return;
+
+ this.utils.disableSelectAll();
+ if ($.isFunction(this.opts.blurCallback)) this.core.setCallback('blur', e);
- var $el = $(clickedElement);
- if (!$el.hasClass('redactor-toolbar, redactor-dropdown') && !$el.is('#redactor-modal') && $el.parents('.redactor-toolbar, .redactor-dropdown, #redactor-modal').size() === 0)
- {
- this.utils.disableSelectAll();
- if ($.isFunction(this.opts.blurCallback)) this.core.setCallback('blur', e);
- }
}, this));
},
- setHelpers: function()
+ isBlured: function(clickedElement)
{
- // autosave
- this.autosave.enable();
+ var $el = $(clickedElement);
+ return (!$el.hasClass('redactor-toolbar, redactor-dropdown') && !$el.is('#redactor-modal') && $el.parents('.redactor-toolbar, .redactor-dropdown, #redactor-modal').length === 0);
+ },
+ setHelpers: function()
+ {
+ // linkify
+ if (this.linkify.isEnabled())
+ {
+ this.linkify.format();
+ }
+
// placeholder
this.placeholder.enable();
// focus
- if (this.opts.focus) setTimeout($.proxy(this.focus.setStart, this), 100);
- if (this.opts.focusEnd) setTimeout($.proxy(this.focus.setEnd, this), 100);
+ if (this.opts.focus) setTimeout(this.focus.setStart, 100);
+ if (this.opts.focusEnd) setTimeout(this.focus.setEnd, 100);
},
plugins: function()
@@ -1332,6 +1443,7 @@
this[s] = RedactorPlugins[s]();
+ // get methods
var methods = this.getModuleMethods(this[s]);
var len = methods.length;
@@ -1346,7 +1458,6 @@
}, this));
-
},
disableMozillaEditing: function()
{
@@ -1357,6 +1468,13 @@
document.execCommand('enableObjectResizing', false, false);
document.execCommand('enableInlineTableEditing', false, false);
} catch (e) {}
+ },
+ disableIeLinks: function()
+ {
+ if (!this.utils.browser('ie')) return;
+
+ // IE prevent converting links
+ document.execCommand("AutoUrlDetect", false, false);
}
};
},
@@ -1367,34 +1485,16 @@
{
var $button = $('').attr('tabindex', '-1');
+ // click
if (btnObject.func || btnObject.command || btnObject.dropdown)
{
- $button.on('touchstart click', $.proxy(function(e)
- {
- if ($button.hasClass('redactor-button-disabled')) return false;
-
- var type = 'func';
- var callback = btnObject.func;
- if (btnObject.command)
- {
- type = 'command';
- callback = btnObject.command;
- }
- else if (btnObject.dropdown)
- {
- type = 'dropdown';
- callback = false;
- }
-
- this.button.onClick(e, btnName, type, callback);
-
- }, this));
+ this.button.setEvent($button, btnName, btnObject);
}
// dropdown
if (btnObject.dropdown)
{
- var $dropdown = $('');
+ var $dropdown = $(' ');
$button.data('dropdown', $dropdown);
this.dropdown.build(btnName, $dropdown, btnObject.dropdown);
}
@@ -1407,9 +1507,33 @@
return $button;
},
+ setEvent: function($button, btnName, btnObject)
+ {
+ $button.on('touchstart click', $.proxy(function(e)
+ {
+ if ($button.hasClass('redactor-button-disabled')) return false;
+
+ var type = 'func';
+ var callback = btnObject.func;
+
+ if (btnObject.command)
+ {
+ type = 'command';
+ callback = btnObject.command;
+ }
+ else if (btnObject.dropdown)
+ {
+ type = 'dropdown';
+ callback = false;
+ }
+
+ this.button.onClick(e, btnName, type, callback);
+
+ }, this));
+ },
createTooltip: function($button, name, title)
{
- var $tooltip = $(' ').addClass('redactor-toolbar-tooltip redactor-toolbar-tooltip-' + name).hide().html(title);
+ var $tooltip = $('').addClass('redactor-toolbar-tooltip redactor-toolbar-tooltip-' + this.uuid + ' redactor-toolbar-tooltip-' + name).hide().html(title);
$tooltip.appendTo('body');
$button.on('mouseover', function()
@@ -1417,13 +1541,11 @@
if ($(this).hasClass('redactor-button-disabled')) return;
var pos = $button.offset();
- var height = $button.innerHeight();
- var width = $button.innerWidth();
$tooltip.show();
$tooltip.css({
- top: (pos.top + height) + 'px',
- left: (pos.left + width/2 - $tooltip.innerWidth()/2) + 'px'
+ top: (pos.top + $button.innerHeight()) + 'px',
+ left: (pos.left + $button.innerWidth()/2 - $tooltip.innerWidth()/2) + 'px'
});
});
@@ -1435,42 +1557,31 @@
},
onClick: function(e, btnName, type, callback)
{
+ this.button.caretOffset = this.caret.getOffset();
+
e.preventDefault();
if (this.utils.browser('msie')) e.returnValue = false;
- if (type == 'command')
- {
- this.inline.format(callback);
- }
- else if (type == 'dropdown')
- {
- this.dropdown.show(e, btnName);
- }
- else
+ if (type == 'command') this.inline.format(callback);
+ else if (type == 'dropdown') this.dropdown.show(e, btnName);
+ else this.button.onClickCallback(e, callback, btnName);
+ },
+ onClickCallback: function(e, callback, btnName)
+ {
+ var func;
+
+ if ($.isFunction(callback)) callback.call(this, btnName);
+ else if (callback.search(/\./) != '-1')
{
- var func;
- if ($.isFunction(callback))
- {
- callback.call(this, btnName);
- this.observe.buttons(e, btnName);
- }
- else if (callback.search(/\./) != '-1')
- {
- func = callback.split('.');
- if (typeof this[func[0]] != 'undefined')
- {
- this[func[0]][func[1]](btnName);
- this.observe.buttons(e, btnName);
- }
- }
- else
- {
- this[callback](btnName);
- this.observe.buttons(e, btnName);
- }
+ func = callback.split('.');
+ if (typeof this[func[0]] == 'undefined') return;
+
+ this[func[0]][func[1]](btnName);
}
+ else this[callback](btnName);
+ this.observe.buttons(e, btnName);
},
get: function(key)
{
@@ -1486,7 +1597,7 @@
},
setInactiveAll: function(key)
{
- if (typeof key == 'undefined')
+ if (typeof key === 'undefined')
{
this.$toolbar.find('a.re-icon').removeClass('redactor-act');
}
@@ -1518,7 +1629,9 @@
$button.html('');
},
addCallback: function($btn, callback)
- {
+ {
+ if ($btn == "buffer") return;
+
var type = (callback == 'dropdown') ? 'dropdown' : 'func';
var key = $btn.attr('rel');
$btn.on('touchstart click', $.proxy(function(e)
@@ -1533,19 +1646,19 @@
var key = $btn.attr('rel');
this.button.addCallback($btn, 'dropdown');
- var $dropdown = $('');
+ var $dropdown = $(' ');
$btn.data('dropdown', $dropdown);
- if (dropdown)
- {
- this.dropdown.build(key, $dropdown, dropdown);
- }
+ // build dropdown
+ if (dropdown) this.dropdown.build(key, $dropdown, dropdown);
return $dropdown;
},
add: function(key, title)
{
if (!this.opts.toolbar) return;
+
+ if (this.button.isMobileUndoRedo(key)) return "buffer";
var btn = this.button.build(key, { title: title });
btn.addClass('redactor-btn-image');
@@ -1557,8 +1670,11 @@
addFirst: function(key, title)
{
if (!this.opts.toolbar) return;
+
+ if (this.button.isMobileUndoRedo(key)) return "buffer";
var btn = this.button.build(key, { title: title });
+ btn.addClass('redactor-btn-image');
this.$toolbar.prepend($(' ').append(btn));
return btn;
@@ -1566,11 +1682,14 @@
addAfter: function(afterkey, key, title)
{
if (!this.opts.toolbar) return;
+
+ if (this.button.isMobileUndoRedo(key)) return "buffer";
var btn = this.button.build(key, { title: title });
+ btn.addClass('redactor-btn-image');
var $btn = this.button.get(afterkey);
- if ($btn.size() !== 0) $btn.parent().after($('').append(btn));
+ if ($btn.length !== 0) $btn.parent().after($('').append(btn));
else this.$toolbar.append($('').append(btn));
return btn;
@@ -1578,11 +1697,14 @@
addBefore: function(beforekey, key, title)
{
if (!this.opts.toolbar) return;
+
+ if (this.button.isMobileUndoRedo(key)) return "buffer";
var btn = this.button.build(key, { title: title });
+ btn.addClass('redactor-btn-image');
var $btn = this.button.get(beforekey);
- if ($btn.size() !== 0) $btn.parent().before($('').append(btn));
+ if ($btn.length !== 0) $btn.parent().before($('').append(btn));
else this.$toolbar.append($('').append(btn));
return btn;
@@ -1590,6 +1712,10 @@
remove: function(key)
{
this.button.get(key).remove();
+ },
+ isMobileUndoRedo: function(key)
+ {
+ return (key == "undo" || key == "redo") && !this.utils.isDesktop();
}
};
},
@@ -1618,7 +1744,8 @@
set: function(orgn, orgo, focn, foco)
{
// focus
- if (!this.utils.browser('msie')) this.$editor.focus();
+ // disabled in 10.0.7
+ // if (!this.utils.browser('msie')) this.$editor.focus();
orgn = orgn[0] || orgn;
focn = focn[0] || focn;
@@ -1630,15 +1757,16 @@
if (orgn.tagName == 'BR' && this.opts.linebreaks === false)
{
- var par = $(this.opts.emptyHtml)[0];
- $(orgn).replaceWith(par);
- orgn = par;
+ var parent = $(this.opts.emptyHtml)[0];
+ $(orgn).replaceWith(parent);
+ orgn = parent;
focn = orgn;
}
this.selection.get();
- try {
+ try
+ {
this.range.setStart(orgn, orgo);
this.range.setEnd(focn, foco);
}
@@ -1648,7 +1776,8 @@
},
setAfter: function(node)
{
- try {
+ try
+ {
var tag = $(node)[0].tagName;
// inline tag
@@ -1671,7 +1800,8 @@
}
}
}
- catch (e) {
+ catch (e)
+ {
var space = this.utils.createSpaceElement();
$(node).after(space);
this.caret.setEnd(space);
@@ -1736,13 +1866,14 @@
{
var offset = 0;
var sel = window.getSelection();
+
if (sel.rangeCount > 0)
{
var range = window.getSelection().getRangeAt(0);
- var preCaretRange = range.cloneRange();
- preCaretRange.selectNodeContents(this.$editor[0]);
- preCaretRange.setEnd(range.endContainer, range.endOffset);
- offset = preCaretRange.toString().length;
+ var caretRange = range.cloneRange();
+ caretRange.selectNodeContents(this.$editor[0]);
+ caretRange.setEnd(range.endContainer, range.endOffset);
+ offset = caretRange.toString().length;
}
return offset;
@@ -1752,8 +1883,7 @@
if (typeof end == 'undefined') end = start;
if (!this.focus.isFocused()) this.focus.setStart();
- var range = document.createRange();
- var sel = document.getSelection();
+ var sel = this.selection.get();
var node, offset = 0;
var walker = document.createTreeWalker(this.$editor[0], NodeFilter.SHOW_TEXT, null, null);
@@ -1762,20 +1892,21 @@
offset += node.nodeValue.length;
if (offset > start)
{
- range.setStart(node, node.nodeValue.length + start - offset);
+ this.range.setStart(node, node.nodeValue.length + start - offset);
start = Infinity;
}
if (offset >= end)
{
- range.setEnd(node, node.nodeValue.length + end - offset);
+ this.range.setEnd(node, node.nodeValue.length + end - offset);
break;
}
}
- sel.removeAllRanges();
- sel.addRange(range);
+ this.range.collapse(false);
+ this.selection.addRange();
},
+ // deprecated
setToPoint: function(start, end)
{
this.caret.setOffset(start, end);
@@ -1793,12 +1924,15 @@
{
html = this.clean.savePreCode(html);
+ // convert script tag
+ html = html.replace(/');
+
// restore form tag
html = this.clean.restoreFormTags(html);
@@ -1871,15 +2012,23 @@
// remove br in the of li
html = html.replace(new RegExp('
', 'gi'), '');
html = html.replace(new RegExp(' ', 'gi'), '');
-
+
+ // remove empty attributes
+ html = html.replace(/(style|rel)="\s*?"/, '');
+
// remove verified
- html = html.replace(new RegExp(' ])>', 'gi'), ' ');
- html = html.replace(new RegExp('<(.*?) data-verified="redactor"(.*?[^>])>', 'gi'), '<$1$2>');
- html = html.replace(new RegExp(' ])>', 'gi'), '');
- html = html.replace(new RegExp(' ])>', 'gi'), ' ');
- html = html.replace(new RegExp(' ])>', 'gi'), ' ');
- html = html.replace(new RegExp(' ])>', 'gi'), ' ');
- html = html.replace(new RegExp('(.*?)', 'gi'), '$1');
+ html = html.replace(/]) data-tagblock="redactor"(.*?[^>])>/gi, ' ');
+ html = html.replace(/<(.*?) data-verified="redactor"(.*?[^>])>/gi, '<$1$2>');
+
+ var $div = $(" ").html($.parseHTML(html, document, true));
+ $div.find("span").removeAttr("rel");
+
+ html = $div.html();
+
+ // remove rel attribute from img
+ html = html.replace(/ ![]() ])rel="(.*?[^>])"(.*?[^>])>/gi, ' ![]() ');
+
+ html = html.replace(/ (.*?)<\/span>/gi, '$1');
html = html.replace(/ data-save-url="(.*?[^>])"/gi, '');
// remove image resize
@@ -1902,9 +2051,7 @@
}
// reconvert inline
- html = html.replace(/<(.*?) data-redactor-tag="(.*?)"(.*?[^>])>/gi, '<$1$3>');
- html = html.replace(/<(.*?) data-redactor-class="(.*?)"(.*?[^>])>/gi, '<$1$3>');
- html = html.replace(/<(.*?) data-redactor-style="(.*?)"(.*?[^>])>/gi, '<$1$3>');
+ html = html.replace(/\sdata-redactor-(tag|class|style)="(.*?[^>])"/gi, '');
html = html.replace(new RegExp('<(.*?) data-verified="redactor"(.*?[^>])>', 'gi'), '<$1$2>');
html = html.replace(new RegExp('<(.*?) data-verified="redactor">', 'gi'), '<$1>');
@@ -1915,12 +2062,9 @@
html = $.trim(html);
html = html.replace(/\$/g, '$');
- html = html.replace(/”/g, '"');
- html = html.replace(/“/g, '"');
- html = html.replace(/‘/g, '\'');
- html = html.replace(/’/g, '\'');
// convert dirty spaces
+ html = html.replace(//gi, '');
html = html.replace(/ <\/span>/gi, ' ');
html = html.replace(/]*>\t<\/span>/gi, '\t');
html = html.replace(/]*>(\s| )<\/span>/gi, ' ');
@@ -1939,6 +2083,11 @@
if (this.utils.isCurrentOrParent('PRE'))
{
+ html = html.replace(/”/g, '"');
+ html = html.replace(/“/g, '"');
+ html = html.replace(/‘/g, '\'');
+ html = html.replace(/’/g, '\'');
+
return this.clean.getPreCode(html);
}
@@ -2004,6 +2153,7 @@
html = this.clean.onPasteRemoveSpans(html);
html = this.clean.onPasteRemoveEmpty(html);
+
html = this.clean.convertInline(html);
return html;
@@ -2015,21 +2165,106 @@
// style
html = html.replace(/ |