简体   繁体   中英

Polymer element in Chrome extension content script

I created a custom Polymer element, and tried to use it in my Chrome extension. However, I ran into the following problem.

I can't access my element's API from the content script. Here is what I mean.

my-element's template

<link rel="import" href="../polymer/polymer.html">
<dom-module id="my-element">
<template>
... some html...
</template>
<script src="js/my-element.js"></script>
</dom-module>

in my-element.js

Polymer({
  is: 'my-element',
  init: function () {
    console.log('init');
  }
});

in content.js

var link = document.createElement('link');
link.setAttribute('rel', 'import');
link.setAttribute('href', chrome.extension.getURL('my-element.html'));
link.onload = function() {
  var elem = document.createElement('my-element');
  document.body.appendChild(elem);
  elem.init(); // Error: undefined is not a function
};
document.body.appendChild(link);

What is interesting it's that I can see that my-element is rendered properly on page, with all it's shadow dom and things. And If I run document.querySelector('my-element').init() in the host webpage's console, it is executed without errors. However, executing the same code inside the content script yields an error.

I tried to include Polymer itself as a content script. I ran into registerElement problem, but I solved it thanks to this question. In this case, I have window.Polymer defined in my content.js . My-element's API becomes fully accessible, but now it's shadow dom is not rendered when I append it to the host webpage's DOM.

You're hitting the sandbox of your content script:

Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any functions or access any variables defined by content scripts.

from https://developer.chrome.com/extensions/content_scripts#execution-environment

The script of your Polymer component runs in the host page, so it's invisible to your content script.

You can inject a new script tag into the host page, and source it from a .js file in your extension, eg

var script = document.createElement('<script>');
script.src = chrome.extension.getURL('something.js');
document.appendChild(script);

This will run something.js in the context of the host page, granting it access to all other scripts (including your Polymer component) in the host page, but also making it invisible to your content script. Please pay special attention to the security implications of injecting your script in the host page.

If you're not able/willing to push all your extension logic into that injected script, eg because you need access to chrome.* APIs or some other kind of communication between host page and content script, take a look at message posting .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM