从 chrome 扩展注册自定义元素
Registering a custom element from a chrome extension
我曾尝试通过本机 javascript 和聚合物从 chrome 扩展中注册自定义元素,但没有成功。 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 组件的建议 - 有人这样做了吗?我的直觉是暂时在阴影 DOM 上使用标准 html 标记(div,等等...)注册这些元素,直到它被支持为止。有什么建议吗?
确实可以。但是,有点老套。
原答案
步骤如下:
- 本机 Web 组件(无 Polymer)
注意:这需要使用 webcomponentsjs polyfill
Chrome 将阻止原生 registerElement
在 chrome 扩展中执行。为了克服它,你需要阻止使用原生的 registerElement
来支持模拟的(polyfill)。
在 webcomponents-lite.js
中注释掉以下代码(如果您愿意,可以使其更优雅:
scope.hasNative = false; //Boolean(document.registerElement);
瞧! nativeregisterElement
现在已被 polyfill 取代 - chrome 不会阻止在扩展中使用。
聚合物网络组件
您将需要执行上述步骤中列出的代码,此外,您还需要通过以下代码加载聚合物
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 在动态加载时无法在扩展中工作。因此,上述修改是必要的。一个更简单的替代方法是 将聚合物加载到内容脚本中的头部 中,如下所示:
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
加载的 url 添加到清单的 web_accessible_resources
部分。
以上是必要的,因为 polymer.html 必须通过 html 资源加载。阅读 Eric Bidelman's reply here
请注意如果您的组件已经加载它们,您可能不需要在此处加载它们。
2017 年 7 月遇到这个问题。我找到的直接解决方案是加载最新的 webcomponents polyfill for custom elements 作为额外的内容脚本。 polyfill 文件中无需更改代码(可能改进了功能检测)。
清单摘录:
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["webcomponents-sd-ce.js", "contentscript.js"]
}
]
对我来说,在 content.js
中使用 @webcomponents/custom-elements
包就足够了。
另外 webcomponents-sd-ce.js
重量大约 80kb 而 custom-elements.min.js
只有 16kb。
只需将其作为依赖项安装并导入到 content.js
中,让您的包管理器完成剩下的工作。
npm i @webcomponents/custom-elements
import '@webcomponents/custom-elements'
这就是我在我的项目中使用它的方式popup-tab-switcher。
我认为所有这些解决方法都不是必需的,自定义元素必须适用于没有 polyfill 的扩展。请投票给 the issue in Chrome bugs 以提请注意此缺陷。
我曾尝试通过本机 javascript 和聚合物从 chrome 扩展中注册自定义元素,但没有成功。 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 组件的建议 - 有人这样做了吗?我的直觉是暂时在阴影 DOM 上使用标准 html 标记(div,等等...)注册这些元素,直到它被支持为止。有什么建议吗?
确实可以。但是,有点老套。
原答案
步骤如下:
- 本机 Web 组件(无 Polymer)
注意:这需要使用 webcomponentsjs polyfill
Chrome 将阻止原生registerElement
在 chrome 扩展中执行。为了克服它,你需要阻止使用原生的registerElement
来支持模拟的(polyfill)。
在 webcomponents-lite.js
中注释掉以下代码(如果您愿意,可以使其更优雅:
scope.hasNative = false; //Boolean(document.registerElement);
瞧! nativeregisterElement
现在已被 polyfill 取代 - chrome 不会阻止在扩展中使用。
聚合物网络组件
您将需要执行上述步骤中列出的代码,此外,您还需要通过以下代码加载聚合物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 在动态加载时无法在扩展中工作。因此,上述修改是必要的。一个更简单的替代方法是 将聚合物加载到内容脚本中的头部 中,如下所示:
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
加载的 url 添加到清单的 web_accessible_resources
部分。
以上是必要的,因为 polymer.html 必须通过 html 资源加载。阅读 Eric Bidelman's reply here
请注意如果您的组件已经加载它们,您可能不需要在此处加载它们。
2017 年 7 月遇到这个问题。我找到的直接解决方案是加载最新的 webcomponents polyfill for custom elements 作为额外的内容脚本。 polyfill 文件中无需更改代码(可能改进了功能检测)。
清单摘录:
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["webcomponents-sd-ce.js", "contentscript.js"]
}
]
对我来说,在 content.js
中使用 @webcomponents/custom-elements
包就足够了。
另外 webcomponents-sd-ce.js
重量大约 80kb 而 custom-elements.min.js
只有 16kb。
只需将其作为依赖项安装并导入到 content.js
中,让您的包管理器完成剩下的工作。
npm i @webcomponents/custom-elements
import '@webcomponents/custom-elements'
这就是我在我的项目中使用它的方式popup-tab-switcher。
我认为所有这些解决方法都不是必需的,自定义元素必须适用于没有 polyfill 的扩展。请投票给 the issue in Chrome bugs 以提请注意此缺陷。