Fork me on GitHub

Chrome Extension笔记之omnibox


一、什么是omnibox

omnibox是什么呢,这个干说没啥意思,一图抵千言:

上面这幅动图就是一个omnibox的例子,首先是用户在地址栏上输入了一个关键词并按下tab键,当检测到特定的关键词与我们事先指定的关键词相匹配时将调用对应的插件,这个关键词是在manifest.json文件中设置的,按下tab键,接下来用户再输入的东西将会传给插件,同时我们知道,一个输入框会有很多个事件,为了更好的与用户交互,通常会监听这些事件来辅助用户输入,比如自动完成之类的,在用户输入的时候会给出一些搜索建议,从代码结构上说,这些事件都是挂载在chrome.omniox上的一些回调函数,接下来的重点就是介绍这些事件。

首先在用户开始输入的时候,会触发onInputStarted事件,但这个具体是什么时候算是开始呢,即用户在按下tab键chrome将地址栏搜索交给我们插件,然后输入第一个字符之后的这一刻,这个叫inputStarted。

然后就是用户在地址栏上是一个字母一个字母或者一个汉字词语输入的,地址栏上输入的内容会不断发生变化,这个变化的事件叫做onInputChanged,在onInputChanged中可以为用户提供一些搜索建议。

当用户在地址栏上输入完毕,按下回车时会触发一个事件,这个事件叫onInputEntered。

当用户在地址栏上输了一会儿,但是突然决定不用这个,按ESC打算取消时,有一个事件onInputCancelled。


上面的几个事件可以用下面这张图简单总结:

image


在onInputChanged方法中可能有很复杂的逻辑,根据不同的情况为用户提供乱七八糟的搜索建议,但我们向无论什么情况下总有一个建议是首选的,处在搜索建议的第一条,chrome.omnibox.setDefaultSuggestion(object suggestion)设置。


接下来写一个简单的例子,初步学习一下omnibox是如何使用的。

首先定义manifest.json,设置插件的关键词:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
{
  "manifest_version": 2,
  "name": "omnibox usage example",
  "version": "0.1",
  "omnibox": {
    "keyword": "foobar"
  },
  "icons": {
    "16": "images/icon.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["js/background.js"]
  }
}

这里指定的关键词是“foobar”,然后要指定background.js,因为接下来要在background.js中设置监听事件。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 当用户按下tab chrome将输入交给插件,然后输入第一个字符之后触发此事件
chrome.omnibox.onInputStarted.addListener(() => {
    console.log("[" + new Date() + "] omnibox event: onInputStarted");
});
 
// 当用户的输入改变之后
// text 用户的当前输入
// suggest 调用suggest为用户提供搜索建议
chrome.omnibox.onInputChanged.addListener((text, suggest) => {
    console.log("[" + new Date() + "] omnibox event: onInputChanged, user input: " + text);
    // 为用户提供一些搜索建议
    suggest([{
            "content": text + " foo",
            "description": "是否要查看“" + text + " foo” 有关的内容?"
            }, {
                "content": text + " bar",
                "description":"是否要查看“" + text + " bar” 有关的内容?"
            }
            ]);
});
 
// 按下回车时事件,表示向插件提交了一个搜索
chrome.omnibox.onInputEntered.addListener((text, disposition) => {
    console.log("[" + new Date() + "] omnibox event: onInputEntered, user input: " + text + ", disposition: " + disposition);
});
 
// 取消输入时触发的事件,注意使用上下方向键在搜索建议列表中搜搜也会触发此事件
chrome.omnibox.onInputCancelled.addListener(() => {
    console.log("[" + new Date() + "] omnibox event: onInputCancelled");
});
 
// 当删除了搜索建议时触发的
chrome.omnibox.onDeleteSuggestion.addListener(text => {
    console.log("[" + new Date() + "] omnibox event: onDeleteSuggestion, text: " + text);
});
 
// 设置默认的搜索建议,会显示在搜索建议列表的第一行位置,content省略使用用户当前输入的text作为content
chrome.omnibox.setDefaultSuggestion({
            "description": "啥也不干,就是随便试试...."
            })

然后调出在地址栏输入"foobar",然后按tab,观察background页面的输出:

二、实战:基于omnibox的XXX

本来打算想一个牛逼哄哄的例子,后来想了半天觉得这个东西实属鸡肋,用户使用路径过长,用起来很麻烦,而且这个东西的原理也比较简单,就几个简单的回调方法,所以就不再费心设计例子了。


三、总结

3.1 一个插件能不能指定多个关键词呢?

我们知道omnibox能够增加我们插件的曝光率,那么我们能不能为自己插件设置多个keyword呢?

官方文档中好像并没有说明,那么我们来测试一下,将之前的manifest.json中的keyword修改为一个数组行不行呢:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
{
  "manifest_version": 2,
  "name": "omnibox usage example",
  "version": "0.1",
  "omnibox": {
    "keyword": ["foobar", "barfoo"]
  },
  "icons": {
    "16": "images/icon.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["js/background.js"]
  }
}

然后重新加载它:

image

啊哦,好像不太行哎。


3.2 当多个插件的关键词冲突了怎么办?

另外一种情况就是如果我插件要注册的关键字很火,结果被别人捷足先登了,当那么当用户的chrome上同时安装这两个插件会发生什么事呢?

创建两个插件,关键字都指定为"foobar",插件1:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
{
  "manifest_version": 2,
  "name": "foobar 1",
  "version": "0.1",
  "omnibox": {
    "keyword": "foobar"
  },
  "icons": {
    "16": "images/icon.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["js/background.js"]
  }
}

插件2:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
{
  "manifest_version": 2,
  "name": "foobar 2",
  "version": "0.1",
  "omnibox": {
    "keyword": "foobar"
  },
  "icons": {
    "16": "images/icon.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["js/background.js"]
  }
}

然后安装这两个插件,两个插件都能够安装成功:

image

好吧,跟我预想的冲突检测好像不太一样,那我现在在地址栏中键入“foobar”看究竟是哪一个起作用吧:

image

嗯,后安装的将先安装的给覆盖掉了。




相关资料

1. chrome.omnibox

2. Sample Extensions


.

posted @   CC11001100  阅读(3007)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示