从 chrome 扩展注册自定义元素 [英] Registering a custom element from a chrome extension
问题描述
我曾尝试通过原生 javascript 和聚合物从 chrome 扩展程序中注册自定义元素,但没有成功.该问题记录在此处.
I have tried registering custom elements through native javascript and polymer from within a chrome extension with no luck. The issue is documented here.
Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'polymer-element'. Elements cannot be registered from extensions.
我正在寻找在扩展中使用 Web 组件的建议 - 有没有人这样做过?我的直觉是暂时在 shadow DOM 上使用标准 html 标签(div 等...)注册这些元素,直到它被支持为止.有什么建议吗?
I am looking for suggestions for using web components in an extension - has anyone done so? My instinct is to register these elements using standard html tags (div, etc...) on the shadow DOM for the time being until it is supported. Any suggestions?
推荐答案
确实有可能.但是,有点hacky.
It is indeed possible. But, a little hacky.
原答案
步骤如下:
- 原生网络组件(无聚合物)
注意:这需要使用 webcomponentsjs polyfill
Chrome 将阻止本地registerElement
在 chrome 扩展程序中执行.为了克服它,您需要阻止使用本机registerElement
以支持模拟的(polyfill).
- Native web components (no Polymer)
NOTE: This requires the usage of the webcomponentsjs polyfill
Chrome will prevent nativeregisterElement
from being executed within a chrome extension. To overcome it you need to prevent the usage of the nativeregisterElement
in favor of a simulated one (the polyfill).
在 webcomponents-lite.js
中注释掉以下代码(如果您愿意,可以使其更优雅:
In webcomponents-lite.js
Comment out the following code (and make this more elegant if you'd like:
scope.hasNative = false; //Boolean(document.registerElement);
瞧!本机registerElement
现在已被 polyfill 取代 - chrome 不会阻止在扩展中使用.
And voila! the nativeregisterElement
has now been replaced by the polyfill - which chrome does not prevent from using within an extension.
聚合物网络组件
您将需要执行上述步骤中列出的代码,此外,您还需要通过以下代码加载聚合物
Polymer Web components
You will need to perform the code listed in the step above and in addition, you will need to load polymer via the following code
var link = document.createElement('link');
link.setAttribute('rel', 'import');
link.setAttribute('href', "link_to_your_polymer.html");
link.onload = function() {
// Execute polymer dependent code here
}
更新 #1 - 改进的解决方案
经过进一步调查,我了解到 Polymer 在动态加载时无法在扩展中工作.因此,上述修改是必要的.一个更简单的替代方法是在您的内容脚本中将聚合物加载到头部,如下所示:
After further investigation, I've learned that Polymer would not work in an extension when loaded dynamically. As a result, the above modifications are necessary. A simpler alternative to this is to load polymer into the head in your content script like this:
function loadRes(res) {
return new Promise(
function(resolve, reject) {
var link = document.createElement('link');
link.setAttribute('rel', 'import');
link.setAttribute('href', res);
link.onload = function() {
resolve(res);
};
document.head.appendChild(link);
});
}
loadRes( chrome.extension.getURL("path_to_your_webcomponents-lite.js") ) // You may/may not need webcomponents.js here
.then( loadRes( chrome.extension.getURL("path_to_your_polymer.html") ) )
.then( loadRes( chrome.extension.getURL("path_to_your_custome_component") ) )
.then(function(){
// code that depends on web components
});
您必须将 chrome.extension.getURL
加载的网址添加到清单的 web_accessible_resources
部分.
YOU MUST add the urls loaded by chrome.extension.getURL
to the web_accessible_resources
portion of your manifest.
以上是必须的,因为polymer.html必须通过html资源加载.阅读埃里克·比德曼在这里的回复
The above is necessary since polymer.html must be loaded through an html resource. Read Eric Bidelman's reply here
请注意,如果您的组件已经加载了 webcomponents polyfill,则您可能不需要在此处加载它们.
Please note that you may not need the webcomponents polyfill loaded here if your component already loads them.
这篇关于从 chrome 扩展注册自定义元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!