@bigfishtv/cockpit
Version:
177 lines (140 loc) • 4.96 kB
JavaScript
var $ = require('jquery');
if(typeof window.RedactorPlugins == 'undefined') window.RedactorPlugins = {};
var RedactorPlugins = window.RedactorPlugins;
RedactorPlugins.source = function() {
return {
init: function() {
var button = this.button.addFirst('html', 'HTML');
this.button.addCallback(button, this.source.toggle);
var style = {
'width': '100%',
'margin': '0',
'background': '#111',
'box-sizing': 'border-box',
'color': 'rgba(255, 255, 255, .8)',
'font-size': '14px',
'outline': 'none',
'padding': '16px',
'line-height': '22px',
'font-family': 'Menlo, Monaco, Consolas, "Courier New", monospace'
};
this.source.$textarea = $('<textarea />');
this.source.$textarea.css(style).hide();
if (this.opts.type === 'textarea') {
this.core.box().append(this.source.$textarea);
}
else
{
this.core.box().after(this.source.$textarea);
}
this.core.element().on('destroy.callback.redactor', $.proxy(function() {
this.source.$textarea.remove();
}, this));
},
toggle: function() {
return (this.source.$textarea.hasClass('open')) ? this.source.hide() : this.source.show();
},
setCaretOnShow: function() {
this.source.offset = this.offset.get();
var scroll = $(window).scrollTop();
var width = this.core.editor().innerWidth();
var height = this.core.editor().innerHeight();
// caret position sync
this.source.start = 0;
this.source.end = 0;
var $editorDiv = $("<div/>").append($.parseHTML(this.core.editor().html(), document, true));
var $selectionMarkers = $editorDiv.find("span.redactor-selection-marker");
if ($selectionMarkers.length > 0) {
var editorHtml = $editorDiv.html().replace(/&/g, '&');
if ($selectionMarkers.length === 1) {
this.source.start = this.utils.strpos(editorHtml, $editorDiv.find("#selection-marker-1").prop("outerHTML"));
this.source.end = this.source.start;
}
else if ($selectionMarkers.length === 2) {
this.source.start = this.utils.strpos(editorHtml, $editorDiv.find("#selection-marker-1").prop("outerHTML"));
this.source.end = this.utils.strpos(editorHtml, $editorDiv.find("#selection-marker-2").prop("outerHTML")) - $editorDiv.find("#selection-marker-1").prop("outerHTML").toString().length;
}
}
},
setCaretOnHide: function(html)
{
this.source.start = this.source.$textarea.get(0).selectionStart;
this.source.end = this.source.$textarea.get(0).selectionEnd;
// if selection starts from end
if (this.source.start > this.source.end && this.source.end > 0) {
var tempStart = this.source.end;
var tempEnd = this.source.start;
this.source.start = tempStart;
this.source.end = tempEnd;
}
this.source.start = this.source.enlargeOffset(html, this.source.start);
this.source.end = this.source.enlargeOffset(html, this.source.end);
html = html.substr(0, this.source.start) + this.marker.html(1) + html.substr(this.source.start);
if (this.source.end > this.source.start) {
var markerLength = this.marker.html(1).toString().length;
html = html.substr(0, this.source.end + markerLength) + this.marker.html(2) + html.substr(this.source.end + markerLength);
}
return html;
},
hide: function() {
this.source.$textarea.removeClass('open').hide();
this.source.$textarea.off('.redactor-source');
var code = this.source.$textarea.val();
code = this.paragraphize.load(code);
code = this.source.setCaretOnHide(code);
this.code.start(code);
this.button.enableAll();
this.core.editor().show().focus();
this.selection.restore();
this.code.sync();
},
show: function() {
this.selection.save();
this.source.setCaretOnShow();
var height = this.core.editor().innerHeight();
var code = this.code.get();
code = code.replace(/\n\n\n/g, "\n");
code = code.replace(/\n\n/g, "\n");
this.core.editor().hide();
this.button.disableAll('html');
this.source.$textarea.val(code).height(height).addClass('open').show();
this.source.$textarea.on('keyup.redactor-source', $.proxy(function() {
if (this.opts.type === 'textarea') {
this.core.textarea().val(this.source.$textarea.val());
}
}, this));
this.marker.remove();
$(window).scrollTop(scroll);
if (this.source.$textarea[0].setSelectionRange) {
this.source.$textarea[0].setSelectionRange(this.source.start, this.source.end);
}
this.source.$textarea[0].scrollTop = 0;
setTimeout($.proxy(function() {
this.source.$textarea.focus();
}, this), 0);
},
enlargeOffset: function(html, offset)
{
var htmlLength = html.length;
var c = 0;
if (html[offset] === '>') {
c++;
}
else
{
for(var i = offset; i <= htmlLength; i++)
{
c++;
if (html[i] === '>') {
break;
}
else if (html[i] === '<' || i === htmlLength) {
c = 0;
break;
}
}
}
return offset + c;
}
};
};