Reputation: 10520
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:
Upvotes: 3
Views: 1757
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
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