'offset',
'paragraphize',
'paste',
- 'placeholder',
+ 'placeholder', // Unsupported module
'progress', // Unsupported module
'selection',
'shortcuts',
attr = 'class';
}
- this.placeholder.hide();
this.buffer.set();
return (this.utils.isCollapsed()) ? this.block.formatCollapsed(tag,
build: function () {
return {
start: function () {
- if (this.opts.type === 'inline') {
- this.opts.type = 'inline';
- }
- else if (this.opts.type === 'div') {
- // empty
- var html = $.trim(this.$editor.html());
- if (html === '') {
- this.$editor.html(this.opts.emptyHtml);
- }
-
- this.build.buildTextarea();
- }
- else if (this.opts.type === 'textarea') {
- this.build.startTextarea();
+ if (this.opts.type !== 'textarea') {
+ throw new Error('Only `<textarea>` types are allowed.');
}
+ this.build.startTextarea();
+
// set in
this.build.setIn();
return (typeof name === 'undefined') ? 'content-' + this.uuid : name;
},
- buildTextarea: function () {
- this.$textarea = $('<textarea>');
- this.$textarea.attr('name', this.build.getName());
- this.$textarea.hide();
- this.$element.after(this.$textarea);
-
- this.build.setStartAttrs();
- },
+ buildTextarea: function () {},
loadFromTextarea: function () {
this.$editor = $('<div />');
if (this.opts.type === 'inline' || this.opts.type === 'pre') {
this.opts.toolbarMobile = false;
this.opts.toolbar = false;
- this.opts.air = false;
- this.opts.linkify = false;
}
this.build.setHelpers();
// init buttons
- if (this.opts.toolbar || this.opts.air) {
- this.toolbarsButtons = this.button.init();
- }
+ this.toolbarsButtons = this.button.init();
// load toolbar
- if (this.opts.air) {
- this.air.build();
- }
- else if (this.opts.toolbar) {
- this.toolbar.build();
- }
-
- if (this.detect.isMobile() && this.opts.toolbarMobile && this.opts.air) {
- this.opts.toolbar = true;
- this.toolbar.build();
- }
+ this.toolbar.build();
// observe dropdowns
- if (this.opts.air || this.opts.toolbar) {
- this.core.editor().on(
- 'mouseup.redactor-observe.' + this.uuid + ' keyup.redactor-observe.' + this.uuid + ' focus.redactor-observe.' + this.uuid + ' touchstart.redactor-observe.' + this.uuid,
- $.proxy(this.observe.toolbar, this)
- );
- this.core.element().on('blur.callback.redactor', $.proxy(function () {
- this.button.setInactiveAll();
-
- }, this));
- }
+ this.core.editor().on(
+ 'mouseup.redactor-observe.' + this.uuid + ' keyup.redactor-observe.' + this.uuid + ' focus.redactor-observe.' + this.uuid + ' touchstart.redactor-observe.' + this.uuid,
+ $.proxy(this.observe.toolbar, this)
+ );
+ this.core.element().on('blur.callback.redactor', $.proxy(function () {
+ this.button.setInactiveAll();
+
+ }, this));
// modal templates init
this.modal.templates();
// plugins
this.build.plugins();
- // autosave
- this.autosave.init();
-
// sync code
this.code.html = this.code.cleaned(this.core.editor().html());
this.core.callback('init');
this.core.callback('initToEdit');
- // get images & files list
- this.storage.observe();
-
// started
this.start = false;
},
setHelpers: function () {
- // linkify
- if (this.opts.linkify) {
- this.linkify.format();
- }
-
- // placeholder
- this.placeholder.init();
-
// focus
if (this.opts.focus) {
setTimeout(this.focus.start, 100);
}
// init
- if ($.isFunction(this[s].init)) {
+ if (typeof this[s].init === 'function') {
this[s].init();
}
-
}, this));
}
};
},
setFormatting: function () {
- $.each(this.toolbarsButtons.format.dropdown, $.proxy(function (i, s) {
- if ($.inArray(i, this.opts.formatting) === -1) {
- delete this.toolbarsButtons.format.dropdown[i];
+ for (var key in this.toolbarsButtons.format.dropdown) {
+ if (this.toolbarsButtons.format.dropdown.hasOwnProperty(key) && this.opts.formatting.indexOf(key) === -1) {
+ delete this.toolbarsButtons.format.dropdown[key];
}
-
- }, this));
+ }
},
hideButtons: function () {
load: function ($toolbar) {
this.button.buttons = [];
- $.each(this.opts.buttons, $.proxy(function (i, btnName) {
- if (!this.toolbarsButtons[btnName] || (btnName === 'file' && !this.file.is()) || (btnName === 'image' && !this.image.is())) {
+ this.opts.buttons.forEach((function(btnName) {
+ if (btnName === 'image' && !this.image.is()) {
return;
}
- $toolbar.append($('<li>').append(this.button.build(btnName,
- this.toolbarsButtons[btnName]
- )));
-
- }, this));
- },
- buildButtonTooltip: function ($btn, title) {
- if (typeof this.button.toolbar() === 'undefined') return;
- if (this.opts.air || this.detect.isMobile()) return;
-
- var $tooltip = $('<span>');
- $tooltip.addClass('re-button-tooltip');
- $tooltip.html(title);
-
- var self = this;
- var $toolbar = this.button.toolbar();
- var $box = $toolbar.closest('.redactor-toolbar-box');
- $box = ($box.length === 0) ? $toolbar : $box;
- $box.prepend($tooltip);
- $btn.on('mouseover', function () {
- if ($(this).hasClass('redactor-button-disabled')) {
- return;
+ if (this.toolbarsButtons.hasOwnProperty(btnName)) {
+ var listItem = elCreate('li');
+ listItem.appendChild(this.button.build(btnName,
+ this.toolbarsButtons[btnName]
+ )[0]);
+ $toolbar[0].appendChild(listItem);
}
-
- var pos = ($toolbar.hasClass('toolbar-fixed-box')) ? $btn.offset() : $btn.position();
- pos = (self.opts.toolbarFixedTarget !== document) ? $btn.position() : pos;
- var top = ($toolbar.hasClass('toolbar-fixed-box')) ? $btn.position().top : pos.top;
- var height = $btn.innerHeight();
- var width = $btn.innerWidth();
- var posBox = ($toolbar.hasClass('toolbar-fixed-box')) ? 'fixed' : 'absolute';
- posBox = (self.opts.toolbarFixedTarget !== document) ? 'absolute' : posBox;
- var scrollFix = (self.opts.toolbarFixedTarget !== document) ? $toolbar.position().top : 0;
-
- $tooltip.show();
- $tooltip.css({
- top: (top + height + scrollFix) + 'px',
- left: (pos.left + width / 2 - $tooltip.innerWidth() / 2) + 'px',
- position: posBox
- });
-
- }).on('mouseout', function () {
- $tooltip.hide();
- });
+ }).bind(this));
},
+ buildButtonTooltip: function () {},
build: function (btnName, btnObject) {
- if (this.opts.toolbar === false) {
- return;
- }
-
- var title = (typeof btnObject.label !== 'undefined') ? btnObject.label : btnObject.title;
- var $button = $('<a href="javascript:void(null);" alt="' + title + '" rel="' + btnName + '" />');
+ var $button = $('<a href="javascript:void(null);" rel="' + btnName + '" />');
$button.addClass('re-button re-' + btnName);
$button.attr({
'role': 'button',
- 'aria-label': title,
'tabindex': '-1'
});
- if (typeof btnObject.icon !== 'undefined' && !this.opts.buttonsTextLabeled) {
- var $icon = $('<i>');
- $icon.addClass('re-icon-' + btnName);
-
- $button.append($icon);
- $button.addClass('re-button-icon');
-
- this.button.buildButtonTooltip($button, title);
- }
- else {
- $button.html(btnObject.title);
- }
+ $button.html(btnObject.title);
// click
if (btnObject.func || btnObject.command || btnObject.dropdown) {
this.dropdown.hideAll(false);
}
- if (this.opts.air && type !== 'dropdown') {
- this.air.hide(e);
- }
-
if (this.detect.isIe() || !this.detect.isDesktop()) {
this.utils.unfreezeScroll();
}
setIcon: function ($btn, icon) {
if (!this.opts.buttonsTextLabeled) {
$btn.html(icon).addClass('re-button-icon');
- this.button.buildButtonTooltip($btn, $btn.attr('alt'));
}
},
changeIcon: function (key, newIconClass) {
return {
onSet: function (html) {
html = this.clean.savePreCode(html);
- html = this.clean.saveFormTags(html);
// convert script tag
if (this.opts.script) {
return html;
},
saveFormTags: function (html) {
- return html.replace(
- /<form(.*?)>([\w\W]*?)<\/form>/gi,
- '<section$1 rel="redactor-form-tag">$2</section>'
- );
+ return html;
},
restoreFormTags: function (html) {
return html.replace(
''
);
- // clean
- if (this.opts.type === 'textarea') {
- html = this.clean.onSet(html);
- }
- else if (this.opts.type === 'div' && html === '') {
- html = this.opts.emptyHtml;
- }
+ html = this.clean.onSet(html);
html = html.replace(
/<p><span id="selection-marker-1" class="redactor-selection-marker">​<\/span><\/p>/,
this.events.stopDetectChanges();
this.core.editor().html(html);
+
this.observe.load();
this.events.startDetectChanges();
},
if (this.opts.type === 'textarea') {
this.code.sync();
}
-
- this.placeholder.enable();
},
get: function () {
if (this.opts.type === 'textarea') {
this.core.callback('destroy');
- // placeholder
- this.placeholder.destroy();
-
- // progress
- this.progress.destroy();
-
// help label
$('#redactor-voice-' + this.uuid).remove();
this.$element.val(html).show();
}
- // air
- if (this.opts.air) {
- this.$air.remove();
- }
-
if (this.opts.toolbar && this.$toolbar) {
this.$toolbar.remove();
}
// hide link's tooltip
$('.redactor-link-tooltip').remove();
-
- // autosave
- clearInterval(this.autosaveTimeout);
}
};
},
this.code.sync();
- // autosave
- if (this.autosave.is()) {
-
- clearTimeout(this.autosaveTimeout);
- this.autosaveTimeout = setTimeout($.proxy(this.autosave.send, this),
- 300
- );
- }
-
},
onDropUpload: function (e) {
e.preventDefault();
return;
}
- this.placeholder.hide();
var $figure = $('<' + this.opts.imageTag + '>');
$img = $('<img>');
var pre = this.utils.isTag(this.selection.current(), 'pre');
if (direct) {
- this.air.collapsed();
this.marker.remove();
var node = this.insert.nodeToPoint(e, this.marker.get());
this.buffer.set();
// insert
- this.air.collapsed();
-
if (pre) {
$(pre).after($figure);
}
}
this.events.dropImage = false;
- this.storage.add({
- type: type,
- node: $img[0],
- url: json.url,
- id: id
- });
var nextNode = $img[0].nextSibling;
var $nextFigure = $figure.next();
this.utils.restoreScroll();
this.observe.image = false;
this.events.startDetectChanges();
- this.placeholder.enable();
this.code.sync();
}
// Arrange tag
tag = this.inline.arrangeTag(tag);
- this.placeholder.hide();
this.buffer.set();
(this.utils.isCollapsed()) ? this.inline.formatCollapsed(tag,
insert: function () {
return {
set: function (html) {
- this.placeholder.hide();
-
this.code.set(html);
this.focus.end();
-
- this.placeholder.enable();
},
html: function (html, data) {
- this.placeholder.hide();
this.core.editor().focus();
var block = this.selection.block();
if (data.pre) this.clean.cleanPre();
this.caret.end(endNode);
- this.linkify.format();
},
text: function (text) {
text = text.toString();
return;
}
- this.placeholder.hide();
this.core.editor().focus();
// blocks
}
this.utils.disableSelectAll();
- this.linkify.format();
this.clean.normalizeCurrentHeading();
},
raw: function (html) {
- this.placeholder.hide();
this.core.editor().focus();
var sel = this.selection.get();
}
},
node: function (node, deleteContent) {
- this.placeholder.hide();
-
if (typeof this.start !== 'undefined') {
this.core.editor().focus();
}
if (last) {
this.caret.end(last);
}
-
- this.linkify.format();
},
placeHtml: function (html) {
var marker = document.createElement('span');
this.selection.update(sel, range);
},
nodeToPoint: function (e, node) {
- this.placeholder.hide();
-
node = node[0] || node;
if (this.utils.isEmpty()) {
if (key === this.keyCode.BACKSPACE || key === this.keyCode.DELETE) {
if (this.utils.isSelectAll()) {
this.focus.start();
- this.toolbar.setUnfixed();
return;
}
this.selection.restore();
}
}
-
- // linkify
- if (this.linkify.isKey(key)) {
- this.selection.save();
- this.linkify.format();
- this.selection.restore();
- }
-
}
};
formData.append('clipboard', 1);
formData.append(this.opts.imageUploadParam, blob);
- this.progress.show();
this.upload.send(formData, false);
this.code.sync();
this.rtePaste = false;
formData.append('clipboard', 1);
formData.append(this.opts.imageUploadParam, blob);
- this.progress.show();
this.upload.send(formData, e);
this.rtePaste = false;
},
};
},
- // =placeholder
+ // =placeholder -- UNSUPPORTED MODULE
placeholder: function () {
return {
-
- // public
- enable: function () {
- setTimeout($.proxy(function () {
- return (this.placeholder.isEditorEmpty()) ? this.placeholder.show() : this.placeholder.hide();
-
- }, this), 5);
- },
- show: function () {
- this.core.editor().addClass('redactor-placeholder');
- },
- update: function (text) {
- this.opts.placeholder = text;
- this.core.editor().attr('placeholder', text);
- },
- hide: function () {
- this.core.editor().removeClass('redactor-placeholder');
- },
- is: function () {
- return this.core.editor().hasClass('redactor-placeholder');
- },
-
- // private
- init: function () {
- if (!this.placeholder.enabled()) {
- return;
- }
-
- if (!this.utils.isEditorRelative()) {
- this.utils.setEditorRelative();
- }
-
- this.placeholder.build();
- this.placeholder.buildPosition();
- this.placeholder.enable();
- this.placeholder.enableEvents();
-
- },
- enabled: function () {
- return (this.opts.placeholder) ? this.core.element().attr('placeholder',
- this.opts.placeholder
- ) : this.placeholder.isAttr();
- },
- enableEvents: function () {
- this.core.editor().on('keydown.redactor-placeholder.' + this.uuid,
- $.proxy(this.placeholder.enable, this)
- );
- },
- disableEvents: function () {
- this.core.editor().off('.redactor-placeholder.' + this.uuid);
- },
- build: function () {
- this.core.editor().attr('placeholder', this.core.element().attr('placeholder'));
- },
- buildPosition: function () {
- var $style = $('<style />');
- $style.addClass('redactor-placeholder-style-tag');
- $style.html('#' + this.core.id() + '.redactor-placeholder::after ' + this.placeholder.getPosition());
-
- $('head').append($style);
- },
- getPosition: function () {
- return '{ top: ' + this.core.editor().css('padding-top') + '; left: ' + this.core.editor().css(
- 'padding-left') + '; }';
- },
- isEditorEmpty: function () {
- var html = $.trim(this.core.editor().html()).replace(/[\t\n]/g, '');
- var states = ['', '<p>​</p>', '<p>​<br></p>', this.opts.emptyHtmlRendered];
-
- return ($.inArray(html, states) !== -1);
- },
- isAttr: function () {
- return (typeof this.core.element().attr('placeholder') !== 'undefined' && this.core.element().attr(
- 'placeholder') !== '');
- },
- destroy: function () {
- this.core.editor().removeAttr('placeholder');
-
- this.placeholder.hide();
- this.placeholder.disableEvents();
-
- $('.redactor-placeholder-style-tag').remove();
- }
+ enable: function () {},
+ show: function () {},
+ update: function () {},
+ hide: function () {},
+ is: function () {},
+ init: function () {},
+ enabled: function () {},
+ enableEvents: function () {},
+ disableEvents: function () {},
+ build: function () {},
+ buildPosition: function () {},
+ getPosition: function () {},
+ isEditorEmpty: function () {},
+ isAttr: function () {},
+ destroy: function () {}
};
},
this.button.hideButtons();
this.button.hideButtonsOnMobile();
- this.$toolbarBox = $('<div />').addClass('redactor-toolbar-box');
- this.$toolbar = this.toolbar.createContainer();
- this.$toolbarBox.append(this.$toolbar);
+ this.$toolbarBox = $('<div class="redactor-toolbar-box" />');
+ this.$toolbarBox[0].innerHTML = '<ul class="redactor-toolbar" id="redactor-toolbar-' + this.uuid + '" role="toolbar"></ul>';
+ this.$toolbar = $(this.$toolbarBox[0].children[0]);
+ this.$box[0].insertBefore(this.$toolbarBox[0], this.$box[0].firstChild);
- this.toolbar.append();
this.button.$toolbar = this.$toolbar;
this.button.setFormatting();
this.button.load(this.$toolbar);
-
- this.toolbar.setOverflow();
- this.toolbar.setFixed();
-
- },
- createContainer: function () {
- return $('<ul>').addClass('redactor-toolbar').attr({
- 'id': 'redactor-toolbar-' + this.uuid,
- 'role': 'toolbar'
- });
- },
- append: function () {
- if (this.opts.toolbarExternal) {
- this.$toolbar.addClass('redactor-toolbar-external');
- $(this.opts.toolbarExternal).html(this.$toolbarBox);
- }
- else {
- if (this.opts.type === 'textarea') {
- this.$box.prepend(this.$toolbarBox);
- }
- else {
- this.$element.before(this.$toolbarBox);
- }
-
- }
- },
- setOverflow: function () {
- if (this.opts.toolbarOverflow) {
- this.$toolbar.addClass('redactor-toolbar-overflow');
- }
- },
- setFixed: function () {
- if (!this.opts.toolbarFixed || this.opts.toolbarExternal) {
- return;
- }
-
- if (this.opts.toolbarFixedTarget !== document) {
- var $el = $(this.opts.toolbarFixedTarget);
- this.toolbar.toolbarOffsetTop = ($el.length === 0) ? 0 : this.core.box().offset().top - $el.offset().top;
- }
-
- // bootstrap modal fix
- var late = (this.core.box().closest('.modal-body').length !== 0) ? 1000 : 0;
-
- setTimeout($.proxy(function () {
- var self = this;
- this.toolbar.observeScroll(false);
- if (this.detect.isDesktop()) {
- $(this.opts.toolbarFixedTarget).on('scroll.redactor.' + this.uuid,
- function () {
- if (self.core.editor().height() < 100 || self.placeholder.isEditorEmpty()) {
- return;
- }
-
- self.toolbar.observeScroll();
- }
- );
- }
- else {
- $(this.opts.toolbarFixedTarget).on('scroll.redactor.' + this.uuid,
- function () {
- if (self.core.editor().height() < 100 || self.placeholder.isEditorEmpty()) {
- return;
- }
-
- self.core.toolbar().hide();
- clearTimeout($.data(this, 'scrollCheck'));
- $.data(this,
- 'scrollCheck',
- setTimeout(function () {
- self.core.toolbar().show();
- self.toolbar.observeScroll();
- }, 250)
- );
-
- }
- );
- }
-
- }, this), late);
-
- },
- setUnfixed: function () {
- this.toolbar.observeScrollDisable();
- },
- getBoxTop: function () {
- return (this.opts.toolbarFixedTarget === document) ? this.core.box().offset().top : this.toolbar.toolbarOffsetTop;
- },
- observeScroll: function (start) {
- // tolerance 0 if redactor in the hidden layer
- var tolerance = 0;
-
- if (start !== false) {
- tolerance = (this.opts.toolbarFixedTarget === document) ? 20 : 0;
- }
-
- var scrollTop = $(this.opts.toolbarFixedTarget).scrollTop();
- var boxTop = this.toolbar.getBoxTop();
-
- if (scrollTop === boxTop) {
- return;
- }
-
- if ((scrollTop + this.opts.toolbarFixedTopOffset + tolerance) > boxTop) {
- this.toolbar.observeScrollEnable(scrollTop, boxTop);
- }
- else {
- this.toolbar.observeScrollDisable();
- }
- },
- observeScrollResize: function () {
- this.$toolbar.css({
-
- width: this.core.box().innerWidth(),
- left: this.core.box().offset().left
-
- });
- },
- observeScrollEnable: function (scrollTop, boxTop) {
- if (typeof this.fullscreen !== 'undefined' && this.fullscreen.isOpened === false) {
- this.toolbar.observeScrollDisable();
- return;
- }
-
- var end = boxTop + this.core.box().outerHeight() - 32;
- var width = this.core.box().innerWidth();
-
- var position = (this.detect.isDesktop()) ? 'fixed' : 'absolute';
- var top = (this.detect.isDesktop()) ? this.opts.toolbarFixedTopOffset : ($(this.opts.toolbarFixedTarget).scrollTop() - boxTop + this.opts.toolbarFixedTopOffset);
- var left = (this.detect.isDesktop()) ? this.core.box().offset().left : 0;
-
- if (this.opts.toolbarFixedTarget !== document) {
- position = 'absolute';
- top = this.opts.toolbarFixedTopOffset + $(this.opts.toolbarFixedTarget).scrollTop() - boxTop;
- left = 0;
- }
-
- this.$toolbar.addClass('toolbar-fixed-box');
-
- this.$toolbar.css({
- position: position,
- width: width,
- top: top,
- left: left
- });
-
- if (scrollTop > end) {
- $('.redactor-dropdown-' + this.uuid + ':visible').hide();
- }
-
- this.toolbar.setDropdownsFixed();
-
- this.$toolbar.css('visibility', (scrollTop < end) ? 'visible' : 'hidden');
- $(window).on('resize.redactor-toolbar.' + this.uuid,
- $.proxy(this.toolbar.observeScrollResize, this)
- );
},
- observeScrollDisable: function () {
- this.$toolbar.css({
- position: 'relative',
- width: 'auto',
- top: 0,
- left: 0,
- visibility: 'visible'
- });
-
- this.toolbar.unsetDropdownsFixed();
- this.$toolbar.removeClass('toolbar-fixed-box');
- $(window).off('resize.redactor-toolbar.' + this.uuid);
- },
- setDropdownsFixed: function () {
- var position = (this.opts.toolbarFixedTarget === document && this.detect.isDesktop()) ? 'fixed' : 'absolute';
- this.toolbar.setDropdownPosition(position);
- },
- unsetDropdownsFixed: function () {
- this.toolbar.setDropdownPosition('absolute');
- },
- setDropdownPosition: function (position) {
- var self = this;
- $('.redactor-dropdown-' + this.uuid).each(function () {
- var $el = $(this);
- var $button = self.button.get($el.attr('rel'));
- var top = (position === 'fixed') ? self.opts.toolbarFixedTopOffset : $button.offset().top;
-
- $el.css({
- position: position,
- top: ($button.innerHeight() + top) + 'px'
- });
- });
- }
+ createContainer: function () {},
+ append: function () {},
+ setOverflow: function () {},
+ setFixed: function () {},
+ setUnfixed: function () {},
+ getBoxTop: function () {},
+ observeScroll: function () {},
+ observeScrollResize: function () {},
+ observeScrollEnable: function () {},
+ observeScrollDisable: function () {},
+ setDropdownsFixed: function () {},
+ unsetDropdownsFixed: function () {},
+ setDropdownPosition: function () {}
};
},