$.fn.ImperaviLanguages = {
ru : {
html : 'Код',
// Styles dropdown menu
styles : {
name : 'Стили',
paragraph : 'Параграф',
quote : 'Цитата',
code : 'Код',
h2 : 'Заголовок 2',
h3 : 'Заголовок 3',
h4 : 'Заголовок 4',
h5 : 'Заголовок 5',
h6 : 'Заголовок 6',
},
// Formatting dropdown menu
format : {
name : 'Формат',
bold : 'Полужирный',
italic : 'Наклонный',
sup : 'Надстрочный',
sub : 'Надстрочный',
strike : 'Зачеркнутый',
remove : 'Очистить форматирование'
},
// Lists dropdown menu
lists : {
name : 'Списки',
unordered : 'Обычный список',
ordered : 'Нумерованный список',
outdent : 'Уменьшить отступ',
indent : 'Увеличить отступ'
},
// Working with images
image : {
name : 'Изображение',
download : 'Скачать изображение',
text : 'Текст',
mailto : 'Эл. почта',
web : 'URL',
title : 'Подсказка',
buttons : {
save : 'Сохранить',
cancel : 'Отменить',
insert : 'Вставить',
remove : 'Удалить'
},
align : {
name : 'Обтекание текстом',
none : 'нет',
left : 'слева',
right : 'справа'
}
},
// Insert and format tables
table : {
name : 'Таблица',
insert : 'Вставить таблицу',
remove : 'Удалить таблицу',
row: {
name : 'Строки',
above : 'Добавить строку сверху',
below : 'Добавить строку снизу',
remove : 'Удалить строку'
},
column : {
name : 'Столбцы',
left : 'Добавить столбец слева',
right : 'Добавить столбец справа',
remove : 'Удалить столбец',
},
header : {
add : 'Добавить заголовок',
remove : 'Удалить заголовок'
}
},
// Insert video from youtube etc
video : {
name : 'Видео',
code : 'Код видео ролика'
},
// Insert or remove hyperlink to a file
file : {
name : 'Файл',
upload : 'Загрузить',
download : 'Скачать',
choose : 'Выбрать',
or_choose : 'Или выберите',
drop : 'Перетащите файл сюда'
},
// Insert or remove hyperlink
hyperlink : 'Ссылка'
}
}
;
$.fn.ImperaviToolbarDefault = {
html : true,
// Styles dropdown menu
// TODO: User styles here. Move all to format section from here
styles : {
paragraph : true,
quote : true,
code : true,
h2 : true,
h3 : true,
h4 : true,
h5 : true,
h6 : true
},
// Formatting dropdown menu
format : {
bold : true,
italic : true,
sup : true,
sub : true,
strike : true,
remove : true
},
// Lists dropdown menu
lists : {
unordered : true,
ordered : true,
outdent : true,
indent : true
},
// Working with images
image : true,
// Insert and format tables
table : {
insert : true,
remove : true,
header : {
add : true,
remove : true
},
row : {
above : true,
below : true,
remove : true
},
column : {
left : true,
right : true,
remove : true
}
},
// Insert video from youtube etc
video : true,
// Insert or remove hyperlink to a file
file : true,
// Insert or remove hyperlink
hyperlink : true
}
;
(function( $ ) {
$.fn.ImperaviActionDelegator = function(o) { this.initialize() }
$.fn.ImperaviActionDelegator.prototype = {
initialize: function() {},
delegateButtonClick: function(button, iframe) {
switch (button.attr('rel')) {
case 'indent':
case 'outdent':
alert('yay!')
break;
case 'video':
new $.fn.ImperaviPluginVideo
break;
case 'image':
new $.fn.ImperaviPluginImage
break;
case 'hyperlink':
new $.fn.ImperaviPluginHyperlink
break;
case 'file':
new $.fn.ImperaviPluginFile
break;
default:
return button
break;
}
}
}
})(jQuery);
// Internationalization
(function( $ ) {
$.fn.ImperaviI18n = function(o) {
var o = $.extend({
locale : 'en'
}, o)
this.initialize(o)
}
$.fn.ImperaviI18n.prototype = {
o : null,
locales : null,
initialize: function(o) {
this.o = $.extend({ locale : $.fn.ImperaviOptions().options.locale }, o)
this.locales = $.fn.ImperaviLanguages[this.o.locale]
},
t: function(key) {
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviPluginVideo = function(o) { this.initialize(o) }
$.fn.ImperaviPluginVideo.prototype = {
initialize: function(o) {
this.o = o
this.dialog = new $.fn.ImperaviDialog({
title : 'Insert video',
width : 600,
height : 300,
onOkay : function() {
alert(this.el.find('textarea').val())
this.hide()
}
})
this.dialog.show()
this.dialog.el.addClass('imperavi-plugin-video')
this.build()
},
build: function() {
var textarea = $(document.createElement('textarea'))
this.dialog.setContent(textarea)
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviPluginImage = function(o) { this.initialize(o) }
$.fn.ImperaviPluginImage.prototype = {
initialize: function(o) {
this.o = o
this.dialog = new $.fn.ImperaviDialog({
title : 'Insert image',
width : 800,
height : 600,
onRemove : function() {
alert('fuck yeah!')
this.hide()
},
onOkay : function() {
this.hide()
}
})
this.dialog.show()
this.dialog.el.addClass('imperavi-plugin-image')
this.build()
},
build: function() {
// Add 'remove' button
this.removeButton = this.dialog.addButton('Remove', 'remove')
this.removeButton.hide();
// Create tabs and content for tabs
this.tabsArea = this.buildTabsArea()
this.uploadTab = this.buildTab('Upload image', this.buildUploadTabContent())
.appendTo(this.tabsArea)
.addClass('current')
this.pickTab = this.buildTab('Pick image', this.buildPickTabContent())
.appendTo(this.tabsArea)
this.dialog.setContent(this.tabsArea)
this.switchTabs();
},
// Build tabs container
buildTabsArea: function() {
var article = $(document.createElement('article'))
.addClass('imperavi-tabs')
return article
},
// Add another one tab
buildTab: function(title, content) {
var section = $(document.createElement('section'))
var heading = $(document.createElement('h3'))
.html(title)
.addClass('imperavi-tab')
.appendTo(section)
var content = $(document.createElement('div'))
.appendTo(section)
.html(content)
return section
},
// Switch between tabs
switchTabs: function() {
var currentTab = this.uploadTab
this.tabsArea.on('click', '.imperavi-tab', function(e){
e.preventDefault();
if (currentTab.length) {
currentTab.removeClass('current')
}
currentTab = $(this).closest('section').addClass('current')
})
},
buildPickTabContent: function() {
},
buildUploadTabContent: function() {
// Create wrapper
var wrapper = $(document.createElement('div'))
.attr('id', 'upload-wrapper')
// Create place for thumbnail
var thumbnail = $(document.createElement('figure'))
.addClass('thumbnail')
.appendTo(wrapper)
var caption = $(document.createElement('span'))
.html('No image yet')
.appendTo(thumbnail)
// Create form
var form = $(document.createElement('form'))
.attr('enctype', 'application/x-www-form-urlencoded')
.attr('method', 'post')
.attr('action', '/imperavi/upload')
.appendTo(wrapper)
// Choose image from disk
var imageLocal = this.buildInput('Choose image from disk', 'image', 'file')
.appendTo(form)
// Image url
var imageUrl = this.buildInput('or specify link to image', 'image-url', 'text')
.appendTo(wrapper)
// Image position
var imagePos = this.buildPositionSelect().appendTo(wrapper)
// Submit form
form.on("change", ":file", function() {
thumbnail.addClass("loading");
$.ajax(form.prop("action"), {
files : form.find(":file"),
iframe : true,
dataType : "json"
}).always(function() {
thumbnail.removeClass("loading");
}).done(function(data) {
/*
$.each(data.files, function(idx, file) {
$("
(, )")
.find("b").text(file.filename).end()
.find(".size").text(formatSize(file.length)).end()
.find(".mime").text(file.mime).end()
.appendTo("#filelist");
});
*/
//form.find(":file").val("");
alert(data)
});
});
return wrapper
},
buildInput: function(title, name, type) {
var wrapper = $(document.createElement('div'))
.addClass('field')
var label = $(document.createElement('label'))
.attr('for', name)
.html(title)
.appendTo(wrapper)
var url = $(document.createElement('input'))
.attr('type', type)
.attr('name', name)
.attr('id', name)
.appendTo(wrapper)
return wrapper
},
buildPositionSelect: function() {
var wrapper = $(document.createElement('div'))
.addClass('field')
var label = $(document.createElement('label'))
.attr('for', 'image-position')
.html('Image position')
.appendTo(wrapper)
var select = $(document.createElement('select'))
.attr('id', 'image-position')
.attr('name', 'image-position')
.appendTo(wrapper)
// Create select options
var options = {
none : 'None',
left : 'To left',
right : 'To right'
}
$.each(options, function(value, caption) {
$(document.createElement('option'))
.attr('value', value)
.html(caption)
.appendTo(select)
})
return wrapper
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviPluginHyperlink = function(o) { this.initialize(o) }
$.fn.ImperaviPluginHyperlink.prototype = {
initialize: function(o) {
this.o = o
this.dialog = new $.fn.ImperaviDialog({
title : 'Insert hyperlink',
width : 450,
height : 237,
onRemove : function() {
alert('fuck yeah!')
this.hide()
},
onOkay : function() {
alert('fuck')
this.hide()
}
})
this.dialog.show()
this.dialog.el.addClass('imperavi-plugin-hyperlink')
this.dialog.addButton('Remove', 'remove')
this.build()
},
build: function() {
var wrapper = $(document.createElement('div'))
var url = this.build_input('Url', 'url').appendTo(wrapper)
var caption = this.build_input('Title', 'title').appendTo(wrapper)
this.dialog.setContent(wrapper)
},
build_input: function(title, name) {
var wrapper = $(document.createElement('div'))
.addClass('field')
var label = $(document.createElement('label'))
.attr('for', name)
.html(title)
.appendTo(wrapper)
var url = $(document.createElement('input'))
.attr('type', 'text')
.attr('name', name)
.attr('id', name)
.appendTo(wrapper)
return wrapper
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviPluginFile = function(o) { this.initialize(o) }
$.fn.ImperaviPluginFile.prototype = {
initialize: function(o) {
this.o = o
this.dialog = new $.fn.ImperaviDialog({
title : 'Attach file',
width : 450,
height : 237,
onRemove : function() {
alert('fuck yeah!')
this.hide()
},
onOkay : function() {
alert('fuck')
this.hide()
}
})
this.dialog.show()
this.dialog.el.addClass('imperavi-plugin-file')
this.dialog.addButton('Remove', 'remove')
this.build()
},
build: function() {
var wrapper = $(document.createElement('div'))
var file = this.build_input('File', 'attachment').appendTo(wrapper)
//var caption = this.build_input('Title', 'title').appendTo(wrapper)
this.dialog.setContent(wrapper)
},
build_input: function(title, name) {
var wrapper = $(document.createElement('div'))
.addClass('field')
var label = $(document.createElement('label'))
.attr('for', name)
.html(title)
.appendTo(wrapper)
var file = $(document.createElement('input'))
.attr('type', 'file')
.attr('name', name)
.attr('id', name)
.appendTo(wrapper)
return wrapper
}
}
})(jQuery);
// TODO: add custom events
// - onShow
// - onClose
// - onBuilt
// - onContentLoaded
// - onOkay
// - onCancel
(function( $ ) {
$.fn.ImperaviDialog = function(o) {
var o = $.extend({
onOkay : function() { this.hide() },
onCancel : function() { this.hide() },
onClose : function(e) { this.close(e) },
onBuilt : function() {},
onLoad : function() {}
}, o)
this.initialize(o)
}
$.fn.ImperaviDialog.prototype = {
el : null,
o : null,
overlay : null,
initialize: function(o) {
// Retrieve user options passed to imperavi
this.o = $.extend($.fn.ImperaviOptions().options.dialog, o)
},
build: function() {
// Build dialog just once
if (this.el) return;
// Create overlay
this.overlay = new $.fn.ImperaviOverlay()
// Dialog window
this.el = $(document.createElement('div'))
.attr('id', 'imperavi-dialog')
.appendTo($('body'));
this.container = $(document.createElement('div'))
.attr('id', 'imperavi-dialog-container')
.appendTo(this.el);
// Close button
this.closeBtn = $(document.createElement('a'))
.attr('href', 'javascript:;')
.html('×')
.attr('id', 'imperavi-dialog-close')
.appendTo(this.container);
// Dialog title
this.title = $(document.createElement('h1'))
.attr('id', 'imperavi-dialog-title')
.appendTo(this.container);
// Dialog content
this.article = $(document.createElement('article'))
.attr('id', 'imperavi-dialog-content')
.appendTo(this.container);
// Buttons panel
this.buttons_wrapper = $(document.createElement('div'))
.attr('id', 'imperavi-dialog-buttons-wrapper')
.appendTo(this.container);
this.buttons = $(document.createElement('div'))
.attr('id', 'imperavi-dialog-buttons')
.appendTo(this.buttons_wrapper);
this.okay_button = this.addButton('Okay', 'okay')
this.cancel_button = this.addButton('Cancel', 'cancel')
// Set default size
this.setSize(this.o.width, this.o.height)
// Set default title
this.setTitle(this.o.title)
this.o.onBuilt.call(this)
},
addButton: function(caption, name) {
var callbackName = 'on' + name.charAt(0).toUpperCase() + name.slice(1)
return $(document.createElement('a'))
.attr('id', 'imperavi-dialog-' + name)
.attr('href', 'javascript:;')
.html(caption)
.click($.proxy(function(){ this.o[callbackName].call(this) }, this))
.appendTo(this.buttons);
},
addEvents: function() {
var onCloseCallback = $.proxy(function(e){ this.o.onClose.call(this, e) }, this)
$(document).keyup(function(e) { onCloseCallback(e) })
this.closeBtn.click(function(e) { onCloseCallback(e) })
this.overlay.el.click(function(e) { onCloseCallback(e) })
},
removeEvents: function() {
var onCloseCallback = $.proxy(function(e){ this.o.onClose.call(this, e) }, this)
$(document).unbind('keyup', onCloseCallback)
this.closeBtn.unbind('click', onCloseCallback)
this.overlay.el.unbind('click', onCloseCallback)
},
setSize: function(width, height) {
this.el.css({
width : width + 'px',
height : height + 'px',
marginTop : '-' + height / 2 + 'px',
marginLeft : '-' + width / 2 + 'px'
}).fadeIn('fast');
this.container.css({
width : width + 'px',
height : height + 'px',
})
},
setTitle: function(title) {
this.title.html(title)
},
setContent: function(content) {
this.article.html(content)
},
// TODO Load content via ajax
loadContent: function(url) {
this.setContent('')
this.o.onLoad.call(this)
},
cleanUp: function() {
this.removeEvents()
this.setContent('')
this.setTitle('')
},
show: function() {
this.build()
this.overlay.show()
this.el.show()
this.addEvents()
},
hide: function() {
this.el.hide()
this.overlay.hide()
this.cleanUp()
},
close: function(e) {
if (e.keyCode == 27 || e.type == 'click')
this.hide()
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviOverlay = function(o) { this.initialize(o) }
$.fn.ImperaviOverlay.prototype = {
el : null,
initialize: function(o) {
this.o = o
},
build: function() {
if (this.el) return;
this.el = $(document.createElement('div'))
.attr('id', 'imperavi-overlay')
.appendTo($('body'));
},
show: function() {
this.build()
this.el.show()
},
hide: function() {
this.el.hide()
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviIframe = function(textarea, o) { this.initialize(textarea, o) }
$.fn.ImperaviIframe.prototype = {
textarea : null,
wrapper : null,
el : null,
initialize: function(textarea, o) {
this.textarea = textarea
this.o = o
this.textarea.hide();
this.build()
this.populate()
this.enable(true)
},
// Build Iframe object and stuff
build: function() {
this.wrapper = $(document.createElement('div'))
.addClass('imperavi')
.insertAfter(this.textarea)
this.el = $(document.createElement('iframe'))
.appendTo(this.wrapper)
.css({ width : this.textarea.outerWidth(), height : this.textarea.outerHeight() })
},
populate: function() {
html = ''
html += ''
//html += ''
//html += ''
html += '' + this.textarea.val()
html += ''
this.doc().open();
this.doc().write(html);
this.doc().close();
},
enableObjects: function() {
if (!$.browser.mozilla) return;
//this.doc().execCommand('styleWithCSS', false, false)
//this.doc().execCommand('enableObjectResizing', false, false)
//this.doc().execCommand('enableInlineTableEditing', false, false)
},
observe: function() {
},
enable: function(status) {
// Located here for Chrome support
this.doc().designMode = status ? 'on' : 'off';
this.el.load($.proxy(function() {
this.enableObjects();
this.observe();
}, this));
},
doc: function() {
var i = this.el.get(0)
if (i.contentDocument) return i.contentDocument
if (i.contentWindow) return i.contentWindow.document
return i.document
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviIframeResizer = function(iframe, o) { this.initialize(iframe, o) }
$.fn.ImperaviIframeResizer.prototype = {
iframe : null,
el : null,
initialize: function(iframe, o) {
this.iframe = iframe
this.o = o
this.build()
},
build: function() {
this.el = $(document.createElement('div'))
.addClass('imperavi-resizer')
.insertAfter(this.iframe.el)
this.el.append($(document.createElement('div')))
}
}
})(jQuery);
(function( $ ) {
$.fn.ImperaviToolbar = function(iframe, o) {
var o = $.extend({
onButtonClick : function(button) {},
}, o)
this.initialize(iframe, o)
}
$.fn.ImperaviToolbar.prototype = {
iframe : null,
el : null,
initialize: function(iframe, o) {
this.iframe = iframe
this.o = o
this.x = $.fn.ImperaviToolbarDefault // TODO make it pretty
this.l = $.fn.ImperaviLanguages.ru // TODO make it pretty
this.build()
},
// Build Toolbar object
build: function() {
this.el = $(document.createElement('ul'))
.insertBefore(this.iframe.el);
$.each(this.x, $.proxy(function(key, value) {
// Buttons with dropdown
if (typeof value == 'object') {
this.el.append(this.addDropdown(key, value))
} else if (typeof value == 'boolean' && value == true) {
var title = typeof this.l[key] == 'object' ? this.l[key].name : this.l[key]
this.el.append(this.addButton(key, title, null))
}
}, this));
},
addButton: function(name, title, caption) {
var li = $(document.createElement('li')).addClass('button-' + name)
var a = $(document.createElement('a'))
.attr('href', 'javascript:;')
.attr('rel', name)
.attr('title', title)
.appendTo(li)
// This executes a custom callback on button click
.click($.proxy(function(){ this.o.onButtonClick.call(this, a) }, this))
var span = $(document.createElement('span'))
.html(caption)
.appendTo(a);
return li.append(a)
},
addDropdown: function(name, items) {
var button = this.addButton(name, this.l[name].name, null)
var ul = $(document.createElement('ul'))
button.addClass('has-dropdown')
// Add dropdown items
$.each(items, $.proxy(function(key, value) {
if (typeof value == 'object') {
var separator = true
$.each(value, $.proxy(function(key2, value2) {
if (value2 == true) {
var item = this.addButton(key2, null, this.l[name][key][key2])
if (separator) item.addClass('separator')
ul.append(item)
separator = false
}
}, this));
} else if (typeof value == 'boolean' && value == true) {
ul.append( this.addButton(key, null, this.l[name][key]) )
}
}, this));
return button.append(ul)
}
}
})(jQuery);
(function( $ ) {
$.fn.imperavi = function(o) {
// Editor options
var o = $.extend({
locale : 'ru', // TODO replace with $.fn.ImperaviLanguage
resizer : $.fn.ImperaviIframeResizer,
dialog : $.fn.ImperaviDialog,
overlay : $.fn.ImperaviOverlay,
iframe : $.fn.ImperaviIframe,
toolbar : $.fn.ImperaviToolbar,
delegator : $.fn.ImperaviActionDelegator,
options : {
dialog : {
title : 'Default title',
width : 500,
height : 300
}
}
}, o)
// Global options
$.fn.ImperaviOptions = function() { return o }
// Main object
$.fn.Imperavi = function(el) { this.initialize(el) }
$.fn.Imperavi.prototype = {
textarea : null,
iframe : null,
toolbar : null,
resizer : null,
delegator : null,
// Initialize imperavi
initialize: function(el) {
this.textarea = $(el)
this.build()
this.autosave()
},
build: function() {
// Delegate action to another object
this.delegator = new o.delegator
// Create iframe
this.iframe = new o.iframe(this.textarea, o)
// Create editor resizer
this.resizer = new o.resizer(this.iframe, o)
// Create toolbar
this.toolbar = new o.toolbar(this.iframe, {
onButtonClick : $.proxy(function(button) {
this.delegator.delegateButtonClick(button, this.iframe)
}, this)
})
},
autosave: function() {
// TODO: implement
}
}
// Apply imperavi for each selected element
return this.each(function() {
new $.fn.Imperavi(this)
})
}
})(jQuery);
// Vendor
// require ./imperavi/jquery.iframe-transport.js
// Imperavi
;