diff --git a/modules/editor/skins/xeed/js/xeed.js b/modules/editor/skins/xeed/js/xeed.js index e0498c11f..918c810a0 100644 --- a/modules/editor/skins/xeed/js/xeed.js +++ b/modules/editor/skins/xeed/js/xeed.js @@ -47,7 +47,7 @@ Xeed = xe.createApp('Xeed', { minHeight : 400 }, options); this._options = opts; - + // min height if (opts.minHeight > opts.height) opts.minHeight = opts.height; @@ -61,6 +61,7 @@ Xeed = xe.createApp('Xeed', { } // Convert to wysiwyg editor + this.$textarea = $text; this.$root = $text.parent(); this.$richedit = this.$root.find('div.edit>div.xdcs:first'); @@ -129,7 +130,7 @@ Xeed = xe.createApp('Xeed', { var v = this._options[key]; if (is_def(v)) return v; }, - + /** * @brief Set option * @param key String option key @@ -208,7 +209,7 @@ Xeed = xe.createApp('Xeed', { */ getFrame : function(seq) { var self = this; - + return { editor_sequence : seq, getSelectedHTML : function(){}, @@ -345,7 +346,7 @@ Xeed = xe.createApp('Xeed', { // unregister ui event if (selector) { - ($btn = is_str(selector)?this.$toolbar.find(selector):$(selector)).unbind('click'); + ($btn = is_str(selector)?this.$toolbar.find(selector):$(selector)).unbind('click'); } }, @@ -377,7 +378,7 @@ Xeed = xe.createApp('Xeed', { this.$richedit.focus(); }, - + /** * @brief Fire event on keydown * @param event object @@ -476,7 +477,7 @@ Simple = xe.createPlugin('SimpleCommand', { // empty button list self.$btns = {}; }, - + API_ON_CHANGE_NODE : function(sender, params) { var self = this, node = params[0]; @@ -532,7 +533,7 @@ Block = xe.createPlugin('BlockCommand', { .each(function(){ var $this = $(this), num; if (!/(?:^|\s)h([1-7])(?:\s|$)/i.test($this.parent().attr('class'))) return true; - + num = RegExp.$1; if (np && !np.indexOf('Mac')) $this.attr('title', 'Ctrl+Command+'+num); else $this.attr('title', 'Ctrl+'+num); @@ -593,15 +594,15 @@ Block = xe.createPlugin('BlockCommand', { if (!sel) return ret; - nodes = sel.collapsed?[sel.getStartNode()]:sel.getNodes(); + nodes = sel.collapsed?[sel[_sc_]]:sel.getNodes(); $(nodes).each(function(i,node){ var name; - while(node[_pn_]) { + while(node && node[_pn_]) { name = node[_nn_].toLowerCase(); - if (/^t(able|body|foot|head|r)$/i.test(name)) { + if (/^t(able|body|foot|head|r)$/.test(name)) { node = node[_pn_]; continue; } @@ -613,12 +614,29 @@ Block = xe.createPlugin('BlockCommand', { } if (rx_root.test(node[_pn_].className || '')) { - if (name != 'br') { - if (node[_nt_] == 3) node = $(node).wrap('
')[0][_pn_]; - if (node[_nt_] == 1) node.className += ' '+_xs_; + var nodes = [], n=node, $p; - ret.push(node); + // get all non-block previous siblings + while(n[_ps_]){ + if (is_block(n[_ps_])) break; + nodes.push(n[_ps_]); + n = n[_ps_]; } + nodes.reverse(); + + // current node + nodes.push(n=node); + + // get all non-block next siblings + while(n[_ns_]) { + if (is_block(n[_ns_])) break; + nodes.push(n[_ns_]); + n = n[_ns_]; + } + + $p = $('
').addClass(_xs_); + node[_pn_].insertBefore($p[0], nodes[0]); + ret.push($p.append(nodes).get(0)); break; } @@ -632,9 +650,11 @@ Block = xe.createPlugin('BlockCommand', { var $this = $(this); return !$this.is('.'+_xr_) && !$this.parentsUntil('.'+_xr_).filter('.'+_xs_).length; }); - + $ret.removeClass(_xs_).each(function(){ if (!this.className) $(this).removeAttr('class') }); + sel.select(); + return $.makeArray($.unique(ret)); }, match : function(node, selector) { @@ -697,7 +717,9 @@ Block = xe.createPlugin('BlockCommand', { fireChangeNode : function(sel) { var self = this, _sel = sel || this.oApp.getSelection(); - setTimeout(function(){ self.cast('ON_CHANGE_NODE', [_sel[_sc_]]) }, 0); + setTimeout(function(){ + if (_sel && _sel[_sc_]) self.cast('ON_CHANGE_NODE', [_sel[_sc_]]) + }, 0); }, /** * @brief Quotes selection @@ -743,7 +765,7 @@ Block = xe.createPlugin('BlockCommand', { this.fireChangeNode(sel); }, /** - * @brief + * @brief */ API_EXEC_BOX : function(sender, params) { var self = this, sel = this.oApp.getSelection(), start, end, ancestor, match, $bx, _bx_ = 'div.bx'; @@ -784,7 +806,7 @@ Block = xe.createPlugin('BlockCommand', { this.fireChangeNode(sel); }, API_EXEC_INDENT : function(sender, params) { - var parents = this.getBlockParents(); + var sel = this.oApp.getSelection(), parents = this.getBlockParents(); $(parents).each(function(){ var $this = $(this), left = parseInt($this.css('margin-left'), 10); @@ -798,9 +820,10 @@ Block = xe.createPlugin('BlockCommand', { this.cast('SAVE_UNDO_POINT'); this.fireChangeNode(); + try { sel.select() } catch(e){}; }, API_EXEC_OUTDENT : function(sender, params) { - var parents = this.getBlockParents(); + var sel = this.oApp.getSelection(), parents = this.getBlockParents(); $(parents).each(function(){ var $this = $(this), left = parseInt($this.css('margin-left'), 10); @@ -817,6 +840,7 @@ Block = xe.createPlugin('BlockCommand', { this.cast('SAVE_UNDO_POINT'); this.fireChangeNode(); + try { sel.select() } catch(e){}; }, /** * @brief @@ -1037,21 +1061,21 @@ Font = xe.createPlugin('Font', { $tb.find('li.cr') .find('ul.ct,ul.cx') .each(function(){ - + var $this = $(this), $li = $this.find('>li').remove(), $clone_li, $span, $btn, colors,i,c,types; - + colors = $li.text().split(';'); for(i=0,c=colors.length; i < c; i++) { types = $.trim(colors[i]).split(':'); $clone_li = $li.clone(true); $btn = $clone_li.find('>button'); $span = $btn.find('>span'); - + (($span.length)?$span:$btn).text('#'+types[0]); $btn.css('backgroundColor', '#'+types[0]); if (types[1]) $btn.css('color', '#'+types[1]); - + $this.append($clone_li); } }) @@ -1291,9 +1315,9 @@ LineBreak = xe.createPlugin('LineBreak', { }, activate : function() { this.oApp.$richedit.keydown(this._fn); - + // If you pres Enter key,').parent(); + if ($node.length) { + $node = $node.eq(0); + } else { + nodes = $.merge(sibling(sc,1), [sc], sibling(sc)); + nodes[0][_pn_].insertBefore(($node=$('
')).get(0), nodes[0]); + $node.append(nodes); + } // wrap with '' in a table cell if ($node.is('td,th')) $node = $node.wrapInner('
').children(0); @@ -1410,7 +1440,7 @@ LineBreak = xe.createPlugin('LineBreak', { if (!$.browser.msie) { if (!$br[0][_ns_]) $br.after(d.createTextNode(invisibleCh)); if ($.browser.safari) { - // TODO : remove broken character which is displayed only in Safari. + // TODO : remove broken character which is displayed only in Safari. } } @@ -1617,7 +1647,7 @@ Filter = xe.createPlugin('ContentFilter', { _r2t : [], // rich2text filters _t2r : [], // text2rich filters _types : [], // valid types - + init : function() { this._in = []; this._out = []; @@ -1657,11 +1687,11 @@ Filter = xe.createPlugin('ContentFilter', { */ API_BEFORE_SET_CONTENT : function(sender, params) { var i,c; - + for(i=0,c=this._in.length; i < c; i++) params[0] = this._in[i](params[0]); for(i=0,c=this._t2r.length; i < c; i++) params[0] = this._t2r[i](params[0]); }, - + API_BEFORE_SET_CONTENT_HTML : function(sender, params) { for(i=0,c=this._r2t.length; i < c; i++) params[0] = this._r2t[i](params[0]); }, @@ -1826,7 +1856,7 @@ Resize = xe.createPlugin('Resize', { }, activate : function() { var $root = this.oApp.$root, chk; - + if (!this.prev_height) this.prev_height = this.oApp.getOption('height'); this.$container = this.oApp.$richedit.parent(); @@ -1948,7 +1978,7 @@ UndoRedo = xe.createPlugin('UndoRedo', { if ($undo && $undo[0]) { fn = (index > 0 && len)?'removeClass':'addClass'; $undo.parent()[fn]('disable'); - } + } if ($redo && $redo[0]) { fn = (index+1 < len)?'removeClass':'addClass'; @@ -2075,14 +2105,20 @@ SChar = xe.createPlugin('SChar', { this.$btn = $tb.find('button.sc').mousedown(function(){ self.cast('TOGGLE_SCHAR_LAYER'); return false; }); this.$layer = this.$btn.next('div.lr') .mousedown(function(event){ event.stopPropagation(); }) - .find('li.li').each(function(){ - var $this = $(this), $ul = $this.find('>ul'), $li = $ul.find('li').remove(), i, c, chars; - - chars = $li.text(); - - for(i=0, c=chars.length; i < c; i++) { - $ul.append( $li.clone(true).find('>button').text(chars.substr(i,1)).end() ); - } + .find('li.li').each(function(i){ + var $this = $(this), $ul = $this.find('>ul'), $li = $ul.find('li').remove(), chars, format; + + chars = $li.text(); + format = $('
';
}
-
+
if (!code) {
code = ''+name+'';
}
@@ -2582,7 +2618,7 @@ FileUpload = xe.createPlugin('FileUpload', {
sel.pasteHTML(code);
} else if(this.oApp.$richedit.is(':visible')){
this.oApp.$richedit.append(code);
-
+
sel = this.oApp.getEmptySelection();
sel.selectNode(this.oApp.$richedit[0].lastChild);
}
@@ -2597,10 +2633,10 @@ FileUpload = xe.createPlugin('FileUpload', {
function _callback(ret){
var i, c, selector=[];
-
+
if (ret && ret.error && ret.error == 0) {
if (!$.isArray(file_srl)) file_srl = [file_srl];
-
+
for(i=0,c=file_srl.length; i < c; i++) {
selector.push('li[file_srl='+file_srl[i]+']');
}
@@ -2608,12 +2644,12 @@ FileUpload = xe.createPlugin('FileUpload', {
self.$file_list.find(selector.join(',')).remove();
if ($.isFunction(callback)) callback();
-
+
self.updateCount();
self.updateFileSize();
}
}
-
+
$.exec_xml('file', 'procFileDelete', {file_srls:file_srl, editor_sequence:1}, _callback);
}
});
@@ -2722,7 +2758,7 @@ URL = xe.createPlugin('URL', {
},
API_TOGGLE_URL_LAYER : function() {
if (!this.$layer) return;
-
+
this.cast( (this.$layer.hasClass('open')?'HIDE':'SHOW')+'_URL_LAYER' );
},
API_HIDE_ALL_LAYER : function() {
@@ -2743,7 +2779,7 @@ Table = xe.createPlugin('Table', {
$th_btns : null,
$unit_btns : null,
selection : null,
-
+
selector : '.xeed_selected_cell',
cell_selector : '',
cmd : {
@@ -2947,6 +2983,8 @@ Table = xe.createPlugin('Table', {
this.selection = this.oApp.getSelection();
$layer.addClass('open').parent('li').addClass('active');
+
+ this.cast('HIDE_ALL_LAYER', [$layer[0]]);
},
API_HIDE_TABLE_LAYER : function(sender, params) {
var $layer = this.$layer;
@@ -3038,7 +3076,7 @@ AutoSave = xe.createPlugin('AutoSave', {
init : function(){ },
activate : function(){
var self = this, app = this.oApp, $form;
-
+
// start time
this._start_time = (new Date).getTime();
@@ -3059,9 +3097,9 @@ AutoSave = xe.createPlugin('AutoSave', {
},
_save_callback : function(params) {
var self = this;
-
+
this._save_time = (new Date).getTime();
-
+
this.$bar.slideDown(300);
this._update_message();
@@ -3069,26 +3107,26 @@ AutoSave = xe.createPlugin('AutoSave', {
},
_update_message : function() {
var msg = lang.autosave_format, now = (new Date).getTime(), write_interval, save_interval, write_msg, save_msg;
-
+
write_interval = Math.floor( (now - this._start_time)/1000/60 );
save_interval = Math.floor( (now - this._save_time)/1000/60 );
-
+
if (write_interval < 60) {
write_msg = ((write_interval>1)?lang.autosave_mins:lang.autosave_min).replace('%d', write_interval);
} else {
write_interval = Math.floor(write_interval/60);
write_msg = ((write_interval>1)?lang.autosave_hours:lang.autosave_hour).replace('%d', write_interval);
}
-
+
if (save_interval < 60) {
save_msg = ((save_interval>1)?lang.autosave_mins_ago:lang.autosave_min_ago).replace('%d', save_interval);
} else {
save_interval = Math.floor(write_interval/60);
save_msg = ((save_interval>1)?lang.autosave_hours_ago:lang.autosave_hour_ago).replace('%d', save_interval);
}
-
+
msg = msg.replace('%s', write_msg).replace('%s', save_msg);
-
+
this.$bar.find('>p').html(msg);
},
API_EXEC_AUTOSAVE : function() {
@@ -3096,7 +3134,7 @@ AutoSave = xe.createPlugin('AutoSave', {
},
API_ENABLE_AUTOSAVE : function(sender, params) {
var b = this._enable = !!params[0];
-
+
app.setOption('use_autosave', b);
}
});
@@ -3126,7 +3164,7 @@ Clear = xe.createPlugin('Clear', {
}
},
API_EXEC_CLEAR : function() {
- var sel = this.oApp.getSelection(), $div, node, par, content, after;
+ var sel = this.oApp.getSelection(), node, par, content, after;
if (!sel || sel.collapsed) return;
@@ -3134,7 +3172,7 @@ Clear = xe.createPlugin('Clear', {
content = sel.extractContents();
sel.select();
- // TODO : get nearest parent
+ // get nearest parent
node = sel.startContainer;
par = null;
while(par = node[_pn_]) {
@@ -3145,8 +3183,7 @@ Clear = xe.createPlugin('Clear', {
node = par;
}
- $div = $('').appendTo(document).append(content);
- content = $div.remove().text();
+ content = $('').appendTo(document).append(content).remove().text();
sel.setEndAfter(par.lastChild);
after = sel.extractContents();
@@ -3154,6 +3191,10 @@ Clear = xe.createPlugin('Clear', {
content = document.createTextNode(content);
par.appendChild(content);
par.appendChild(after);
+
+ // save undo point
+ this.cast('SAVE_UNDO_POINT');
+ //this.fireChangeNode(sel);
}
});
/**
@@ -3588,7 +3629,7 @@ $.extend(W3CDOMRange.prototype, {
if(this[_sc_][_nt_] == 3) {
oParentContainer = dp(this[_sc_]);
-
+
// Fix Opera bug : How can a text node is a child node of the other text node?
while(oParentContainer[_nt_] == 3) oParentContainer = oParentContainer[_pn_];
@@ -4939,7 +4980,7 @@ function is_def(v){ return typeof(v)!='undefined'; };
function is_str(v){ return typeof(v)=='string'; };
// filter
-function array_filter(arr, fn) {
+function array_filter(arr, fn) {
var ret=[], i, c;
for(i=0,c=arr.length; i < c; i++) {