- Created:
- Updated:
- Fairycat
Simditor编辑器,首行缩进功能
最近尝试使用Simditor编辑器,想使用段落首行缩进,没找到这个动能。所以用该编辑器自带的向右缩进功能作为参照,做出了首行缩进的插件。
想要让首行缩进的样式不被过滤掉,在编辑器的设置里边需要给P标签添加text-indent,设置项为allowedStyles。具体设置方法可以查看Simditor官方网站。
设置允许样式的时候,要保留编辑器默认的设置。p标签的默认样式有左边距和对齐方式:
this._allowedStyles = $.extend({
...,
p: ['margin-left', 'text-align'],
...,
}, this.opts.allowedStyles);
那么,在建立编辑器时的设置,p标签允许的样式再添加一项,text-indent。三个都写全才行。还有,在工具栏添加相应的按钮。按钮的命名在插件js文件中定义。
new Simditor({
...,
allowedStyles: {
...,
p: ['margin-left', 'text-align', 'text-indent']
...,
},
toolbar: [
...,
'indentfl',
'indentfr',
...,
],
...,
});
允许的样式和工具栏按钮已经设置好了,可以添加插件了。插件js文件,在引入编辑器主文件之后任意位置引入就行了。
以下是插件js文件,我给它取文件名为simditor-indentfirstline.js:
(function() {
var SimditorIndentfl,SimditorIndentfr,
hasProp = {}.hasOwnProperty,
extend = function(child, parent) {
for (var key in parent) {
if (hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
};
SimditorIndentfr = (function(superClass) {
extend(SimditorIndentfr, superClass);
function SimditorIndentfr() {
return SimditorIndentfr.__super__.constructor.apply(this, arguments);
}
SimditorIndentfr.prototype.name = 'indentfr';
SimditorIndentfr.prototype.title = 'indentfr';
SimditorIndentfr.prototype.icon = 'indentfr';
SimditorIndentfr.prototype.opts = {
indentWidth: 2,
indentUnit: 'em'
};
SimditorIndentfr.prototype._init = function() {
SimditorIndentfr.__super__._init.apply(this, arguments);
return this.setIcon("angle-double-right");
};
SimditorIndentfr.prototype.setIcon = function(icon) {
return this.el.find("span").removeClass().addClass("fa fa-" + icon);
};
SimditorIndentfr.prototype.command = function() {
var $blockNodes, $endNodes, $startNodes, nodes, result;
$startNodes = this.editor.selection.startNodes();
$endNodes = this.editor.selection.endNodes();
$blockNodes = this.editor.selection.blockNodes();
nodes = [];
$blockNodes = $blockNodes.each(function(i, node) {
var include, j, k, len, n;
include = true;
for (j = k = 0, len = nodes.length; k < len; j = ++k) {
n = nodes[j];
if ($.contains(node, n)) {
include = false;
break;
} else if ($.contains(n, node)) {
nodes.splice(j, 1, node);
include = false;
break;
}
}
if (include) {
return nodes.push(node);
}
});
$blockNodes = $(nodes);
result = false;
$blockNodes.each((function(_this) {
return function(i, blockEl) {
var r;
r = _this.indentBlock(blockEl);
if (r) {
return result = r;
}
};
})(this));
return result;
}
SimditorIndentfr.prototype.indentBlock = function(blockEl) {
var $blockEl, $childList, $nextTd, $nextTr, $parentLi, $pre, $td, $tr, marginLeft, tagName;
$blockEl = $(blockEl);
if (!$blockEl.length) {
return;
}
if ($blockEl.is('p, h1, h2, h3, h4')) {
$blockEl.css('text-indent', this.opts.indentWidth+this.opts.indentUnit);
} else {
return false;
}
return true;
}
SimditorIndentfr.prototype.indentText = function(range) {
var text, textNode;
text = range.toString().replace(/^(?=.+)/mg, '\u00A0\u00A0');
textNode = document.createTextNode(text || '\u00A0\u00A0');
range.deleteContents();
range.insertNode(textNode);
if (text) {
range.selectNode(textNode);
return this.editor.selection.range(range);
} else {
return this.editor.selection.setRangeAfter(textNode);
}
};
return SimditorIndentfr;
})(Simditor.Button);
SimditorIndentfl = (function(superClass) {
extend(SimditorIndentfl, superClass);
function SimditorIndentfl() {
return SimditorIndentfl.__super__.constructor.apply(this, arguments);
}
SimditorIndentfl.prototype.name = 'indentfl';
SimditorIndentfl.prototype.title = 'indentfl';
SimditorIndentfl.prototype.icon = 'indentfl';
SimditorIndentfl.prototype.opts = {
indentWidth: 2,
indentUnit: 'em'
};
SimditorIndentfl.prototype._init = function() {
SimditorIndentfl.__super__._init.apply(this, arguments);
return this.setIcon("angle-double-left");
};
SimditorIndentfl.prototype.setIcon = function(icon) {
return this.el.find("span").removeClass().addClass("fa fa-" + icon);
};
SimditorIndentfl.prototype.command = function() {
var $blockNodes, $endNodes, $startNodes, nodes, result;
$startNodes = this.editor.selection.startNodes();
$endNodes = this.editor.selection.endNodes();
$blockNodes = this.editor.selection.blockNodes();
nodes = [];
$blockNodes = $blockNodes.each(function(i, node) {
var include, j, k, len, n;
include = true;
for (j = k = 0, len = nodes.length; k < len; j = ++k) {
n = nodes[j];
if ($.contains(node, n)) {
include = false;
break;
} else if ($.contains(n, node)) {
nodes.splice(j, 1, node);
include = false;
break;
}
}
if (include) {
return nodes.push(node);
}
});
$blockNodes = $(nodes);
result = false;
$blockNodes.each((function(_this) {
return function(i, blockEl) {
var r;
r = _this.outdentBlock(blockEl);
if (r) {
return result = r;
}
};
})(this));
return result;
}
SimditorIndentfl.prototype.outdentBlock = function(blockEl) {
var $blockEl, $parent, $parentLi, $pre, $prevTd, $prevTr, $td, $tr, marginLeft, range;
$blockEl = $(blockEl);
if (!($blockEl && $blockEl.length > 0)) {
return;
}
if ($blockEl.is('p, h1, h2, h3, h4')) {
/*marginLeft = parseInt($blockEl.css('margin-left')) || 0;
marginLeft = Math.max(Math.round(marginLeft
/ this.opts.indentWidth) - 1, 0)
* this.opts.indentWidth;*/
$blockEl.css('text-indent', '');
} else {
return false;
}
return true;
};
SimditorIndentfl.prototype.outdentText = function(range) {};
return SimditorIndentfl;
})(Simditor.Button);
Simditor.Toolbar.addButton(SimditorIndentfr);
Simditor.Toolbar.addButton(SimditorIndentfl);
}).call(this);
outdentText和indentText两个函数的作用我没有看全,似乎没有用到,但我也没有删除。插件允许首行缩进的标签有p标签和h系列标签,但在建立编辑器的时候,只添加了p标签的允许样式text-indent,所以也只有p标签能用这个功能了。
工具栏按钮我没有找到合适的图标,暂时用双尖括号表示了。