rhymix/modules/editor/skins/dreditor/js/DrEditor.js
ChanMyeong fef0e92afd HTML/CSS code cleaning.
git-svn-id: http://xe-core.googlecode.com/svn/branches/1.5.0@10298 201d5d3c-b55e-5fd7-737f-ddc643e51545
2012-03-02 14:49:25 +00:00

2599 lines
74 KiB
JavaScript

/**
* 단락에디터 Paragraph Editor
* @author NHN (developers@xpressengine.com)
*/
(function($){
var configs = {};
var TOOLSET_LENGTH = 9;
var DrEditor = xe.createApp('DrEditor', {
loaded : false,
last_seq : 0,
toolset_offset : 0,
init : function() {
},
getConfig : function(seq) {
return configs[seq] || {};
},
API_ONREADY : function(sender, params) {
var self = this;
$.each(configs, function(seq, val){
var _container = $('div#DrEditor'+seq);
var _writeArea = _container.find('>div>div.writeArea:first');
var _editArea = _container.find('>div>div.editorArea:first');
var _dummyArea = $('<div class="dummy" style="display:none">').appendTo(_writeArea);
var _blankBox = _writeArea.find('>div.blank:first').prependTo(_writeArea);
var _toolbar = _writeArea.find('>.wToolbarContainer>div.wToolbar');
var _editTool = _writeArea.find('ul.eTool').remove();
var _hookerBtn = $('<button type="button" class="_hookerBtn">').attr('seq', seq).css({position:'absolute',width:'1px',height:'1px',left:'-2000px',top:0}).prependTo(_container);
var $numbers;
// toolbar buttons
_toolbar
.find('button')
.hover(
function(){ $(this).parent().addClass('hover'); },
function(){ $(this).parent().removeClass('hover'); }
)
.click(
function(event){
var type = $(this).parent().attr('class').toUpperCase().split(' ')[0];
self.cast('CLICK_TOOLBUTTON', [seq, this, type]);
return false;
}
);
// _blankBox
//_blankBox.dblclick(function(){ self.cast('OPEN_EDITOR', [seq, null, null, 'HX']); });
// toolbar button sortable
_toolbar.children('ul:first')
.sortable({items : '>li'})
.bind('sortstop', function(){
var tools = [];
if (!$numbers) {
($numbers = _toolbar.find('button .nx')).sort(function(a, b){
return (parseInt(a.firstChild.nodeValue,10) > parseInt(b.firstChild.nodeValue,10))?1:-1;
});
}
_toolbar.find('li').each(function(i){
var t = $(this), $btn = t.find('>button'), title = '';
tools.push(t.attr('class'));
if (i < 9) {
title = xe.lang.shortcut + '('+(i+1)+')';
$btn.append($numbers.eq(i+1));
}
$btn.attr('title', title);
});
tools = tools.join(',');
if (tools) {
var expires = (new Date()).getTime() + 7 * 24 * 3600 * 1000; // one week
document.cookie = 'DrEditorToolbar='+tools+'; expires='+(new Date(expires)).toGMTString()+'; path=/;';
}
});
// container
_editArea
.sortable({
axis : 'y',
items : '>div.eArea',
handle : '>div.drag_handle',
placeholder : 'xe_dr_placeholder'
});
// focus hook event
_hookerBtn
.focus (function(){
if(!_editArea.children('div.eFocus,div.wArea:visible').length) self.cast('SELECT_PARAGRAPH', [seq, _editArea.find('>div:first')]);
self.last_seq = seq;
});
configs[seq] = $.extend(configs[seq], {
sequence : seq,
container : _container,
editArea : _editArea,
writeArea : _writeArea,
blankBox : _blankBox,
toolbar : _toolbar,
editTool : _editTool,
hookerBtn : _hookerBtn,
selFirst : null,
selLast : null,
last_type : ''
});
if (!self.last_seq) self.last_seq = seq;
});
function getPara(event) {
var target = $(event.target);
if(target.is('a,button,:input')) return null;
var para = target.parents('div').andSelf().filter('div.eArea:first');
return para.length?para:null;
};
function falseFunc(){ return false; };
$(document).mousedown(function(event) {
var target = $(event.target);
if(!is_left_click(event)) return true;
if(target.is('a,button,:input')) return true;
if(target.parents('div.wToolbar:first').length) return true;
var para = target.parents('div').andSelf().filter('div.eArea:first');
if(!para.length) {
self.cast('CLEAR_SELECTION', [seq]);
return true;
}
if(para.parents('div.material:first').length) return true;
var seq = para.parents('form:first')[0].elements['editor_sequence'].value;
if (configs[seq].editArea.children('div.wArea:visible').length) {
// save
if (configs[seq].last_type) self.cast('CLOSE_EDITOR', [seq, true, configs[seq].last_type]);
}
// multiple selection
if (event.shiftKey) {
if (configs[seq].selFirst) {
var children = configs[seq].editArea.children('div');
var nSelFirst = children.index(configs[seq].selFirst);
var nPara = children.index(para);
var nStart = Math.min(nSelFirst, nPara);
var nEnd = Math.max(nSelFirst, nPara);
self.cast('CLEAR_SELECTION');
self.cast('SELECT_PARAGRAPH', [seq, children.slice(nStart,nEnd+1), children.eq(nSelFirst), para]);
} else {
self.cast('SELECT_PARAGRAPH', [seq, para, para, para]);
}
} else if (event.ctrlKey) {
if (para.hasClass('eFocus')) {
self.cast('UNSELECT_PARAGRAPH', [seq, para, para, para]);
} else {
self.cast('SELECT_PARAGRAPH', [seq, para, para, para]);
}
} else {
self.cast('CLEAR_SELECTION');
self.cast('SELECT_PARAGRAPH', [seq, para, para, para]);
}
return false;
});
// global doubleclick
$(document).dblclick(function(event){
var target = $(event.target);
if(target.is('a,button,:input')) return true;
if(event.shiftKey || event.ctrlKey) return true;
var para = target.parents('div').andSelf().filter('div.eArea:first');
if(!para.length) return true;
var seq = para.parents('form:first')[0].elements['editor_sequence'].value;
var type = para.attr('type');
if (type) {
self.cast('CLEAR_SELECTION');
self.cast('OPEN_EDITOR', [seq, para, null, type]);
}
});
$(document).keydown(function(event){
var target = $(event.target);
if(!event.altKey && !event.ctrlKey && !event.metaKey && target.is(':input:not(button._hookerBtn)')) return true;
if(event.keyCode == 16 && event.shiftKey) return true; // only shift key
if(event.keyCode == 17 && event.ctrlKey) return true; // only ctrl key
if(event.keyCode == 18 && event.altKey) return true; // only alt key
if(event.keyCode == 9) return true;
var ret = self.cast('ONKEYDOWN', [self.last_seq, event]);
if (ret == true || ($.isArray(ret) && $.inArray(ret, true))) return false;
});
// scroll event
var _scrollTimer = null;
$(window).scroll(function(event){
if (_scrollTimer) clearTimeout(_scrollTimer);
_scrollTimer = setTimeout(function(){
_scrollTimer = null;
self.cast('ONSCROLL');
}, 10);
});
},
API_ONLOAD : function(sender, params) {
var self = this;
this.loaded = true;
$.each(configs, function(seq,val){ self.cast('TOOLBAR_REPOSITION', [seq]) });
},
API_CREATE_EDITOR : function(sender, params) {
configs[params[0]] = {form:params[1]};
},
API_GET_CONTENT : function(sender, params) {
var seq = params[0];
var box = configs[seq].editArea.contents().clone();
var dum = $('<div>').append(box);
var htm = '';
// remove no-content area
dum.find('>div.wArea,>div.eArea>div.drag_handle,>div.eArea>button.del').remove();
// getting content
this.cast('GETTING_CONTENT', [seq, dum]);
htm = dum
.html()
.replace(
/<(img|br)([^>]*)\/?>/gi,
function(m0,m1,m2){
var ret = ['<'+m1];
(m2 = $.trim(m2))?ret.push(m2):0;
ret.push('/>');
return ret.join(' ');
}
);
return htm;
},
API_SET_CONTENT : function(sender, params) {
var seq = params[0];
var txt = params[1];
// clear all document
this.cast('CLEAR', [seq]);
// process text
var dum = $('<div>').html( txt );
this.cast('SETTING_CONTENT', [seq, dum]);
// set content
if(configs[seq] && configs[seq].editArea) {
configs[seq].editArea.append(dum.children('div.eArea'));
}
},
API_AFTER_SET_CONTENT : function(sender, params) {
var seq = params[0];
// show or hide blankbox
if(configs[seq].editArea.find('>div.eArea').length) {
configs[seq].blankBox.hide();
} else {
configs[seq].blankBox.show();
}
},
API_CLEAR : function(sender, params) {
var seq = params[0];
if(configs[seq] && configs[seq].editArea) configs[seq].editArea.empty();
},
API_GET_SELECTED_PARAGRAPH : function(sender, params) {
var seq = params[0];
return configs[seq].editArea.children('div.eFocus');
},
API_SELECT_PARAGRAPH : function(sender, params) {
var seq = params[0];
var par = params[1]; // clicked paragraph
var fir = params[2]; // selection first
var las = params[3]; // selection last
var self = this;
configs[seq].selFirst = fir || null;
configs[seq].selLast = las || null;
var box = (las || fir || par).eq(0), top;
if (box && box.length) {
top = box.position().top + Math.floor(box.height()/2);
configs[seq].hookerBtn.css('top', top+'px');
}
par.addClass('eFocus');
if (par.length) {
configs[seq].hookerBtn.focus();
par.each(function(){
var t = $(this);
if (!t.find('>div.drag_handle:first').length) {
t.prepend('<div class="drag_handle left" title="'+xe.lang.drag_this+'" />');
t.prepend('<div class="drag_handle right" title="'+xe.lang.drag_this+'" />');
}
});
par = par.parent().find('>.eFocus');
par.find('>button.del').remove();
$('<button type="button" class="del"><span>'+xe.lang.cmd_del+'</span></button>')
.click(function(){ self.cast('DELETE_PARAGRAPH', [seq, par]); return false; })
.appendTo(par.eq(0));
}
if ($.browser.msie) {
try { document.selection.createRange().collapse(true) } catch(e) {};
}
},
API_UNSELECT_PARAGRAPH : function(sender, params) {
var seq = params[0];
var par = params[1]; // clicked paragraph
par.removeClass('eFocus').find('>button.del').remove();
},
API_CLEAR_SELECTION : function(sender, params) {
var skip_seq = params[0];
$.each(configs, function(seq){
if(skip_seq && skip_seq == seq) return true;
$(this.editArea.children('div.eFocus')).removeClass('eFocus');
this.selFirst = null;
this.selLast = null;
});
},
API_SAVE_PARAGRAPH : function(sender, params) {
var seq = params[0];
var _editor = params[1];
var _box = params[2];
var _type = (params[3]||'').toLowerCase();
if (_type) _box.addClass('eArea _'+_type).attr('type', _type);
if (_editor && _box) _editor.before(_box);
},
API_DELETE_PARAGRAPH : function(sender, params) {
var self = this;
var seq = params[0];
var target = params[1];
if (target && target.length) {
var prev = target.eq(0).prev('div.eArea');
var next = target.eq(target.length-1).next('div.eArea');
target
.removeClass('eFocus')
.hide('fast', function(){
$(this).remove();
self.cast('TOOLBAR_REPOSITION', [seq]);
if (!configs[seq].editArea.children('div.eArea:first').length) configs[seq].blankBox.show();
});
if (next.length) this.cast('SELECT_PARAGRAPH', [seq, next, next, next]);
else if (prev.length) this.cast('SELECT_PARAGRAPH', [seq, prev, prev, prev]);
}
},
API_CLICK_TOOLBUTTON : function(sender, params) {
var seq = params[0];
var button = $(params[1]);
var type = params[2];
var selbox = this.cast('GET_SELECTED_PARAGRAPH', [seq]);
if(selbox.length) selbox = selbox.eq(0);
else selbox = null;
var editor = configs[seq].editArea.children('div.wArea:visible');
if (editor.length) {
if (editor.is(type)) this.cast('CLOSE_EDITOR', [seq, false, type]);
} else {
this.cast('CLEAR_SELECTION');
this.cast('OPEN_EDITOR', [seq, null, selbox, type]);
}
},
API_ONSCROLL : function(sender, params) {
var self = this;
if (this.loaded) {
$.each(configs, function(seq,val){ self.cast('TOOLBAR_REPOSITION', [seq]) });
}
},
API_ONKEYDOWN : function(sender, params) {
var self = this;
var seq = params[0];
var event = params[1];
var key = event.keyCode, ctrl = event.ctrlKey, meta = event.metaKey, alt = event.altKey, shift = event.shiftKey;
var ENTER = 13, UP = 38, DOWN = 40, DEL = 46;
var selection, para, prev, next;
if ($(event.target).is(':text')) return false;
// hit enter to edit a selected paragraph
if(key == ENTER) {
configs[seq].editArea.children('div.eFocus:first').dblclick();
return true;
}
if (key == UP || key == DOWN) {
if (ctrl) { // hit ctrl + up, down to move paragraphs
selection = this.cast('GET_SELECTED_PARAGRAPH', [seq]);
if (key == UP) {
prev = selection.eq(0).prev('div.eArea');
if (prev.length) prev.before(selection);
else configs[seq].editArea.prepend(selection);
} else {
next = selection.eq(selection.length-1).next('div.eArea');
if (next.length) next.after(selection);
else configs[seq].editArea.append(selection);
}
setTimeout(function(){ self.cast('ONMOVE_PARAGRPH', [seq]) }, 0);
} else if (shift) { // hit shift + up, down to select multiple paragraphs
var children = configs[seq].editArea.children('div.eArea');
var current = configs[seq].selLast || configs[seq].selFirst;
if (key == UP) {
if ((prev=current.prev('div.eArea')).length) current = prev;
} else {
if ((next=current.next('div.eArea')).length) current = next;
}
var nSelFirst = children.index(configs[seq].selFirst);
var nCurrent = children.index(current);
var nStart = Math.min(nSelFirst, nCurrent);
var nEnd = Math.max(nSelFirst, nCurrent);
this.cast('CLEAR_SELECTION');
this.cast('SELECT_PARAGRAPH', [seq, children.slice(nStart,nEnd+1), children.eq(nSelFirst), current]);
} else { // hit up or down arrow to move selection
selection = this.cast('GET_SELECTED_PARAGRAPH', [seq]);
if (key == UP) {
prev = selection.eq(0).prev('div.eArea');
if (prev.length) para = prev;
else para = selection.eq(0);
} else {
next = selection.eq(selection.length-1).next('div.eArea');
if (next.length) para = next;
else para = selection.eq(selection.length-1);
}
this.cast('CLEAR_SELECTION');
this.cast('SELECT_PARAGRAPH', [seq, para, para, para]);
}
selection = this.cast('GET_SELECTED_PARAGRAPH', [seq]);
this.cast('SCROLL_INTO_VIEW', [seq, selection, (key==UP)?'top':'bottom']);
return true;
}
// delete key
if (key == DEL) {
selection = this.cast('GET_SELECTED_PARAGRAPH', [seq]);
this.cast('DELETE_PARAGRAPH', [seq, selection]);
return true;
}
// number key
if (48 <= key && key <= 58) {
var buttons = configs[seq].toolbar.find('button');
if (key == 48) key = buttons.length+48;
buttons.eq(key-49).click();
return true;
}
// change toolset
if (key == 192) {
var ul = configs[seq].toolbar.find('ul:first');
var lis = ul.find('>li');
var more = lis.eq(lis.length-1);
if ((lis.length-1) % TOOLSET_LENGTH) {
var empty_len = TOOLSET_LENGTH - ((lis.length-1) % TOOLSET_LENGTH);
for(;empty_len--;) more.before('<li class="blank" style="height:57px;" />');
lis = ul.find('>li');
}
var toolset_count = (lis.length-1) / 9
this.toolset_offset++;
if (this.toolset_offset >= toolset_count) this.toolset_offset = 0;
more.before( lis.slice(0,TOOLSET_LENGTH) );
}
},
API_ADD_DEFAULT_EDITOR_ACTION : function(sender, params) {
var self = this;
var seq = params[0];
var editor = params[1];
var type = (params[2]||'').toUpperCase();
// save and cancel button
var _buttons = editor.find('div.btnArea button');
_buttons.eq(0).click(function(){ self.cast('CLOSE_EDITOR', [seq, true, type]); }); // save button
_buttons.eq(1).click(function(){ self.cast('CLOSE_EDITOR', [seq, false, type]); }); // cancel button
// textbox default value
editor.find('input[type=text],textarea')
.focus(function(){ if($.trim(this.value) == this.title) this.value = ''; })
.blur(function(){ var val=$.trim(this.value); if (val==this.title || val == '') this.value = this.title; })
.filter('input').keydown(function(event){ if(event.keyCode == 13) return false; });
// set default checkbox and radio button
editor.find('input[type=checkbox],input[type=radio]').filter(':checked').addClass('_default_check');
editor.find('input,textarea').keydown(function(event){
var ESC = 27, ENTER = 13;
if (!configs[seq].last_type) return true;
if (event.keyCode == 27) {
self.cast('CLOSE_EDITOR', [seq, false, configs[seq].last_type]);
return false;
}
if (event.ctrlKey && event.keyCode == ENTER) {
self.cast('CLOSE_EDITOR', [seq, true, configs[seq].last_type]);
return false;
}
});
},
API_RESET_EDITOR : function(sender, params) {
var seq = params[0];
var editor = params[1];
var type = (params[2]||'').toUpperCase();
// reset textbox
editor.find('input[type=text],textarea').each(function(){ this.value = this.title; });
// reset checkbox and radio buttons
editor.find('input[type=checkbox],input[type=radio]').filter('._default_check').attr('checked', 'checked');
},
API_TOOLBAR_REPOSITION : function(sender, params) {
var seq = params[0];
var toolbar = configs[seq].toolbar.parent();
var view_bottom = $(window).scrollTop() + document.documentElement.clientHeight; //scroll_top + doc_height
var old_top = toolbar.css('top');
var offset_top = toolbar.css('top', 0).offset().top;
var new_top = Math.min( ((view_bottom - toolbar.height()) - offset_top - 5), 0);
if (old_top != new_top) toolbar.css('top', new_top+'px');
},
API_OPEN_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1]; // selection to edit
var bef = params[2]; // selection to be before this editor
var type = params[3];
this.cast('OPEN_'+type.toUpperCase()+'_EDITOR', [seq, box, bef]);
configs[seq].last_type = type;
configs[seq].blankBox.hide();
this.cast('TOOLBAR_REPOSITION', [seq]);
},
API_CLOSE_EDITOR : function(sender, params) {
var seq = params[0];
var save = !!params[1];
var type = params[2];
this.cast('CLOSE_'+type.toUpperCase()+'_EDITOR', [seq, save]);
if (configs[seq].editArea.children('div.eArea').length) {
configs[seq].blankBox.hide();
} else {
configs[seq].blankBox.show();
}
this.cast('TOOLBAR_REPOSITION', [seq]);
},
API_SCROLL_INTO_VIEW : function(sender, params) {
var seq = params[0];
var sel = params[1];
var edge = params[2];
if (!sel || !sel.length) return;
if (!edge) {
this.cast('SCROLL_INTO_VIEW', [seq, sel, 'bottom']);
this.cast('SCROLL_INTO_VIEW', [seq, sel, 'top']);
return;
}
if (edge != 'top' && edge != 'bottom') edge = 'top';
var pos, view_height = $(window).height(), scroll_top = $(window).scrollTop();
if (edge == 'top') {
pos = sel.eq(0).offset();
if (pos.top-5 < scroll_top) $(window).scrollTop(pos.top-5);
} else {
sel = sel.eq(sel.length - 1);
pos = sel.offset();
pos.height = sel.outerHeight();
pos.toolbar = 0;
if (configs[seq].toolbar.parent().is(':visible')) pos.toolbar = configs[seq].toolbar.parent().outerHeight()+10;
if (pos.top+pos.height > scroll_top+view_height-pos.toolbar-5) {
$(window).scrollTop( pos.top+pos.height-view_height+pos.toolbar+5);
}
}
}
});
var editor = new DrEditor;
xe.registerApp(editor);
// Header Writer
var header_tag = 'h1,h2,h3,h4,h5,h6';
var HeaderWriter = xe.createPlugin('HeaderWriter', {
configs : null,
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.hx');
var _inputHead = _editor.find('input[type=text]:first');
var _inputLevel = _editor.find(':radio').click(function(){ self.cast('CHANGE_HEADER_FORMAT', [seq, this.value]) });
self.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'HX']);
this.configs[seq] = {
editor : _editor,
inputHead : _inputHead,
inputLevel : _inputLevel
};
return this.configs[seq];
},
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div.xe_dr_hx,'+header_tag)
.each(function(){
var t = $(this);
if (!t.is('.xe_dr_hx')) t = t.wrap('<div>').parent();
t.attr('class', 'eArea _hx').attr('type', 'hx');
var header = t.children(header_tag);
if(!header.attr('id')) header.attr('id', 'h'+(new Date).getTime());
});
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
var header = obj.children('div._hx').children(header_tag).each(function(){ var t=$(this); t.parent().after(t).remove() });
},
API_CHANGE_HEADER_FORMAT : function(sender, params) {
var seq = params[0];
var val = params[1];
this.configs[seq].inputHead.attr('class', 'inputTitle '+val);
},
API_OPEN_HX_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1]; // selection to edit
var bef = params[2]; // selection to be before this editor
var cfg = this.configs[seq];
// Create this editor if it doesn't exists
if(!cfg) cfg = this.create(seq);
this.cast('RESET_EDITOR', [seq, cfg.editor, 'HX']);
if(box) {
var tagName = box.children(header_tag)[0].tagName.toLowerCase();
box.hide().after(cfg.editor);
cfg.inputHead.val( box.find(header_tag).eq(0).text() );
cfg.inputLevel.filter('[value='+tagName+']').click();
} else if (bef) {
$(bef).after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show().find('input[type=text]:first').focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_HX_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._hx:hidden');
if(save) {
var newBox = $('<div>');
var id = box.children(header_tag).attr('id');
var tagName = cfg.inputLevel.filter(':checked').val();
if (!id) id = 'h'+(new Date).getTime();
newBox.html('<'+tagName+' id="'+id+'"></'+tagName+'>').children(':first').text(cfg.inputHead.val());
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'HX']);
} else {
box.show();
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
}
});
editor.registerPlugin(new HeaderWriter);
var IndexWriter = xe.createPlugin('IndexWriter', {
init : function() {
this.configs = {};
},
createIndex : function(seq) {
var toc = $('<ul class="toc"></ul>');
var rand = Math.ceil(Math.random()*1000);
configs[seq].editArea.children('div._hx').children('h1,h2,h3,h4,h5,h6')
.each(function(){
var t = $(this), id = t.attr('id'), n = this.nodeName.replace(/[^0-9]/,'');
if (!id) t.attr('id', id = 'h'+rand+Math.ceil(Math.random()*1000));
toc.append('<li class="toc'+n+'"><a href="#'+id+'">'+t.html()+'</a></li>');
});
return $('<div class="eArea _index">').append(toc);
},
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div.xe_dr_index,ul.toc')
.each(function(){
var t = $(this);
if (t.is('ul')) t = t.wrap('<div>').parent();
t.attr('class', 'eArea _index').attr('type', 'index');
});
},
refreshIndex : function(seq) {
configs[seq].editArea.children('div._index').replaceWith(this.createIndex(seq));
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
var toc = obj.children('div._index').children('ul.toc');
toc.parent().before(toc).remove();
},
API_OPEN_INDEX_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1]; // selection to edit
var bef = params[2]; // selection to be before this editor
if (box) {
box.fadein('fast');
} else if (bef) {
bef.after(box = this.createIndex(seq));
} else {
configs[seq].editArea.append(box = this.createIndex(seq));
}
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
this.cast('SCROLL_INTO_VIEW', [seq, box]);
},
API_AFTER_CLOSE_HX_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
if (save) {
// auto refresh if a header was saved or updated.
this.refreshIndex(seq);
}
},
ONMOVE_PARAGRPH : function(sender, params) {
var seq = params[0];
var selbox = this.cast('GET_SELECTED_PARAGRAPH', [seq]);
if (selbox.filter('div._index').length) {
// auto refresh if a header was moved.
this.refreshIndex(seq);
}
}
});
editor.registerPlugin(new IndexWriter);
// Text Editor
var TextWriter = xe.createPlugin('TextWriter', {
configs : null,
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.txt:first');
var _textarea = $('<textarea>').hide();
var _iframe = _editor.find('iframe').css('height','100%').after(_textarea);
self.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'TXT']);
this.configs[seq] = {
editor : _editor,
iframe : _iframe,
textarea : _textarea,
xpress : null
};
return this.configs[seq];
},
createXpressEditor : function(seq) {
var self = this;
var ed = new xe.XpressCore();
var elAppContainer = this.configs[seq].editor[0];
var oWYSIWYGIFrame = this.configs[seq].iframe[0];
var oIRTextarea = this.configs[seq].textarea[0];
var pHotkey;
ed.registerPlugin(new xe.CorePlugin(function(){ this.oApp.exec('FOCUS',[]) }));
ed.registerPlugin(new xe.StringConverterManager());
ed.registerPlugin(new xe.XE_EditingAreaVerticalResizer(elAppContainer));
ed.registerPlugin(new xe.ActiveLayerManager());
ed.registerPlugin(pHotkey=new xe.Hotkey());
ed.registerPlugin(new xe.XE_WYSIWYGStyler());
ed.registerPlugin(new xe.XE_WYSIWYGStyleGetter());
ed.registerPlugin(new xe.MessageManager(oMessageMap));
ed.registerPlugin(new xe.XE_Toolbar(elAppContainer));
ed.registerPlugin(new xe.XE_UndoRedo());
ed.registerPlugin(new xe.XE_Hyperlink(elAppContainer));
ed.registerPlugin(new xe.XE_EditingAreaManager("WYSIWYG", oIRTextarea, {nHeight:200, nMinHeight:100}, null, elAppContainer));
ed.registerPlugin(new xe.XE_EditingArea_HTMLSrc(oIRTextarea));
ed.registerPlugin(new xe.XE_EditingArea_WYSIWYG(oWYSIWYGIFrame));
ed.registerPlugin(new xe.XpressRangeManager(oWYSIWYGIFrame));
ed.registerPlugin(new xe.XE_ExecCommand(oWYSIWYGIFrame));
ed.registerPlugin(new xe.XE_FontNameWithSelectUI(elAppContainer));
ed.registerPlugin(new xe.XE_FontSizeWithSelectUI(elAppContainer));
ed.registerPlugin(new xe.XE_LineHeightWithSelectUI(elAppContainer));
ed.registerPlugin(new xe.XE_ColorPalette(elAppContainer));
ed.registerPlugin(new xe.XE_FontColor(elAppContainer));
ed.registerPlugin(new xe.XE_BGColor(elAppContainer));
ed.registerPlugin(new xe.XE_SCharacter(elAppContainer));
ed.registerPlugin(new xe.XE_WYSIWYGEnterKey("BR"));
//ed.registerPlugin(new xe.XE_FontSetter(this.getFontFamily(), this.getFontSize()));
// Ctrl+Enter를 입력하면 현재 문단 저장 후 새 텍스트 문단을 보여준다.
pHotkey.add(pHotkey.normalize('ctrl+enter'), function(){
setTimeout(function() { self.cast('CLOSE_EDITOR', [seq, true, 'TXT']) }, 1);
});
pHotkey.add(pHotkey.normalize('esc'), function(){
setTimeout(function() { self.cast('CLOSE_EDITOR', [seq, false, 'TXT']) }, 1);
});
// 에디터 시작
ed.run();
return ed;
},
API_AFTER_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.contents()
.each(function(){
var t = $(this);
if (t.is('div.eArea')) return true;
// clean contentless paragraph {{{
if (
( this.nodeType == 3 && !$.trim(this.nodeValue) ) ||
( t.is('p') && /^\s*(<br ?\/?>)?\s*$/i.test(t.html()) ) ||
( t.is('br') )
) {
t.remove();
return true;
}
// }}} clean contentless paragraph
if(this.nodeType == 3) t = t.wrap('<p />').parent();
if(!t.is('div.xe_dr_txt')) t = t.wrap('<div />').parent();
t.attr('class', 'eArea _txt').attr('type', 'txt');
});
},
API_GETTING_CONTENT : function(sender, params) {
var self = this;
var seq = params[0];
var obj = params[1];
obj.children('div._txt').each(function(){
var div = $(this), node = null;
div.contents().each(function(){
var t = $(this);
if(this.nodeType == 3 || t.is('br,a,b,i,s,u,sub,sup,em,strong,span,img,font')) {
if( t.is('br,img') || $.trim(t.text()) ) {
if(!node) div.before(node = $('<p>'));
node.append(this);
} else {
t.remove();
}
return true;
}
div.before(t);
node = null;
});
div.remove();
});
},
API_OPEN_TXT_EDITOR : function(sender, params) {
var self = this;
var seq = params[0];
var box = params[1];
var bef = params[2]; // selection to be before this editor
var cfg = this.configs[seq];
var meanless;
// Create this editor if it doesn't exists
if (!cfg) cfg = this.create(seq);
// 이벤트 제거를 위해 DOM에서 제거한다.
var tx = cfg.editor.find('div.txEditor:first');
tx.prev().after(tx.remove());
if(box) {
box.hide().after(cfg.editor).find('button.del,div.drag_handle').remove();
cfg.textarea.val( box.html() );
} else if (bef) {
bef.after(cfg.editor);
cfg.textarea.val( '<p><br /></p>' );
} else {
cfg.editor.appendTo(configs[seq].editArea);
cfg.textarea.val( '<p><br /></p>' );
}
cfg.editor.show();
(function(){
try {
meanless = cfg.iframe[0].contentWindow.document.body.firstChild;
cfg.xpress = self.createXpressEditor(seq);
self.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
} catch(e) {
setTimeout(arguments.callee, 10);
}
})();
},
API_CLOSE_TXT_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._txt:hidden');
if(save) {
var newBox = $('<div>').html( cfg.xpress.getIR() );
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'TXT']);
} else {
box.show();
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
}
});
editor.registerPlugin(new TextWriter);
var QuoteWriter = xe.createPlugin('QuoteWriter', {
configs : {},
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.quote:first');
var _textarea = _editor.find('textarea:first');
var _source = _editor.find('input[type=text]:first');
self.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'QUOTE']);
this.configs[seq] = {
editor : _editor,
textarea : _textarea,
source : _source
};
return this.configs[seq];
},
API_SETTING_CONTENT : function(sender, params) {
var self = this;
var seq = params[0];
var obj = params[1];
obj.children('div.xe_dr_blockquote,blockquote.citation')
.each(function(){
var t = $(this);
if (t.is('div.xe_dr_blockquote')) {
t.find('>blockquote').attr('class', 'citation');
} else if (t.is('blockquote')) {
t = t.wrap('<div>').parent();
}
t.attr('class', 'eArea _quote').attr('type', 'quote');
});
},
API_GETTING_CONTENT : function(sender, params) {
var self = this;
var seq = params[0];
var obj = params[1];
obj.children('div._quote').each(function(){
var quote = $(this).children('blockquote.citation');
quote.parent().before(quote).remove();
});
},
API_OPEN_QUOTE_EDITOR : function(sender, params) {
var self = this;
var seq = params[0];
var box = params[1];
var bef = params[2]; // selection to be before this editor
var cfg = this.configs[seq];
if (!cfg) cfg = this.create(seq);
if (box) {
box.hide().after(cfg.editor);
cfg.textarea.val( untranslate(box.find('p').html().replace(/<br ?\/?>/ig, '\n')) );
cfg.source.val(box.find('cite').html());
} else {
self.cast('RESET_EDITOR', [seq, cfg.editor, 'QUOTE']);
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show().find('textarea').focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_QUOTE_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._quote:hidden');
var txt = $.trim(cfg.textarea.val());
if (save && txt) {
var newBox = $('<div>');
var quote = $('<blockquote class="citation" />').append( $('<p>').html( translate(txt).replace(/\r?\n/g, '<br />') ) ).appendTo(newBox);
var src = $.trim(cfg.source.val());
if(src == cfg.source.attr('title')) src = '';
if(src) $('<cite>').html(translate_cite(src)).appendTo(quote);
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'QUOTE']);
} else {
box.show();
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
}
});
editor.registerPlugin(new QuoteWriter);
var MovieWriter = xe.createPlugin('MovieWriter', {
configs : {},
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.movie');
var _textarea = _editor.find('textarea');
self.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'MOVIE']);
this.configs[seq] = {
editor : _editor,
embed : _textarea.eq(0),
desc : _textarea.eq(1),
source : _editor.find('input[type=text]')
};
return this.configs[seq];
},
API_SETTING_CONTENT : function(sender, params) {
var self = this;
var seq = params[0];
var obj = params[1];
obj.children('object,embed,div.xe_dr_mov,div:has(div.embed)')
.each(function(){
var t = $(this);
if (!t.is('div')) t = t.wrap('<div>').parent();
t.attr('class', 'eArea _movie').attr('type', 'movie');
t.find('>embed,>object').wrap('<div class="embed">');
t.find('>p.cite>cite').unwrap();
});
},
API_GETTING_CONTENT : function(sender, params) {
var self = this;
var seq = params[0];
var obj = params[1];
var mov = obj.children('div._movie').children('embed,object');
// TODO : 플래시 태그면 embed, object를 모두 사용하도록 변환
obj.parent().before(mov).remove();
},
API_OPEN_MOVIE_EDITOR : function(sender, params) {
var self = this;
var seq = params[0];
var box = params[1];
var bef = params[2]; // selection to be before this editor
var cfg = this.configs[seq];
if (!cfg) cfg = this.create(seq);
self.cast('RESET_EDITOR', [seq, cfg.editor, 'MOVIE']);
if (box) {
var embed = $.trim( box.find('>div.embed').html() );
var desc = $.trim( box.find('>p.desc').html() );
var source = $.trim( box.find('>cite').html() );
cfg.embed.val( embed );
cfg.desc.val( desc );
cfg.source.val( source );
box.hide().after(cfg.editor);
} else if (bef) {
bef.after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show().find('textarea:first').focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_MOVIE_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._movie:hidden');
var val = $.trim(cfg.embed.val());
if (save && val) {
var newBox = $('<div>').append( $('<div class="embed">').html(val) );
var desc = $.trim(cfg.desc.val());
var source = $.trim(cfg.source.val());
if (desc == cfg.desc.attr('title')) desc = '';
if (source == cfg.source.attr('title')) source = '';
if (desc) newBox.append( $('<p class="desc">').text(desc) );
if (source) newBox.append( $('<cite>').html(translate_cite(source)) );
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'MOVIE']);
} else {
box.show();
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
}
});
editor.registerPlugin(new MovieWriter);
// Image Writer
var ImageWriter = xe.createPlugin('ImageWriter', {
configs : null,
_iframe : null,
_form : null,
init : function() {
var target = 'xe_dr_imgframe_'+(new Date).getTime();
this.configs = {};
this._iframe = $('<iframe name="'+target+'" src="about:blank" style="position:absolute;width:1px;height:1px;left:-2000px;top:0">');
this._form = $('<form target="'+target+'" method="POST" enctype="multipart/form-data" style="position:absolute;width:1px;height:1px;left:-2000px;"></form>')
.append('<input type="hidden" name="editor_sequence" value="" />')
.append('<input type="hidden" name="callback" />')
.append('<input type="hidden" name="file_srl" />')
.append('<input type="hidden" name="mid" value="" />')
.append('<input type="hidden" name="module" value="file" />')
.append('<input type="hidden" name="act" value="procFileIframeUpload" />')
.append('<input type="hidden" name="uploadTargetSrl" value="" />');
if (typeof(xeVid) != 'undefined') this._form.append('<input type="hidden" name="vid" value="'+xeVid+'" />');
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.img');
var _file = _editor.find('input[type=file]');
var _desc = _editor.find('input[type=text].desc');
var _image = _editor.find('div.image > img');
var _resize = _editor.find('div.resize');
var _align = _editor.find('div.align');
var _message = _editor.find('p.uploading');
self.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'IMG']);
_file.change(function(){
var t = $(this);
var prev = t.prev();
if ( !/\.(jpe?g|png|gif)$/i.test(t.val()) ) {
t.val('');
return false;
}
var callback_id = ''+(new Date).getTime()+Math.ceil(Math.random()*1000);
window[callback_id] = function(fileObj){ self.onfileuploaded(seq, callback_id, fileObj); }
var filesrl = (_image.attr('class')||'').match(/(?:^|\s)xe_filesrl_(\d+)(?:\s|$)/);
filesrl = (filesrl && filesrl[1])? filesrl[1] : '';
// upload file
self._form.find('input[name=editor_sequence]').val(seq);
self._form.find('input[name=callback]').val(callback_id);
self._form.find('input[name=file_srl]').val(filesrl);
self._form.find('input[name=uploadTargetSrl]').val(editorRelKeys[seq]["primary"].value);
self._form.append(t).submit();
setTimeout(function(){ self.reset_fileform(t); prev.after(t) }, 0);
// hide image and show uploading
_image.parent().hide();
_file.hide();
_resize.hide();
_align.hide();
_message.show();
});
_message.find('button').click(function(){
self._iframe.attr('src', 'about:blank');
_file.show();
_message.hide();
if (_image.attr('src')) _image.parent().show();
});
_align.find('input[type=radio]').click(function(){ _image.parent().css('text-align', this.value); });
_resize.find('button.btn_resize').click(function(){
var w = parseInt(_resize.find('input[type=text].width').val());
var n = parseInt(_resize.find('dd>em').text());
if (isNaN(w) || isNaN(n) || w > n) {
_resize.find('p.resizeError').show();
return false;
}
_resize.find('p.resizeError').hide();
var _src = _image.attr('rawsrc') || _image.attr('src');
$.exec_json('file.procFileImageResize',{width:w, source_src:decodeURI(_src)},function(data){
if(data.error != 0) return;
_image.attr({
src : encodeURI(data.resized_info.src),
width : data.resized_info.info[0],
height : data.resized_info.info[1]
});
if(!_image.attr('rawsrc')) _image.attr('rawsrc', _src);
});
})
this.configs[seq] = {
editor : _editor,
file : _file,
desc : _desc,
image : _image,
resize : _resize,
align : _align,
message : _message
};
return this.configs[seq];
},
show_resize : function(seq, src) {
var cfg = this.configs[seq];
cfg.resize.find('p.resizeError').hide();
cfg.image
.load(function(){ var w=this.width, h=this.height, t=$(this); if(w>600){ cfg.resize.show().find('dd>em').text(w);cfg.resize.find('dd>input:text').val(600); } })
.attr('src', src)
.parent().show();
},
reset_fileform : function(obj) {
var next = obj.next();
var form = $('<form>').append(obj)[0].reset();
next.before(obj);
},
onfileuploaded : function(seq, callback_id, fileObj) {
// remove callback function
try {
delete window[callback_id];
} catch(e) {
window[callback_id] = null;
}
if(fileObj.error==-1){
alert(fileObj.message);
return;
}
var self = this;
var cfg = this.configs[seq];
if(fileObj.upload_target_srl && fileObj.upload_target_srl != 0) {
editorRelKeys[seq]['primary'].value = fileObj.upload_target_srl;
}
// show resize
cfg.image
.removeAttr('width')
.removeAttr('height')
.removeAttr('rawsrc')
.attr('filesrl', fileObj.file_srl);
cfg.file.show();
cfg.align.show();
cfg.message.hide();
this.show_resize(seq, encodeURI(fileObj.uploaded_filename));
// 이미지 파일도 서버측에서는 파일로 카운트 되므로,
// reloadFileList를 호출해서 orderedFiles와 uploadedFiles 배열을 갱신해주도록 한다.
// 관련 이슈 : http://textyle.xpressengine.net/18256095
var settings = {
fileListAreaID : '',
editorSequence : seq,
uploadTargetSrl : ''
};
reloadCallback[seq] = function(){};
reloadFileList(settings);
},
API_ONREADY : function() {
this._form.attr('action', request_uri)
this._form.find('input[name=mid]').val(current_mid);
this._iframe.appendTo(document.body).after(this._form);
},
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('img,p.img,div._img,div.xe_dr_img')
.each(function(){
var t = $(this);
if(t.is('img')) t = t.wrap('<p class="img"></p>');
if(t.is('p.img')) t = t.wrap('<div></div>').parent();
if(t.is('div.xe_dr_img')) {
var img = t.children('p:has(img)').attr('class', 'img');
var desc = t.children('p.desc').remove();
var cite = t.children('p.cite').remove();
var s_desc = $.trim(desc.html() || '');
var s_cite = $.trim(cite.html() || '');
var s_text = [];
if (s_desc) s_text.push(s_desc);
if (s_cite) s_text.push(s_cite);
if (s_text.length) img.append('<br>').append($('<div>').html(s_text.join(' - ')).contents());
}
t.attr('class', 'eArea _img').attr('type', 'img');
});
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div._img')
.each(function(){
var t = $(this);
var p = t.children('p').attr('class', 'img');
t.before(p).remove();
});
},
API_OPEN_IMG_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1];
var bef = params[2];
var cfg = this.configs[seq];
if (!cfg) cfg = this.create(seq);
// reset
this.cast('RESET_EDITOR', [seq, cfg.editor, 'IMG']);
if(box) {
var p = box.children('p.img:first');
var img = p.find('img');
box.hide().after(cfg.editor);
cfg.align.show();
if (img.attr('rawsrc')) cfg.image.attr('rawsrc', img.attr('rawsrc'));
this.show_resize(seq, img.attr('src'));
var align = p.css('text-align');
if (align) {
cfg.align.find('input[value='+align.toLowerCase()+']').attr('checked', 'checked');
cfg.image.parent().css('text-align', align);
}
var _class = img.attr('class').match(/(?:^|\s)xe_filesrl_(\d+)(?:\s|$)/);
if (_class && _class[1]) cfg.image.attr('filesrl', _class[1]);
var desc = $.trim(p.text());
if (desc) cfg.desc.val(desc);
} else if (bef) {
bef.after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show();
(($.browser.msie||$.browser.opera)?cfg.desc:cfg.file).focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_IMG_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._img:hidden');
if (save && cfg.image.attr('src')) {
var align = cfg.align.find('input[type=radio]:checked').val();
var newBox = $('<div>');
var img = $('<img>').attr('src', cfg.image.attr('src'));
var rawsrc = cfg.image.attr('rawsrc');
$('<p class="img">').css('text-align', align).append(img).appendTo(newBox);
img.attr({ 'width':cfg.image.attr('width'), 'height':cfg.image.attr('height') });
if (rawsrc) img.attr('rawsrc', rawsrc);
var desc = $.trim(cfg.desc.val());
if (desc && desc != cfg.desc.attr('title')) img.after(translate_cite(desc)).after('<br />');
var filesrl = cfg.image.attr('filesrl');
if (filesrl) img.addClass('xe_filesrl_'+filesrl);
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'IMG']);
} else {
box.show();
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
},
API_BEFORE_RESET_EDITOR : function(sender, params) {
var seq = params[0];
var type = params[2];
var cfg = this.configs[seq];
if (type == 'IMG') {
cfg.image
.removeAttr('filesrl')
.removeAttr('width')
.removeAttr('height')
.removeAttr('src')
.removeAttr('rawsrc')
.parent().css('text-align', '').hide();
cfg.resize.hide().find('input[type=text]').val('');
cfg.align.hide().find('input[type=radio]:first').attr('checked', 'checked');
cfg.file.show();
cfg.desc.val('');
this.reset_fileform(cfg.file);
}
},
API_AFTER_DELETE_PARAGRAPH : function(sender, params) {
var self = this;
var seq = params[0];
var target = params[1];
if (target && target.length) {
var srl = [];
target.filter('div._img').each(function(){
var s = $(this).find('img[class^=xe_filesrl]').attr('class').replace('xe_filesrl_','');
if(s) srl.push(s);
});
if(srl.length) exec_xml('file','procFileDelete',{file_srls:srl.join(','),editor_sequence:seq});
}
}
});
editor.registerPlugin(new ImageWriter);
// Material Writer
var MaterialWriter = xe.createPlugin('MaterialWriter', {
configs : {},
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.material:first');
var _buttons = _editor.find('div.controls button');
_buttons.eq(0).click(function(){ self.load_material(seq, 1); });
_buttons.eq(1).click(function(){ self.cast('CLOSE_EDITOR', [seq, false, 'MATERIAL']); });
this.configs[seq] = {
editor : _editor,
template : _editor.find('div._container > dl').remove(),
to_save : null,
loaded : false,
prev_page : 0,
next_page : 0,
total_page : 0
};
this.load_material(seq, 1);
return this.configs[seq];
},
load_material_next : function(seq){
var cfg = this.configs[seq];
if(++cfg.next_page>=cfg.total_page) cfg.next_page=cfg.total_page;
cfg.next_page = cfg.next_page>0?cfg.next_page:1;
this.load_material(seq, cfg.next_page);
},
load_material_prev : function(seq){
var cfg = this.configs[seq];
cfg.prev_page = --cfg.prev_page>0?cfg.prev_page:1;
this.load_material(seq, cfg.prev_page);
},
load_material : function(seq, page) {
var self = this;
var cfg = this.configs[seq];
var area = cfg.editor.find('div._container');
var paginate = cfg.editor.find('div.paginate');
if (!page) page = 1;
function callback(data){
if(data.page_navigation.total_count) cfg.editor.find('p.noData').css('display','none');
// 글감 목록 전부 삭제
area.children().remove();
// 페이징
paginate.find('> span').text(data.page_navigation.cur_page+'/'+data.page_navigation.total_page);
cfg.prev_page = data.page_navigation.cur_page;
cfg.next_page = data.page_navigation.cur_page;
cfg.total_page = data.page_navigation.total_page;
if(!cfg.loaded){
paginate.find('> button.prev').click(function(){ self.load_material_prev(seq) });
paginate.find('> button.next').click(function(){ self.load_material_next(seq) });
}
// 컨텐트 추가
$.each(data.material_list, function(){
var tpl = cfg.template.clone();
tpl.addClass('xe_dr_'+this.type);
tpl.find('dt').text(this.regdate.substring(0,4)+'.'+this.regdate.substring(4,6)+'.'+this.regdate.substring(6,8)+' '+this.regdate.substring(8,10)+':'+this.regdate.substring(10,12));
tpl.find('dd > div.eArea').html(this.content);
tpl.find('dd > span.btnDrEditor > button').click(function(event){
var t = $(event.target);
var o = t.parent().prev('div.eArea').eq(0).clone();
self.cast('SETTING_CONTENT', [seq, o]);
cfg.to_save = o;
self.cast('CLOSE_MATERIAL_EDITOR', [seq, true]);
});
area.append(tpl);
});
cfg.loaded =true;
}
if(area.length) $.exec_json('material.dispMaterialList',{page:page, list_count:4}, callback);
},
API_OPEN_MATERIAL_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1];
var bef = params[2];
var cfg = this.configs[seq];
if (!cfg) cfg = this.create(seq);
if (bef) {
bef.after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_MATERIAL_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box;
if (save && cfg.to_save) {
var newBox = cfg.to_save.children('div.eArea');
cfg.to_save = null;
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, '']);
} else {
box = cfg.editor.prev('div.eArea');
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
}
});
editor.registerPlugin(new MaterialWriter);
// File Writer
var regex_srl = /filesrl_([0-9-]+)/;
var FileWriter = xe.createPlugin('FileWriter', {
configs : {},
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.file');
var _files = _editor.find('dl.attachedFile');
var _summary = _editor.find('p.summary').next('div.hr').andSelf();
var _template = _files.find('> dd:first').show().remove();
var _count = _summary.find('strong.filecount');
var _size = _summary.find('em.filesize');
var _inputs = _editor.find('input[type=text]');
this.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'FILE']);
this.configs[seq] = {
editor : _editor,
template : _template,
summary : _summary,
files : _files,
count : _count,
size : _size,
desc : _inputs.eq(0),
cite : _inputs.eq(1),
n_count : 0,
n_size : 0,
queue_idx : 0
};
return this.configs[seq];
},
onstartupload : function(seq) {
this.configs[seq].queue_idx = 0;
},
onfileuploaded : function(seq, fileObj, serverData, obj) {
var self = this;
var cfg = this.configs[seq];
var tpl = cfg.template.clone();
tpl.find('>strong').text(fileObj.name);
tpl.find('>em').text(this.formatsize(fileObj.size));
tpl.addClass('filesrl_-'+(orderedFiles.length+cfg.queue_idx));
tpl.find('button.btnDelete').click(function(){ self.ondelete(seq, $(this)) }).hide();
tpl.appendTo(cfg.files);
cfg.files.show().append(tpl);
cfg.queue_idx++;
// summary
cfg.summary.show();
cfg.count.text(++cfg.n_count);
cfg.size.text(this.formatsize(cfg.n_size += fileObj.size));
// process next queue
if (obj.getStats().files_queued > 0) obj.startUpload();
},
onreloadlist : function(seq, upload_target_srl) {
var cfg = this.configs[seq];
if(upload_target_srl) editorRelKeys[seq].primary.value = upload_target_srl;
cfg.files.children('dd').each(function(){
var dd = $(this);
var srl = dd.attr('class').match(regex_srl);
var cls;
if (!srl || !srl[1]) return;
cls = srl[0]; srl = parseInt(srl[1]);
if (srl <= 0) {
var fileObj = orderedFiles[Math.abs(srl)];
if (!fileObj) return;
// 기존 파일 시퀀스를 지우고 새 시퀀스 추가
dd.removeClass(cls).addClass('filesrl_'+fileObj.file_srl);
// 삭제버튼 보여주기
dd.find('button.btnDelete').show();
}
});
},
ondelete : function(seq, btn) {
var cfg = this.configs[seq];
var srl = btn.parent().attr('class').match(regex_srl);
if (!srl || !srl[1] || (srl=parseInt(srl[1])) < 0) return;
// remove this file
btn.parent().remove();
if (!cfg.files.children('dd').length) {
cfg.files.hide();
cfg.summary.hide();
}
// TODO : delete this file from the server
var fileObj = uploadedFiles[srl];
if (fileObj) {
cfg.count.text(--cfg.n_count);
cfg.size.text(this.formatsize(cfg.n_size -= fileObj.file_size));
}
},
formatsize : function(size) {
size = parseFloat(size);
if (isNaN(size)) return 'NaN';
var units = ['B','KB','MB','GB','TB'];
var i = 0;
while((i < units.length-1) && size > 1024) {
size /= 1024;
i++;
}
size = (size+'').replace(/(\.\d{2})\d+$/, '$1') + ' ' + units[i];
return size;
},
API_ONREADY : function() {
reloadFileList({fileListAreaID:'',editorSequence:1,uploadTargetSrl:''});
},
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div.xe_dr_file,dl.attachedFile')
.each(function(){
var t = $(this);
if (t.is('dl')) {
var div = t.wrap('<div>').parent();
if ((t=t.next('p.desc,p.cite')).length) div.appned(t);
if ((t=t.next('p.desc,p.cite')).length) div.appned(t);
t = div;
}
t.attr('class', 'eArea _file').attr('type', 'file');
});
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div._file')
.each(function(){
var t = $(this);
t.before(t.children('dl,p')).remove();
});
},
API_OPEN_FILE_EDITOR : function(sender, params) {
var self = this;
var init = false;
var seq = params[0];
var box = params[1];
var bef = params[2];
var cfg = this.configs[seq];
if (!cfg) {
cfg = this.create(seq);
init = true;
}
this.cast('RESET_EDITOR', [seq, cfg.editor, 'FILE']);
if(box) {
box.find('dl.attachedFile > dd').each(function(){
var dd = $(this);
var tpl = cfg.template.clone();
var srl = dd.attr('class').match(regex_srl);
if (!srl || !(srl=srl[1])) return;
srl = parseInt(srl);
tpl.addClass('filesrl_'+srl);
tpl.find('>strong').text(dd.find('>a').text());
tpl.find('>em').text(dd.find('>span').text());
tpl.find('button.btnDelete').click(function(){ self.ondelete(seq, $(this)) });
cfg.n_count++;
cfg.n_size += parseInt(uploadedFiles[srl].file_size) || 0
cfg.files.append(tpl);
});
cfg.count.text(cfg.n_count);
cfg.size.text(this.formatsize(cfg.n_size));
cfg.files.show();
cfg.summary.show();
box.hide().after(cfg.editor);
} else if (bef) {
bef.after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show();
cfg.desc.focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
if (init) {
// if you use firebug, this code will crash your firefox browser.
reloadCallback[seq] = function(upload_target_srl){ self.onreloadlist(seq, upload_target_srl) };
uploaderSettings['editorSequence'] = seq;
uploaderSettings['upload_start_handler'] = function(){ self.onstartupload(seq) };
uploaderSettings['upload_success_handler'] = function(file,serverData){self.onfileuploaded(seq,file,serverData,this)};
editorUploadInit(uploaderSettings);
init = true;
}
},
API_CLOSE_FILE_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._file:hidden');
var file = cfg.files.children('dd');
var desc = $.trim(cfg.desc.val());
var cite = $.trim(cfg.cite.val());
if (save && file.length) {
var newBox = $('<div>');
var dl = $('<dl class="attachedFile"><dt>'+xe.lang.attached_files+'</dt></dl>').appendTo(newBox);
$.each(file, function(){
var dd = $(this);
var srl = dd.attr('class').match(regex_srl);
if (!srl || !(srl=srl[1])) return;
srl = parseInt(srl);
var fileObj = uploadedFiles[srl];
var a = $('<a>').attr('href', request_uri + fileObj.download_url.replace(/\&amp;/g, '&')).text(fileObj.source_filename);
var sz = $('<span>').text(fileObj.disp_file_size);
$('<dd>').attr('class', 'filesrl_'+srl).append(a).append(sz).appendTo(dl);
});
if (desc && desc != cfg.desc.attr('title')) newBox.append($('<p class="desc">').html(translate(desc)));
if (cite && cite != cfg.cite.attr('title')) newBox.append($('<p class="cite">').html(translate(cite)));
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'FILE']);
} else {
box.show();
}
if(!box.length) box = cfg.editor.prev('div.eArea');
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
},
API_BEFORE_RESET_EDITOR : function(sender, params) {
var seq = params[0];
var type = params[2];
if (type == 'FILE') {
var cfg = this.configs[seq];
cfg.n_count = 0;
cfg.n_size = 0;
cfg.count.text(0);
cfg.size.text(0);
cfg.summary.hide();
cfg.files.empty().hide();
}
},
API_AFTER_DELETE_PARAGRAPH : function(sender, params) {
var self = this;
var seq = params[0];
var target = params[1];
if (target && target.length) {
var srl = [];
target.filter('div._file').each(function(){
$(this).find('dd[class^=filesrl_]').each(function(){
var s = $(this).attr('class').replace('filesrl_','');
if(s) srl.push(s);
});
});
if(srl.length) exec_xml('file','procFileDelete',{file_srls:srl.join(','),editor_sequence:seq});
}
}
});
if(window.reloadFileList) editor.registerPlugin(new FileWriter);
// List Writer
var ListWriter = xe.createPlugin('ListWriter', {
configs : {},
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.list');
var _toolbar = _editor.find('ul.toolbar');
var _list = _editor.find('div.listArea');
this.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'LIST']);
_toolbar.find('button').click(function(){
var type = $(this).attr('class').match(/type_([a-z\-]+)/);
if (!type || !type[1]) return false;
self.ontoolbutton(seq, type[1]);
return false;
});
this.configs[seq] = {
editor : _editor,
toolbar : _toolbar,
list : _list,
focused : null
};
return this.configs[seq];
},
ontoolbutton : function(seq, type) {
var cfg = this.configs[seq];
if (!cfg.focused) return alert(no_selected_object_msg);
var par = cfg.focused.parent('li').parent('ul,ol');
if (par.length && type) par.eq(0).css('list-style-type', type);
cfg.focused.focus();
},
add_event : function(seq) {
var self = this;
this.configs[seq].list.find('li > input:not(.hasHandler)')
.addClass('hasHandler xe_content')
.keydown(function(event){ return self.onkeydown(seq, event) })
.focus(function(event){ return self.onfocus(seq, event) });
},
new_item : function(returnObj) {
var html = '<li><input type="text" /></li>';
return returnObj?$(html):html;
},
onkeydown : function(seq, event) {
var self = this;
var meta = event.metaKey;
var ctrl = event.ctrlKey;
var cfg = this.configs[seq];
var obj = $(event.target);
var li = obj.parent('li');
var item, ul, prev, next, val='', start, end, stop = false;
switch(event.keyCode) {
case 13: // enter
stop = true;
if (ctrl) {
setTimeout(function(){ self.cast('CLOSE_EDITOR', [seq, true, 'LIST']) }, 1);
} else {
if (!$.trim(obj.val())) return obj.focus() && false;
var start = this.get_pos(obj, 'start');
var end = this.get_pos(obj, 'end');
var val = obj.val().substr(end);
obj.val( obj.val().substr(0, start) );
li.after(item = this.new_item(true));
this.add_event(seq);
this.set_pos( item.find('>input').focus().val(val), 0 );
}
break;
case 27: // ESC
stop = true;
setTimeout(function(){ self.cast('CLOSE_EDITOR', [seq, false, 'LIST']) }, 1);
break;
case 37: // left
if (!ctrl) break;
stop = true;
this.move_left(obj, li);
setTimeout(function(){obj.focus();}, 1);
break;
case 39: // right
if (!ctrl) break;
stop = true;
this.move_right(obj, li);
setTimeout(function(){obj.focus();},1);
break;
case 38: // up
if (!ctrl) {
if (!event.altKey && !event.shiftKey) {
var objs = cfg.list.find('input[type=text]');
var idx = objs.index(obj);
if (idx > 0) objs.eq(idx-1).focus();
}
break;
}
stop = true;
this.move_up(obj, li);
setTimeout(function(){obj.focus();}, 1);
break;
case 40: // down
if (!ctrl) {
if (!event.altKey && !event.shiftKey) {
var objs = cfg.list.find('input[type=text]');
var idx = objs.index(obj);
if (idx < objs.length-1) objs.eq(idx+1).focus();
}
break;
}
stop = true;
this.move_down(obj, li);
setTimeout(function(){obj.focus()}, 1);
break;
case 8: // backspace
start = this.get_pos(obj, 'start');
if (start == 0) {
var lis = cfg.editor.find('li > input[type=text]');
var n_li = lis.index(obj);
if (n_li > 0) {
stop = true;
prev = lis.eq(n_li - 1);
val = prev.val();
prev.focus().val( val + ($.browser.opera?' ':'') + obj.val() );
this.set_pos(prev, val.length + ($.browser.opera?1:0));
// remove current item
obj.parent().remove();
}
}
break;
case 46: // delete
start = this.get_pos(obj, 'start');
end = this.get_pos(obj, 'end');
if ((start == end) && (end == obj.val().length)) {
var lis = cfg.editor.find('li > input[type=text]');
var n_li = lis.index(obj);
if (n_li < lis.length-1) {
stop = true;
next = lis.eq(n_li + 1);
val = obj.val();
obj.val( val + ($.browser.opera?' ':'') + next.val() );
this.set_pos(obj, val.length);
// remove next item
next.parent().remove();
}
}
break;
}
return !stop;
},
get_pos : function(obj, type) {
var n_before, n_after;
if (typeof obj[0].selectionStart == 'number') {
n_before = obj[0].selectionStart;
n_after = obj[0].selectionEnd;
} else if(document.selection) {
var before = document.selection.createRange().duplicate();
var after = document.selection.createRange().duplicate();
var n_before, n_after;
before.moveEnd('character', obj.val().length);
after.moveStart('character', -obj.val().length);
n_before = (before.text=='')?obj.val().length:obj.val().lastIndexOf(before.text);
n_after = after.text.length;
}
if (n_before == n_after || type == 'start') return n_before;
else if (type == 'end') return n_after;
},
set_pos : function(obj, pos) {
if (typeof obj[0].setSelectionRange == 'function') {
obj[0].setSelectionRange(pos, pos);
} else if(obj[0].createTextRange) {
var range = obj[0].createTextRange();
range.moveStart('character', pos);
range.collapse(true);
range.select();
}
},
move_up : function(obj, li) {
if (li.prev('li').length) return li.prev('li').before(li);
var lev = this.get_level(li);
if (lev == 1) return;
var par = li.parent().parent('li');
var prv = par.prev('li');
if (prv.length) {
var oul = prv.children('ul,ol');
if (!oul.length) oul = $('<ul>').appendTo(prv);
oul.append(li);
} else if (li.is(':first') && par.is(':first')) {
par = par.parents('li');
par.eq(par.length-1).before(li);
} else {
par.parent('ol,ul').prepend(li);
}
},
move_down : function(obj, li) {
if (li.next('li').length) return li.next('li').after(li);
var lev = this.get_level(li);
if (lev == 1) return;
var par = li.parent().parent('li');
var nxt = par.next('li');
if (nxt.length) {
var oul = nxt.children('ul,ol');
if (!oul.length) oul = $('<ul>').appendTo(nxt);
oul.prepend(li);
} else if (li.is(':last') && par.is(':last')) {
par = par.parents('li');
par.eq(par.length-1).after(li);
} else {
par.parent('ol,ul').append(li);
}
},
move_left : function(obj, li) {
if (this.get_level(li) == 1) return;
var next = li.nextAll('li');
var list = li.children('ul,ol');
if (next.length) {
if (!list.length) li.append(list = $('<ul>'));
list.append(next);
}
li.parent().parent('li').after(li);
},
move_right : function(obj, li) {
var prev = li.prev('li');
var list = prev.children('ul,ol');
if (list.length) {
list.append(li);
} else if (prev.length) {
$('<ul>').append(li).appendTo(prev);
}
},
get_level : function(elem) {
var el = $(elem).get(0);
var lev = 0;
var tag = '';
while(el) {
tag = el.tagName.toLowerCase();
if (tag == 'div' && el.className == 'listArea') break;
if (tag == 'ul' || tag == 'ol') lev++;
el = el.parentNode;
}
return lev;
},
onfocus : function(seq, event) {
this.configs[seq].focused = $(event.target);
},
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('ul,ol,div.xe_dr_list').each(function(){
var t = $(this);
if (!t.is('div')) t = t.wrap('<div />').parent();
t.attr('class', 'eArea _list').attr('type', 'list').find('ol>br,ul>br').remove();
});
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div._list')
.each(function() {
var list = $(this).children('ul,ol');
list.parent().before(list).remove();
});
},
API_OPEN_LIST_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1];
var bef = params[2];
var cfg = this.configs[seq];
if (!cfg) cfg = this.create(seq);
this.cast('RESET_EDITOR', [seq, cfg.editor, 'LIST']);
if(box) {
box.hide().after(cfg.editor)
.children('ul,ol').clone()
.appendTo(cfg.list.empty())
.find('li')
.each(function(){
var t = $(this);
var c = t.children('ul,ol').remove();
var v = $.trim(t.text());
t.empty().append( $('<input type="text">').val(v) ).append(c);
});
} else if (bef) {
bef.after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
this.add_event(seq);
cfg.editor.show().find('input[type=text]:first').focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_LIST_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._list:hidden');
if (save) {
var newBox = $('<div>');
var list = cfg.list.children('ul,ol').appendTo(newBox);
var div = $('<div>');
list.find('input[type=text]').each(function(){
var t = $(this);
var v = $.trim(t.val());
if (v || t.parent().children('ul,ol').length) {
div.text(v);
t.before(div[0].firstChild).remove();
} else {
t.parent().remove();
}
});
list.find('ul:not(:has(li)),ol:not(:has(li))').remove();
if (list.children('li').length) {
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'LIST']);
}
}
if(!box.length) box = cfg.editor.prev('div.eArea');
box.show();
cfg.editor.hide().appendTo(configs[seq].writeArea);
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
},
API_AFTER_RESET_EDITOR : function(sender, params) {
var seq = params[0];
var edit = params[1];
var type = params[2];
var cfg = this.configs[seq];
if (type == 'LIST') {
cfg.list.html('<ul><li><input type="text" /></li></ul>');
}
}
});
editor.registerPlugin(new ListWriter);
// Link Writer
var LinkWriter = xe.createPlugin('LinkWriter', {
configs : {},
init : function() {
this.configs = {};
},
create : function(seq) {
var self = this;
var _editor = configs[seq].writeArea.find('>div.link');
var _inputs = _editor.find('input[type=text]');
var _text = _inputs.eq(0);
var _url = _inputs.eq(1);
var _desc = _inputs.eq(2);
this.cast('ADD_DEFAULT_EDITOR_ACTION', [seq, _editor, 'LINK']);
this.configs[seq] = {
editor : _editor,
text : _text,
url : _url,
desc : _desc
};
return this.configs[seq];
},
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div.xe_dr_link,p.link')
.each(function(){
var t = $(this);
if (t.is('div.xe_dr_link')) {
var p = t.children('p');
if (p.length > 1) p.eq(0).append('<br />').append( $('<span class="desc"></span>').text(p.eq(1).text()) );
p.eq(0).children('a').before('<br />');
p.eq(1).remove();
} else {
t = t.wrap('<div>').parent();
}
t.attr('class', 'eArea _link').attr('type', 'link');
});
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div._link')
.each(function(){
var p = $(this).children('p');
p.parent().before(p).remove();
});
},
API_OPEN_LINK_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1];
var bef = params[2];
var cfg = this.configs[seq];
if (!cfg) cfg = this.create(seq);
this.cast('RESET_EDITOR', [seq, cfg.editor, 'LINK']);
if(box) {
box.hide().after(cfg.editor);
cfg.text.val( box.find('strong').text() );
cfg.url.val( box.find('a').attr('href') );
var desc = $.trim(box.find('span.desc').text());
if (desc) cfg.desc.val( desc );
} else if (bef) {
bef.after(cfg.editor);
} else {
cfg.editor.appendTo(configs[seq].editArea);
}
cfg.editor.show();
cfg.text.focus();
this.cast('SCROLL_INTO_VIEW', [seq, cfg.editor]);
},
API_CLOSE_LINK_EDITOR : function(sender, params) {
var seq = params[0];
var save = params[1];
var cfg = this.configs[seq];
var box = cfg.editor.prev('div._link:hidden');
var text = $.trim(cfg.text.val());
var url = $.trim(cfg.url.val());
var desc = $.trim(cfg.desc.val());
if (url == cfg.url.attr('title')) url = '';
if (desc == cfg.desc.attr('title')) desc = '';
if (save && text && url) {
var newBox = $('<div>');
var para = $('<p class="link">').appendTo(newBox)
.append( $('<strong>').text( text ) )
.append( $('<br />') )
.append( $('<a>').attr('href', url).text(url) );
if (desc) para.append('<br />').append( $('<span class="desc" />').text(desc) );
box.remove();
this.cast('SAVE_PARAGRAPH', [seq, cfg.editor, box=newBox, 'LINK']);
}
if(!box.length) box = cfg.editor.prev('div.eArea');
box.show();
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
cfg.editor.hide().appendTo(configs[seq].writeArea);
}
});
editor.registerPlugin(new LinkWriter);
// HR Writer
var HRWriter = xe.createPlugin('HRWriter', {
API_SETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('hr,div.xe_dr_hr').each(function(){
var t = $(this);
if (!t.is('div')) t = t.wrap('<div>').parent();
t.attr('class', 'eArea _hr').attr('type', 'hr');
});
},
API_GETTING_CONTENT : function(sender, params) {
var seq = params[0];
var obj = params[1];
obj.children('div._hr').each(function(){
var hr = $(this).find('hr');
hr.parent().before(hr).remove();
});
},
API_OPEN_HR_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1];
var bef = params[2];
if (box && box.length) {
box.show(300);
} else if (bef && bef.length) {
bef.after(box = $('<div class="eArea _hr"><hr /></div>').attr('type', 'hr'));
} else {
var newBox = box = $('<div class="eArea _hr" />').attr('type', 'hr');
configs[seq].editArea.append(newBox.append('<hr />'));
}
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
}
});
editor.registerPlugin(new HRWriter);
// Help
var HelpViewer = xe.createPlugin('Help', {
views : {},
init : function() {
this.views = {};
},
create : function(seq) {
var self = this;
this.views[seq] = configs[seq].writeArea.find('div.help');
this.views[seq].find('button').click(function(){ self.cast('CLOSE_EDITOR', [seq, false, 'HELP']); });
},
API_OPEN_HELP_EDITOR : function(sender, params) {
var seq = params[0];
var box = params[1];
var bef = params[2];
if(!this.views[seq]) this.create(seq);
if(box) {
box.after(this.views[seq]);
} else if (bef) {
bef.after(this.views[seq]);
} else {
configs[seq].writeArea.prepend(this.views[seq]);
}
this.views[seq].show().find('button').focus();
this.cast('SCROLL_INTO_VIEW', [seq, this.views[seq]]);
},
API_CLOSE_HELP_EDITOR : function(sender, params) {
var seq = params[0];
var box = this.views[seq].prev('div.eArea');
this.views[seq].hide();
this.cast('SELECT_PARAGRAPH', [seq, box, box, box]);
}
});
editor.registerPlugin(new HelpViewer);
// More
var More = xe.createPlugin('More', {
API_BEFORE_CLICK_TOOLBUTTON : function(sender, params) {
var seq = params[0];
var button = $(params[1]);
if(!button.parent().is('li.more')) return true;
button.parents('div.wToolbarContainer:first').toggleClass('more');
this.cast('TOOLBAR_REPOSITION', [seq]);
return false;
}
});
editor.registerPlugin(new More);
// Validator plugin
var ValidatorHook = xe.createPlugin('ValidatorHook', {
API_BEFORE_VALIDATE : function(sender, params) {
var form = $(params[0]);
var seq = form[0].elements['editor_sequence'].value;
var wArea_e = configs[seq].editArea.children('div.wArea:visible').filter(':not(.blank)');
var wArea_w = configs[seq].writeArea.children('div.wArea:visible').filter(':not(.blank)');
if (wArea_e.length || wArea_w.length) {
return !!confirm(submit_without_saving_msg);
}
return true;
}
});
xe.getApp('Validator')[0].registerPlugin(new ValidatorHook);
// Utility function
var table = {'<':'&lt;','>':'&gt;','&':'&amp;','"':'&quot;'}, untable;
function translate(str) {
return str.replace(/<|>|&|"/ig, function(m0) { return table[m0]||m0; });
}
function untranslate(str) {
if (!untable) {
untable = {};
$.each(table, function(key,val){ untable[val] = key; });
}
return str.replace(/&([lg]t|quot|amp);/g, function(m0) { return untable[m0]||m0; });
}
function translate_cite(str) {
var s = str.replace(/<(\/)?([abi]|em|strong|cite)(.*?)>|<|>|&|"/ig, function(m0,m1,m2,m3) {
m1 = m1 || '';
m2 = (m2 || '' ).toLowerCase();
m3 = m3 || '';
if (table[m0]) return table[m0];
if (m3 && m3.substr(0,1) != ' ') return '&lt;'+m1+m2+m3+'&gt;';
if (m2 == 'em' || m2 == 'strong' || m2 == 'a' || m2 =='cite') return '<'+m1+m2+m3+'>';
if (m2 == 'b') return '<'+m1+'strong>';
if (m2 == 'i') return '<'+m1+'em>';
});
return s;
}
function is_left_click(event) {
var ie = $.browser.msie;
return (typeof(event.btn)=='undefined' || (ie && event.btn == 1) || (!ie && event.btn == 0));
}
editor.translate = translate;
editor.translate_cite = translate_cite;
editor.is_left_click = is_left_click;
})(jQuery);