anderspitman
anderspitman

Reputation: 10520

Polymer in Chrome Extension content script

I'm trying to use Polymer in a chrome extension. The overall goal is to leverage styling encapsulation so my content scripts run isolated from the CSS of the page being visited.

Beginning with a custom element in my-element.html

I'm using Vulcanize like so:

vulcanize -o build.html my-element.html

If I try something like this in my content script:

// 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 loads ok, but my-element is not working. It just creates an empty tag with none of my shadow DOM contents.

I see a couple potential problems with what I'm doing:

  1. I'm loading the polymer stuff into a div. Does it need to be loaded directly into body? If so, how is this done?
  2. I'm assuming loading build.html with ajax will work in the first place. Is this an incorrect assumption?

Upvotes: 3

Views: 1757

Answers (2)

awdyson
awdyson

Reputation: 363

Edit: While the method below does work, I don't think I can recommend it except for projects very limited in scope -- single domain target or simple widget.


My guess is that Chrome blocking registerElement() for extensions is causing you issues. Injecting an HTML file which then calls polymer.js seems to put the library in context of the host page rather than the content script.

Here's a proof of concept I hacked together from their tutorial:

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>

Upvotes: 1

Livia Zhang
Livia Zhang

Reputation: 303

I recently created Boundary, a CSS+JS library to solve problems just like this. Boundary creates elements that are completely separate from the existing webpage's CSS.

Take creating a dialog for example. After installing Boundary, you can do this in your content script

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

Elements within #yourDialogID will not be affected by the existing webpage.

Hope this helps. Please let me know if you have any question.

https://github.com/liviavinci/Boundary

Upvotes: 0

Related Questions