npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

s94-editor

v1.1.1

Published

富文本编辑器的基础模块

Downloads

16

Readme

s94-editor

富文本编辑器的基础模块,提供富文本编辑器的基础功能,界面高度自由化

安装

$ npm install s94-editor

使用

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));

属性和方法

new Editor(textarea[, config]) 构造函数,构建编辑器

range 编辑器当前的选区返回

container 编辑器的容器

textarea 编辑器的textarea,里面承载了编辑器对应的html代码

config 配置参数

menu 菜单实例对象

belongNode(dom[, test]) 向上遍历获取符合条件的节点

setRange([range]) 设定的选择范围

updateRange([range]) 更新选择范围

updateValue() 更新textarea的值

updateHtml() 更新编辑器的html内容

execCommand(name[, data]) 执行编辑命令

alignType() 文本布局类型

isbold() 是否加粗

isstrike() 是否删除线

isitalic() 是否斜体

isunderline() 是否下划线

rangePath() 路径节点列表

lastRow() 设定最后一行空白节点

encode_tag(html) 编码html中的特殊标签(form,script)

decode_tag(html) 解码encode_tag方法编译过的html

html() 当前编辑器的html代码

配置参数

菜单组件属性和方法

new Editor.Menu(editor[, config]) 内置的菜单构造函数

Menu.menuList 所有注册的菜单

Editor.Menu.add(name, title, innerHTML, onclick) 注册菜单

container 菜单的容器

editor 菜单对应的编辑器

list 生成的菜单节点对象的键值对象

add(name, title, innerHTML, onclick) 添加菜单

showSelect(list[, options]) 显示自带的列表类型子菜单

showForm(list[, options]) 显示自带的表单类型子菜单

new Editor(textarea[, config])

  • textarea Node 构建编辑器容器的样本,必须为textarea元素
  • config Object 配置数据,查看详细介绍
  • 返回 Editor 编辑器对象

以textarea为样本,复制textarea的所有attr来窗初编辑器的容器,同时也是用来承载编辑器对应的html代码的容器

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));

range

  • 属性 Range 选择范围,查看详细介绍

获取编辑器当前的选区返回

container

  • 属性 Node 编辑器的容器

获取编辑器当前所在的容器

textarea

  • 属性 Node textarea

获取编辑器构建的样本textarea元素,编辑器对应的html代码会不间断的赋值到该元素的value属性上。

但是不能完全保证该元素的value等同于editor.html()(例如当使用js改变了编辑器容器内的html后,没有调用updateValue方法的时候)。所有获取编辑器内容的html依然建议调用editor.html()方法

config

  • 属性 Object 配置参数

获取编辑器当前配置参数,该对象的值是构造函数传入的config和默认的配置参数合并后的结果

menu

  • 属性 Editor.Menu|config.Menu 菜单实例对象

编辑器的菜单实例对象

belongNode(dom[, test])

  • dom Node 开始节点
  • test Function 判断方法,方法的this为当前判断的节点对象,方法返回true表示当前节点符合条件,默认this.nodeType===1为判断条件
  • 返回 Node|False 符合条件的节点,如果直到容器节点也没用符合的,返回false

向上遍历获取符合条件的节点

console.log(editor.belongNode(editor.range.startContainer)); //打印当前编辑的节点

setRange([range])

  • range Range 选择范围对象,查看详细介绍。默认为当前Editor的range
  • 返回 Editor 编辑器对象

设定浏览器的选择范围,有获取锚地的效果。

editor.setRange();

updateRange([range])

  • range Range 选择范围对象,查看详细介绍。默认为浏览器的选择范围
  • 返回 Editor 编辑器对象

更新当前Editor的range,该方法组件会在必要的时候自动调用

该方法调用后,会在editor.container上广播update:range事件,事件对象的range属性可以获取当前Editor的range

editor.updateRange();

updateValue()

  • 返回 Editor 编辑器对象

更新textarea的value属性,该方法组件会在必要的时候自动调用,一般用于用户自定义菜单功能时,如果该功能对内容有变化的时候调用该方法,同步textarea中的值

该方法调用后,会在editor.container上广播update:value事件,事件对象的value属性可以获取编辑器对应的html

editor.updateValue();

updateHtml()

  • 返回 Editor 编辑器对象

更新编辑器的html内容,该方法根据textarea的value重新渲染编辑器容器的html内容。

editor.updateHtml();

execCommand(name[, data])

  • name String 执行命令名称。等同于document.execCommand的第1个参数
  • quality mixed 执行附带参数,默认为null。等同于document.execCommand的第3个参数,部分优化的不同
  • 返回 Editor 编辑器对象

在当前编辑位置,执行编辑命令。查看详细介绍,对document.execCommand做了部分优化见代码示例

//createLink
editor.execCommand("createLink", "http://s94.top"); //插入 <a href="http://s94.top">http://s94.top</a>
editor.execCommand("createLink", {
	text: "牧人与鱼",
	href: "http://s94.top"
}); //插入 <a href="http://s94.top">牧人与鱼</a>

//foreColor、hiliteColor、bold、strikeThrough、italic、underline
editor.execCommand("bold", true); //data为true表示当选区为一个点时,在当前位置插入不占位的空白字符,方便判断当前节点是否为加粗

alignType()

  • 返回 String 文本布局类型,left|center|full|right

返回当前选区的文本布局类型,是对节点的text-align样式结果的统一化

console.log(editor.alignType()); //left

isbold()

  • 返回 Boolean 是否加粗

返回当前选区的节点文本样式是否为 加粗

console.log(editor.isbold()); //false

isstrike()

  • 返回 Boolean 是否加粗

返回当前选区的节点文本样式是否为 删除线

console.log(editor.isstrike()); //false

isitalic()

  • 返回 Boolean 是否加粗

返回当前选区的节点文本样式是否为 斜体

console.log(editor.isitalic()); //false

isunderline()

  • 返回 Boolean 是否加粗

返回当前选区的节点文本样式是否为 下划线

console.log(editor.isunderline()); //false

rangePath()

  • 返回 Array 路径节点列表,

返回当前选区的节点路径节点列表,

var nodeNamePath=[];
editor.rangePath().forEach(function(row){
	nodeTypePath.push(row.nodeName);
})
console.log(nodeNamePath.join(">")); //div>p>span

lastRow()

  • 返回 Node 最后一行的节点对象

检测最后一行是否为空的P标签,如果不是,添加一个空的没用样式的P标签。并返回。该方法主要用于在执行编辑内容的样式修改后,很多情况下换行后会把之前的样式带上,所以需要调用该方法获取一行没有被污染的P标签

editor.lastRow();

encode_tag(html)

  • 返回 String 编码后的html代码

编码html中的特殊标签(form,script)。

编码script的目的:防止编辑的html代码里面的js代码污染

编码form的目的:当编辑器放在form表单里面的时候,如果编辑器里面存在form标签的内容,浏览器会移除form标签,造成内容丢失

console.log(editor.encode_tag('<form action=""></form><script></script>')); //<form-editor-change-tagname action=""></form-editor-change-tagname><script-editor-change-tagname></script-editor-change-tagname>

decode_tag(html)

  • 返回 String 解码后的html代码

解码encode_tag方法编码后的html字符串

var coed = editor.encode_tag('<form action=""></form><script></script>');
var html = editor.decode_tag(code);
console.log(html); //<form action=""></form><script></script>

html()

  • 返回 String 编辑器的html代码

返回当前编辑器的html代码。在this.container.innerHTML的基础上执行了decode_tag和剔除了lastRow方法加入的空白P标签

console.log(editor.html()); //.......

配置参数

  • colors Array 使用内置菜单时,设定菜单的字体颜色和背景颜色集合
  • fontsizes Array 使用内置菜单时,设定菜单的字体大小集合,长度最大为7
  • image_callback Function 使用内置菜单-图片时,此参数表示点击此菜单后的处理,确认好图片地址后,可以通过直接返回,或者执行函数接受一个参数next然后传入图片地址,具体参考s94-js的new s94.Ready(f)
  • menus Array 使用内置菜单时,设定显示的菜单列表,同时具备排序效果。
  • onpaste Function 粘贴内容处理,接收s94.fn对象(类似jQuery对象),要求返回节点集
  • Menu Function 自定义菜单构造函数,如果传入将替换组件自带的菜单,传入当前Editor编辑器对象

除了这些字段,开发者也可以根据自己扩展的功能,自定义配置参数字段,然后可以在editor.configeditor.menu.config里面去获取。

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'), {
	colors: ['#333','rgb(194, 250, 94)'], //自定义组件菜单的字体颜色和背景颜色列表
	fontsizes: ['12px','0.2rem'], //自定义字体大小列表,最多7个
	menus: ['bold','color'],
	onpaste: function(list){
		list.forEach(function(row){
			list.find('img').css("width", "100%"); //设定粘贴的图片样式
        	return list;
		})
	},
    Menu: function(editor){
		var dom = document.createElement('button');
        dom.innerHTML = '菜单示例';
        $(editor.container).after(dom);
        dom.addEventListener('click', function(){
            var html = `<h1>这是插入的标题</h1>`;
            editor.execCommand('insertHTML', html);
            
            editor.range = document.createRange();
            var lastNode = editor.lastRow();
            editor.range.setStart(lastNode, 0);
            editor.range.setEnd(lastNode, 0);
            editor.setRange();
        })
	}
});

new Editor.Menu(editor[, config])

  • editor Editor 编辑器对象
  • config Object 配置数据,类似Editor构造函数的config参数
  • 返回 Editor.Menu 菜单实例对象

内置的菜单,一般不用不需要调用,当没有在Editor构造函数的config参数设定Menu的情况下,会自动调用,返回结果赋值到editor.menu

var menu = new Editor.Menu(editor);

Editor.Menu.menuList

  • 属性 Object 全局的菜单列表

里面包含所有注册的菜单,主要用于查看已有的菜单或者修改某个菜单。如果需要自定义菜单建议调用Editor.Menu.add(name, title, innerHTML, onclick)方法

var Editor = require('s94-editor');
Editor.Menu.menuList['bold']['onclick'] = function(menu){
    alert("这是修改后的加粗菜单功能")
}
//全局菜单的操作需要在Editor实例化之前调用
var editor = new Editor(document.querySelector('.editor-outer'));

Editor.Menu.add(name, title, innerHTML, onclick)

  • name String 组件名称,作为Menu.menuListmenu.list里面存储的key
  • title String 鼠标放上去显示的提示信息
  • innerHTML String 组件菜单html
  • onclick Function 组件菜单onclick事件回调函数,函数接收的第一个参数不是event,而是menu;this不变,为当前菜单节点对象
  • 返回 Editor.Menu.menuList 所有注册的菜单键值对象

该方法用于注册菜单,一般用于全局自定义菜单,示例如下:

var Editor = require('s94-editor');
Editor.Menu.add("test", "测试菜单", '<p style="font-size: 0.6em;">测试</p>', function(menu){
    var editor = menu.editor;
    var html = `<h1>这是插入的标题</h1>`;
    editor.execCommand('insertHTML', html);
    editor.range = document.createRange();
    var lastNode = editor.lastRow();
    editor.range.setStart(lastNode, 0);
    editor.range.setEnd(lastNode, 0);
    editor.setRange();
})
//全局菜单的操作需要在Editor实例化之前调用
var editor = new Editor(document.querySelector('.editor-outer'));

container

  • 属性 Node 菜单的容器

获取菜单的容器,一把用于自定义菜单位置。菜单的默认位置在编辑器容器的前方,可以使用appendChild方法自定义菜单位置

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
document.querySelector('#editor-menu').appendChild(editor.menu.container); //把菜单放到#editor-menu里面去

editor

  • 属性 Editor 当前菜单对应的编辑器的实例

获取当前的编辑器示例,一般用于自定义菜单里面方便调用editor的方法,查看详细介绍

list

  • 属性 Object 生成的菜单节点对象键值对象,key为菜单的name,{name: Node}

菜单在实例化后,会根据config.menus和全局注册的菜单来生成菜单,并把生成的菜单节点对象存储在menu.list方便调用

add(name, title, innerHTML, onclick)

  • name String 组件名称,作为menu.list里面存储的key
  • title String 鼠标放上去显示的提示信息
  • innerHTML String 组件菜单html
  • onclick Function 组件菜单onclick事件回调函数,函数接收的第一个参数不是event,而是menu;this不变,为当前菜单节点对象
  • 返回 Object 所有生成的菜单键值对象menu.list

添加菜单,Menu在实例化的时候,会遍历全局菜单列表执行此方法挨个添加菜单。同时,在实例化后,依然可以调用此方法,用于局部添加菜单,不过这样添加的菜单,不能排序,只能添加到末尾。如果需要排序,同时也不希望每个编辑器都有该菜单,请全局注册后,用config.menus实现

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
editor.menu.add('test2','测试2','测试',function(menu){
    alert("测试2")
})

showSelect(list[, options])

  • list Array 菜单配置列表,[{innerHTML:String, onclick:Function}],参数说明,类似menu.add方法
  • options Object 菜单配置,{type:String, className:String, close:Function}
    • type String 列表布局类型,droplist下拉菜单样式,pointlist点阵样式。默认为droplist
    • className String 自定义容器className,方便自定义样式
    • close Function 菜单关闭时的回调方法,方法this为子菜单节点对象
  • 返回 underfind

显示自带的列表类型子菜单,组件自带的heading、size、align、color、bgcolor都使用了该子菜单,开发者可以在自定义菜单时使用

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
editor.menu.add('test2','测试2','测试',function(menu){
    menu.showSelect([
		{innerHTML: 'H1', onclick: function(menu){menu.editor.execCommand('formatBlock','h1')}},
        {innerHTML: 'H2', onclick: function(menu){menu.editor.execCommand('formatBlock','h2')}},
	])
})

showForm(list[, options])

  • list Array 菜单配置列表,[{type:String, name:String, label:String, value:String, list:Array, }],参数说明:

    • type String 表单组件类型,可选值:textarea | select | text ,默认为text
    • name String 表单组件的name,必须,在提交后,作为获取数据的键值
    • label String 表单组件的提示信息
    • value String 表单组件默认初始值
    • list Array 此字段为select组件特有,表示下拉的option列表,格式{html:String, value:String}
  • options Object 菜单配置,{title:String, className:String, ok:Function, close:Function}

    • title String 表单的标题
    • className String 自定义容器className,方便自定义样式
    • ok Function 菜单点击确定后提交的方法,接收一个键值对对象,里面包含表单的数据,方法this为子菜单节点对象
    • close Function 菜单关闭时的回调方法,方法this为子菜单节点对象
  • 返回 underfind

显示自带的表单类型子菜单,组件自带的style、code都使用了该子菜单,开发者可以在自定义菜单时使用

var Editor = require('s94-editor');
var editor = new Editor(document.querySelector('.editor-outer'));
editor.menu.add('test2','测试2','测试',function(menu){
    menu.showForm([
		{name: "type", label: "操作", type: "select", value: 0, list: [
            {html:"下载图片", value: 1},
            {html:"直接插入图片", value: 0}
        ]},
        {name: "src", label: "图片地址"},
    ], {
        title: '添加图片',
        ok: function(data){
            if(!data.src) return;
            if(data.type==0){
                menu.editor.execCommand('insertImage', data.src);
            }else{
                //记录当前编辑位置
                var range = menu.editor.range;
                // TODO 此处请求服务器,下载图片,然后返回自己服务器保存地址,再插入图片。由于请求服务器一般异步操作,此处用setTimeout代替效果
                setTimeout(function(){
                    menu.editor.setRange(range);
                    menu.editor.execCommand('insertImage', data.src);
                },5000)
            }
        }
    });
})