Registering a custom element from a chrome extension

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

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.

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?

回答1:

It is indeed possible. But, a little hacky.

Original Answer

Here are the steps:

  • Native web components (no Polymer)
    NOTE: This requires the usage of the webcomponentsjs polyfill
    Chrome will prevent native registerElement from being executed within a chrome extension. To overcome it you need to prevent the usage of the native registerElement in favor of a simulated one (the polyfill).

In webcomponents-lite.js Comment out the following code (and make this more elegant if you'd like:

scope.hasNative = false; //Boolean(document.registerElement);

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   }

UPDATE #1 - Improved solution

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      });

YOU MUST add the urls loaded by chrome.extension.getURL to the web_accessible_resources portion of your manifest.

The above is necessary since polymer.html must be loaded through an html resource. Read Eric Bidelman's reply here

Please note that you may not need the webcomponents polyfill loaded here if your component already loads them.



回答2:

Arrived at this problem in July 2017. The straightforward solution I found is to load the latest webcomponents polyfill for custom elements as an extra content script. No code changes necessary in the polyfill file (perhaps feature detection has been improved).

Extract from the manifest:

"content_scripts": [     {       "matches": [""],       "js": ["webcomponents-sd-ce.js", "contentscript.js"]     } ]


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!