Chrome扩展程序内容脚本中的聚合物

3
我将尝试在Chrome扩展程序中使用Polymer。总体目标是利用样式封装,使得我的内容脚本运行时与正在访问的页面的CSS隔离开来。
首先从my-element.html中创建自定义元素。
我会这样使用Vulcanize:
vulcanize -o build.html my-element.html

如果我在我的内容脚本中尝试这样做:

如果我在我的内容脚本中尝试这样做:

// content_script.js
$.get(chrome.extension.getURL('build.html'), function(data) {
  var html = document.createElement('div');
  html.innerHTML = data;
  document.body.appendChild(html);

  var custom = document.createElement('my-element');
  document.body.appendChild(custom);
});

build.html可以正常加载,但是my-element无法工作。它只创建了一个空标签,没有我的shadow DOM内容。

我看到我做的有几个潜在问题:

  1. 我将polymer stuff加载到了一个div中。它需要直接加载到body中吗?如果是这样,应该如何实现?
  2. 我假设使用ajax加载build.html会起作用。这是不正确的假设吗?

只是好奇:为什么你会在Chrome扩展中使用Polymer?既然它是Chrome,你不可以直接使用自定义元素和影子DOM吗? - MaxArt
2
是的,我可以这样做,如果必要的话,下一步我会尝试。但是Polymer添加了很多糖和好用的功能。我认为学习Polymer更有意义,因为它更适合生产环境,而原生Web组件可能还需要很长时间才能完全实现。 - anderspitman
6
有一个突出的Chrome漏洞,阻止内容脚本注册自定义元素:https://code.google.com/p/chromium/issues/detail?id=390807 - ebidel
糟糕。如果我想在Chrome扩展中实现CSS隔离,目前唯一的选择是使用iframe吗?还是有其他合理的途径? - anderspitman
有另外一种方法,请查看我在下面的帖子中提出的解决方案https://dev59.com/Torda4cB1Zd3GeqPMXB_#30034988 - dipole_moment
2个回答

1

编辑: 虽然下面的方法确实可行,但我认为除了针对非常有限的范围——单域名目标或简单小部件的项目,我不能推荐它。


我猜测Chrome阻止扩展使用registerElement()导致了你的问题。 注入HTML文件,然后调用polymer.js似乎将库放在宿主页面的上下文中而不是内容脚本中。
这是我从他们的教程中粗略地修改成概念验证的例子:

manifest.json

{
    "name": "polymer-test",
    "version": "0.0.1",
    "manifest_version": 2,
    // CSP might be overkill
    "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
    "content_scripts": [
        {
            "js": [
                "contentscript.js"
            ],
            "matches": [
                "<all_urls>"
            ]
        }
    ],
    "web_accessible_resources": [
        "counter.html",
        "polymer.html",
        "polymer.js"
    ]
}

contentscript.js

document.body.insertAdjacentHTML('beforeend', '<div>'
    // polymer.html throws an error w/o layout.html -- not a big deal
    + '<link rel="import" href="'+chrome.extension.getURL('/polymer.html')+'">'
    + '<link rel="import" href="'+chrome.extension.getURL('/custom.html')+'">'
    + '<my-counter counter="1">Points</my-counter>'
+ '</div>');

counter.html

<polymer-element name="my-counter" attributes="counter">
    <template>
        <style></style>
        <div id="label"><content></content></div>
        Value: <span id="counterVal">{{counter}}</span><br>
        <button on-tap="{{increment}}">Increment</button>
    </template>
    <script>
        Polymer({
            counter: 0, // Default value
            counterChanged: function() {
                this.$.counterVal.classList.add('highlight');
            },
            increment: function() {
                this.counter++;
            }
        });
    </script>
</polymer-element>

请查看:https://dev59.com/Torda4cB1Zd3GeqPMXB_#30034988 - dipole_moment

0

我最近创建了Boundary,这是一个CSS+JS库,可以解决类似这样的问题。Boundary可以创建与现有网页CSS完全分离的元素。

以创建对话框为例。安装Boundary后,您可以在内容脚本中执行以下操作:

var dialog = Boundary.createBox({
    "id": "yourDialogID"
});

Boundary.loadBoxCSS("#yourDialogID", "style-for-elems-in-dialog.css");

Boundary.appendToBox(
    "#yourDialogID",
    "<button id='submit_button'>submit</button>"
);

Boundary.find("#submit_button").click(function() {
  // find() function returns a regular jQuery DOM element
  // so you can do whatever you want with it.
  // some js after button is clicked.
});

#yourDialogID中的元素不会受到现有网页的影响。

希望这能帮到您。如果有任何问题,请告诉我。

https://github.com/liviavinci/Boundary


明确披露这是您自己的创作,并在答案中包含一个最小示例。否则,这可能被视为垃圾邮件/仅链接/自我推广。 - Xan
如果您能根据这些提示提供一个好的答案,请将其放在主要问题中:https://dev59.com/yGcs5IYBdhLWcg3wgkWu - Xan
@Xan Mmm,我看到了你在我的上一个回答中关于删除代码片段的评论。我想当你说最小化示例时,我误解了你的意思。什么算作最小化示例? - Livia Zhang
我的意思是只添加“运行代码片段”的格式标签。我已经编辑了你的另一篇帖子,将其删除了。 - Xan
@Xan明白了!我以为代码片段标签是为了让stackoverflow识别代码:p - Livia Zhang
多行代码的格式化只需使用正确的缩进量(通常为4个空格),语法高亮通常来自问题标签。 - Xan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接