从chrome扩展注册自定义元素

dip*_*ent 4 web-component google-chrome-extension polymer

我已经尝试通过原生javascript和聚合物从chrome扩展中注册自定义元素而没有运气.这里记录了这个问题.

Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'polymer-element'. Elements cannot be registered from extensions.
Run Code Online (Sandbox Code Playgroud)

我正在寻找在扩展中使用Web组件的建议 - 有没有人这样做过?我的直觉是在阴影DOM上使用标准的html标签(div等)注册这些元素,直到它被支持为止.有什么建议?

Dmi*_*dov 10

对我来说,@webcomponents/custom-elements在我的content.js. 同样webcomponents-sd-ce.js重量约为 80kb,custom-elements.min.js只有 16kb。

只需将其安装为依赖项并将其导入,content.js然后让您的包管理器完成剩下的工作。

npm i @webcomponents/custom-elements
Run Code Online (Sandbox Code Playgroud)
import '@webcomponents/custom-elements'
Run Code Online (Sandbox Code Playgroud)

这就是我在我的项目popup-tab-switcher 中使用它的方式。


我相信所有这些解决方法都是不必要的,自定义元素必须适用于没有 polyfill 的扩展。请投票支持Chrome 错误中的问题,以引起对该缺陷的关注。


dip*_*ent 7

这确实是可能的.但是,有点hacky.

原始答案

以下是步骤:

  • 本机Web组件(无聚合物)
    注意:这需要使用webcomponentsjs polyfill
    Chrome将阻止本机registerElement在chrome扩展中执行.要克服它,你需要防止使用原生registerElement而使用模拟的(polyfill).

webcomponents-lite.js评论中输出以下代码(如果你愿意,可以使它更优雅:

scope.hasNative = false; //Boolean(document.registerElement);
Run Code Online (Sandbox Code Playgroud)

瞧!本机registerElement现在已经换成了填充工具-其中铬不使用扩展内阻止.

  • Polymer Web组件
    您需要执行上述步骤中列出的代码,此外,您还需要通过以下代码加载聚合物

      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
      }
    
    Run Code Online (Sandbox Code Playgroud)

更新#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 
    });
Run Code Online (Sandbox Code Playgroud)

您必须将加载的网址添加chrome.extension.getURLweb_accessible_resources清单的部分.

以上是必要的,因为必须通过html资源加载polymer.html.在这里阅读Eric Bidelman的回复

请注意,如果您的组件已加载,则可能不需要在此处加载的webcomponents polyfill.