# 扩展
civet的扩展分为浏览器扩展和本地扩展两种。
# 浏览器扩展
以下示例是一个浏览器扩展。你需要先下载一个模板,以便能够方便的安装和打包扩展。
如果你对浏览器扩展开发已经很熟练了,那么可以跳过下述内容。
执行`git clone https://github.com/webbery/browser-extension-for-civet.git`命令,下载浏览器扩展模板。
执行`npm install`命令,安装依赖项。
接下来安装civet-extend
:
npm install civet-extend@latest
环境就搭好了,非常简单。
接下来开始给扩展添加内容了。
打开模板下src/scripts
目录,打开background.js
,在顶部引入如下内容
import * as civet from 'civet-extend'
然后我们添加一个右键图片操作,将图片保存到Civet
中。
let menu = {
id: 'add-image',
title: '添加到civet',
contexts: ['image']
}
ext.contextMenus.create(menu)
ext.contextMenus.onClicked.addListener(
function(info, tab) {
switch(info.menuItemId) {
case 'add-image':
civet.resource.save(info.srcUrl)
break;
default:
break;
}
}
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
其中第12行,表示将右键的图片保存到Civet
中。
编写完成后,执行如下命令:
npm run build
在dist
目录下,将会出现chrome、firefox、opera三种浏览器的扩展。
下面可以通过浏览器扩展加载它们,进行调试了。
当然,一个完整的扩展不会如上面那般简单。例如,如果Civet
没有启动,那么扩展应该将这个URL保存起来,直到Civet
启动事件触发之后,同步更新。诸如此类的业务逻辑并不属于该部分内容。
一个浏览器扩展的生命周期如下:
Civet与浏览器扩展之间没有启动的先后顺序之说。
Civet是相当于一个Server,而浏览器扩展则相当于一个Client。
当浏览器扩展连接上Civet时,会将自己的唯一扩展名发送给Civet,然后接收到来自Civet的配置信息。配置内容如下所示,存放在ExtensionContext
中:
{
current: 当前资源库名称
candidates: [
{
name: 资源库名,
ext: [
{
name: 扩展名,
type: UI/backgroud/browser/category
}
]
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
当收到这个信息时,环境的初始化已经完成。
接口:
civet.resource.load(info.srcUrl)
# 本地扩展
扩展安装的路径默认为安装路径下的extesions。
本地扩展需要在package.json
中引入一个配置字段civet
。如下所示:
{
"name": "@civet-extend/zetora",
"civet": {
"activeEvents": [
"onContntType:jpeg,jpg,tif,png",
]
}
}
2
3
4
5
6
7
8
每个扩展包含了一个名字。
本地扩展的生命周期如下:
Civet启动时,会去extensions文件夹中,查看安装的扩展。
首先,在扩展文件夹中寻找package.json文件,检查main
字段,以这个字段的值作为对应的入口文件;如果这个字段不存在,会默认index.js作为入口文件加载。
接着调用入口文件中的activate()
函数,注册激活事件activeEvents
,这些事件将在满足条件的时候自动触发。这个函数不是必须的
# 载入事件
onContntType
标明当一个指定后缀的文件第一次被导入时将会触发read
事件。同时,这个参数还表明该插件支持的文件类型。如果为空,则不会做任何判断
# 自定义界面
有时候,我们需要自定义一些界面,来展示不同内容的信息,例如论文的作者和摘要。这种情况下,就需要扩展界面功能
在package.json
中,onView
的值支持以下几种:
Property = 1,
Navigation = 2,
Overview = 3,
ContentView = 4,
Search = 5
2
3
4
5
这几个值定义在了civet.d.ts
的ViewType
中,分别代表了5种类型的界面组件。例如,activeEvents
中添加自定义属性面板时:
{
"name": "@civet-extend/example",
"civet": {
"activeEvents": [
"onView:Property",
]
}
}
2
3
4
5
6
7
8
如果既需要自定义视图Overview
,又需要自定义属性面板Property
,可以将它们合并在一起,以逗号,
分隔:
{
"name": "@civet-extend/example",
"civet": {
"activeEvents": [
"onView:Property,Overview",
]
}
}
2
3
4
5
6
7
8
# Property模块
Property模块是展示内容属性的地方,配置如下所示,需要在activeEvents
中添加onView:Property
{
"name": "@civet-extend/example",
"civet": {
"activeEvents": [
"onView:Property",
]
}
}
2
3
4
5
6
7
8
如果想通过扩展来调整属性的展示,需要在window
的onDidSelectContentItem
函数中注册响应函数。这个响应函数在一个资源被选中的时候触发。
展示图片属性的代码如下所示:
import { window, ContentItemSelectedEvent, ResourceProperty } from 'civet'
function shouldDisplay(prop: ResourceProperty): boolean {
switch(prop.name) {
case 'filename':
case 'color':
case 'thumbnail':
return false
default:
return true
}
}
window.onDidSelectContentItem(async (e: ContentItemSelectedEvent) => {
let propertyView = window.propertyView
if (e.items.length === 1) {
const resource = e.items[0]
propertyView.name = resource.name
propertyView.preview = resource.thumbnail
window.propertyView.colorPanel.color = resource.color
propertyView.tags = resource.tags
propertyView.category = resource.category
propertyView.property.splice(0, propertyView.property.length)
for (let prop of resource.meta) {
if (shouldDisplay(prop)) {
propertyView.property.push(prop);
}
}
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Overview模块
Overview模块是展示用的主界面。目前在civet中自带了两种风格的主界面,文件视图(在扩展grid_view
中)和地图视图(在扩展map_view
中)。
在Overview模块中,分为前端和后端。
这里的前端指的是在renderer
中显示的html页面,后端是指在worker
中运行的typescript程序。
在前端中,我们可能会需要跟后端交互。目前,我们提供了几种交互的方式:
- 命令机制
命令机制需要开发者在package.json
中,添加相关的命令。例如菜单命令:
"contributes": {
"menus": {
"overview/gridview": [
{
"command": "exportResources",
"group": "1",
"name": "导出文件"
},
...
}
2
3
4
5
6
7
8
9
10
这里定义了gridview
视图的一个菜单,它的命令为exportResources
,在菜单上的显示名称为导出文件
。
到目前为止,视图的右键菜单只能够显示菜单信息,点击时所执行的命令还没有定义。接下来需要做2件事情:a. 注入命令所需的参数;b. 定义命令在后端的响应函数。
在前端,我们提供了一个接口,供开发者注入命令的参数。其定义如下:
function injectCommandParams(command, args);
整个要添加的内容如下图绿色部分所示:
2. 消息机制
开发中
如下所示,通过window
的createOverview
创建一个新的主界面,gridview
为这个界面的id,waterfall layout
作为布局切换的展示名称。
let gridview = window.createOverview('gridview', 'waterfall layout')
当资源载入的时候,onResourcesLoading
注册的函数会被触发:
gridview.onResourcesLoading((e: OverviewItemLoadEvent) => {
console.info('grid view onResourcesLoading', e.resources.length)
frame = frame.replace('{{jquery}}', jquery)
frame = frame.replace('{{waterfall}}', waterfall)
frame = frame.replace('{{resources}}', JSON.stringify(e.resources))
console.info('GRID:', frame)
gridview.html = frame
}, gridview);
2
3
4
5
6
7
8
在这个注册函数中,可以设置Overview
的html
内容,在界面中展示
# 添加新的搜索
如果想要添加一种新的搜索方式,就需要自定义一种搜索类型,以便搜索引擎对整个数据进行重新索引。需要详细考虑该方案的设计,待开发。
# 发布本地扩展
本地扩展以npm包的形式,托管在npm仓库中。因为civet
这个域已经被使用了,所以扩展的Group使用civet-extend
,其后才是扩展的名称,如:@civet-extend/example