我正在使用 Angular 开发 chrome 扩展,我的扩展与 MaxAI chrome 扩展类似,当用户单击小部件时,它会打开侧边栏。
我尝试了一些教程来创建侧边栏,但侧边栏包含 iframe。不使用 iframe 是否可以创建类似这样的侧边栏
我检查了 MaxAI 侧边栏,我可以看到他们没有使用 iframe,而是我可以看到 DOM 中添加了一些特殊标签,如下所示
use-chat-gpt-ai
这是我使用 iframe 的实现
function injectAngularApplication() {
var angularApplicationIframe = document.createElement('iframe');
angularApplicationIframe.src = chrome.runtime.getURL('index.html');
angularApplicationIframe.id = 'angularApplication';
angularApplicationIframe.allow = 'clipboard-read; clipboard-write';
angularApplicationIframe.className = 'angular_application_iframe';
document.body.appendChild(angularApplicationIframe);
}
它将我的 Angular 应用程序注入到 iframe 中。我不想使用 iframe 的原因是当我们重新加载框架时它显示为空,即使我添加了哈希路由。
清单.json
{
"name": "angularchrome",
"description": "AngularChrome Extension.",
"version": "1.0.1",
"manifest_version": 3,
"permissions": [
"webNavigation"
],
"action": {
"default_icon": "/assets/icons/Icon.png",
"default_title": "Click me!"
},
"icons": {
"16": "/assets/icons/Icon.png",
"32": "/assets/icons/Icon.png",
"48": "/assets/icons/Icon.png",
"128": "/assets/icons/Icon.png"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"css": ["content.css"]
}
],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
},
"web_accessible_resources": [
{
"resources": [
"index.html",
"toolbar.html",
"toolbar.scss",
"toolbar.js",
"/assets/icons/ICON.png",
"main.ts"
],
"matches": ["<all_urls>"]
}
]
}
注意:我不想使用chrome提供的侧面板。
任何人都可以建议我一些关于如何使用 Angular 创建 chrome 扩展的更好见解吗?
我做了一个名为 Rafflesia 的开源项目。在其中,我使用 content script 生成 DOM 元素并将它们插入到页面上下文中。
这是我的 content-script.js 的片段:
const scriptsToLoad = ['webpage-script.js'];
scriptsToLoad.forEach(script => {
const s = document.createElement('script');
s.src = chrome.runtime.getURL(script);
(document.head || document.documentElement).appendChild(s);
s.onload = function () {
s.remove();
};
});
const toggler = document.createElement('button')
toggler.innerText = '▲'
toggler.style.position = 'fixed'
// ...
toggler.onclick = toggle
document.body.appendChild(toggler)
const heightAdjuster = document.createElement('div')
heightAdjuster.innerText = '⋯'
heightAdjuster.style.position = 'fixed'
// ...
heightAdjuster.onmousedown = adjustEnter
// ...
document.body.appendChild(heightAdjuster)
这部分都是普通的 JS,因为使用 Angular 创建构建环境并插入到页面中非常困难。您必须 (1) 手动构建 Angular 项目 (2) 将其移至扩展目录 (3) 重新打包扩展 (4) 在浏览器中重新加载扩展 (5) 重新加载所需的页面。因此,我的 DOM 插入部分确实包含了一个用于大部分内容的 iframe,这样我就可以更轻松地更改它。
webpage-script.js
,以便我可以在 iframe 和网页之间使用 事件侦听器,以便我可以传递数据并保持同步。
// Add event listeners into the Overleaf page that can respond to events from
// our external site.
window.addEventListener('message', (e) => {
const {data} = e
const parsedEvent = data
const parsedData = parsedEvent.data
switch (parsedEvent.type) {
case 'rafflesia_copy':
navigator.clipboard.writeText(parsedData)
break;
// ...
}
})
我的 Angular 服务可以创建类型化
Event
对象并与网页通信:
copy() {
if (!this.bibtex) return // Nothing
const msg: Event = {
type: 'rafflesia_copy',
data: this.bibtex
}
window.parent.postMessage(msg, '*')
}
这也可以反过来发生:
ngOnInit(): void {
window.addEventListener('message', e => {
const parsedEvent = e.data
if (parsedEvent?.type === 'rafflesia_getProjectFiles') {
const files = parsedEvent.data.map((x: any) => x.name)
.filter((x: string) => x.endsWith('.bib'))
this.mainbib = files
}
if (parsedEvent?.type === 'rafflesia_read') {
this.draft = parsedEvent.data
this.parse()
}
})
this.refreshProjectFiles()
}
它确实会导致需要构建更多文件,并需要跟踪更多文件,但它改进了构建和迭代过程。