Chrome 扩展内容脚本中的聚合物元素

Polymer element in Chrome extension content script

我创建了一个自定义的 Polymer 元素,并尝试在我的 Chrome 扩展中使用它。但是,我运行陷入了下面的问题。

我无法从内容脚本访问我的元素 API。 这就是我的意思。

我的元素模板

<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>

在我的-element.js

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

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

有趣的是,我可以看到 my-element 在页面上正确呈现,包括阴影 dom 和其他东西。如果我在主机网页的控制台中 运行 document.querySelector('my-element').init() ,它会无误地执行。但是,在内容脚本中执行相同的代码会产生错误。

我尝试将 Polymer 本身作为内容脚本包含在内。我 运行 遇到了 registerElement 问题,但由于 问题,我解决了它。在这种情况下,我在 content.js 中定义了 window.Polymer。我的元素的 API 变得完全可访问,但是现在当我将它附加到主机网页的 DOM.

时它的阴影 dom 不会呈现

您正在访问内容脚本的沙箱:

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

您的 Polymer 组件的脚本 运行 在主机页面中,因此您的内容脚本不可见。

您可以将新的脚本标记插入到主机页面,并从扩展程序中的 .js 文件获取它,例如

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

这将 运行 something.js 在主机页面的上下文中,授予它访问主机页面中所有其他脚本(包括您的 Polymer 组件)的权限,但也会使其对您不可见内容脚本。请特别注意在宿主页面中注入脚本的security implications

如果您不 able/willing 将所有扩展逻辑推送到注入的脚本中,例如因为您需要访问 chrome.* API 或主机页面和内容脚本之间的某种其他类型的通信,请查看 message posting.