Comments (16)
duplicating the answer for ungap/custom-elements-builtin#3 (comment)
@BryceBeagle everything is written in here:
https://github.com/WebReflection/document-register-element#how-to-polyfill-custom-elements-v1
If you have window.customElements
already you don't need any polyfill to use this one, and this one is about using V1, where available, to extend V1 itself, specially on Safari, the only one left behind with built in extends.
Every browser that won't have customElements will never show a warning about anything.
If for some reason you cannot use that approach, you can var dre = require('document-register-elements/pony');
and then if (!window.customElements) dre(window);
In all cases, you won't have any warning.
from document-register-element.
I'm not sure I understand what you're saying, sorry. My scope does not natively have customElements
defined, as you can see with the final error of my original comment above. My understanding is that this means I need to use a polyfill to get this functionality, right?
My issue was not simply with the deprecation warning that I get, but with the Uncaught DOMException
that follows and leaves the custom element undefined. I left the deprecation warning in the output in the event that it was helpful.
I get this error only with this polyfill and not with the webcomponentsjs polyfill, so clearly something is different.
from document-register-element.
Hey @BryceBeagle. Your problem could be unrelated to web components and this polyfill.
What is the scope of your test.js
file? console.log(this);
Maybe try it first in the browser directly without any chrome extension wrapping. This way you could narrow the scope of possible problems. ✌️
from document-register-element.
Oh gosh ... Is this really yet another jsdom thing ?
from document-register-element.
I suspect it something to do with the global object. It might not be window
object in the context of extension API Bryce is using https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript.
Quick fix could be to use window.customElements
instead of customElements
from document-register-element.
Unfortunately, using window.customElements
has the same result for me. In my scope, this
is defined to be window
:
Also, customElements work just fine for me in the browser when not in the Extension, without the polyfill.
from document-register-element.
@BryceBeagle this page works for me https://webreflection.github.io/document-register-element/test/ so it's clear you have some third part obtrusive script that is causing you problems.
As reminder, the extension AdBlock Plus, with nearly 100 million users, ships with this polyfill already in both Chrome and Firefox but it's loaded only if needed as previously explained.
if (!window.customElements) require("document-register-element/pony")(window);
from document-register-element.
@BryceBeagle, it totally makes sense that some API will not be allowed for extensions. Especially the ones which could manipulate the DOM.
I won't be surprised if customElements
is blocked.
I would clarify that first.
You can try moving define
from your test.js
E.g. in you background.js
// chrome.tabs.executeScript(tab.id, {file: 'test.js'}); // content script. probably can't define custom elemenst.
// Instead try this below (copy from test.js to background.js)
class TestElement extends HTMLElement {}
customElements.define('test-element', TestElement);
document.body.appendChild(new TestElement);
Edit: modified example
from document-register-element.
true that we use the poly within the extension page we own, we don't try to pollute the global context that hosts our extensions thought. Is that what you are trying to do?
from document-register-element.
I need to learn more about extensions. But it looks like we have two different scopes.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts
content scripts vs background scripts.
Content scripts have a lot of limitations and probably shouldn't be able to manipulate the DOM or define custom elements.
But @BryceBeagle can try defining elements in both scopes. Content script
and Background script
.
chrome.tabs.executeScript(tab.id, {file: 'test.js'});
test.js is a content script in this case. So it won't work.
Try background scripts instead.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts
from document-register-element.
Content scripts have a lot of limitations and probably shouldn't be able to manipulate the DOM or define custom elements.
the content script cannot change the user global context so this poly won't work for that but it also shouldn't, IMO
from document-register-element.
Thanks again for the responses. I can use customElements freely inside the background.js just fine, even without the polyfill, but that's not very helpful as I need to manipulate the DOM of the users' pages, not just a hidden background page.
I'm trying to inject my elements into a page for a user to use without having to resort to a popup/other page. Unfortunately background scripts are not able to manipulate the DOM properly and that really is the purpose of the content script system.
Content scripts have a lot of limitations and probably shouldn't be able to manipulate the DOM
My understanding is that this is exactly what content scripts are for. Background scripts and popup dialog scripts (I'm guessing this is where ABP uses customElements?) have no way of accessing the page's DOM. Only the content scripts can do that. Here's their definition from the Chrome Developer's page (emphasis mine):
Content scripts are files that run in the context of web pages. By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them and pass information to their parent extension.
There should be a way to make this work. Again, webcomponentsjs
functions perfectly for creating regular customElements that extend HTMLElement, but not for creating type extension custom elements (extending things like HTMLTableElement), which is why I'm trying to use the polyfill.
from document-register-element.
Your error literally says:
Elements cannot be registered from extensions.
meaning you cannot use V0 there or it throws. Since whenever customElements are not defined, V0 is used as fallback, which is probably something the other polyfill doesn't use.
There should be a way to make this work.
The content script is a facade of what the user sees. You can crawl the tree, you can even use MutationObserver, but you won't have direct access to the user global scope/context.
If content script doesn't expose customElements it's, I believe, because it could conflict with user customElements.
However, if the other polyfill works so well, it should be able to work with https://github.com/ungap/custom-elements-builtin but apparently it doesn't.
So how about you ditch custom elements as a whole, since inappropriate for this job, and give wickedElements a try instead, so you forget completely polyfills issues?
background.js
"use strict";
chrome.commands.onCommand.addListener(function (command) {
if (command === "do_thing") {
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
let tab = tabs[0];
chrome.tabs.executeScript(tab.id, {file: 'node_modules/wicked-elements/min.js'});
chrome.tabs.executeScript(tab.id, {file: 'test.js'});
});
return true;
}
});
test.js
class TestElement {
constructor() {
return document.createElement('test-element');
}
onconnected() {
console.log('here we go', this.el);
}
}
wickedElements.define('test-element', TestElement);
document.body.appendChild(new TestElement);
That is just one way to go, you can forget classes all together too.
from document-register-element.
FYI I've just tested the following and it worked like a charm
wickedElements.define('body', {
init(event) {
this.el = event.currentTarget;
console.log('wicked!', this.el);
}
});
That means you can forget about Custom Elements limitations and their polyfill mess.
from document-register-element.
That first example with a class you provided does not seem to work. I get the following error using it:
min.js:1 Uncaught TypeError: e.init is not a function
at min.js:1
at HTMLElement.c (min.js:1)
at C (min.js:1)
at D (min.js:1)
at k (min.js:1)
at A (min.js:1)
at MutationObserver.M (min.js:1)
(anonymous) @ min.js:1
c @ min.js:1
C @ min.js:1
D @ min.js:1
k @ min.js:1
A @ min.js:1
M @ min.js:1
from document-register-element.
That first example with a class you provided ...
I haven't provided any class, I've used a literal object.
With a class, you need to pass an init
method (instead of a constructor), but that'd be another project matter, nothing to do here.
from document-register-element.
Related Issues (20)
- LifeCycle events order of nested custom elements inconsistent across Chrome and Firefox HOT 18
- Built-in elements don't work in Firefox HOT 6
- TypeError: new.target does not define a custom element HOT 3
- document.registerElement is deprecated and will be removed in M73 HOT 3
- Post-install script slowness HOT 3
- appreciate your feedback for custom element diagram HOT 8
- Functions are not evaluated in connectedCallback HOT 1
- `this` reference in contructor broken HOT 14
- Multiple instances of the polyfill leads to unexpected behaviour HOT 1
- error ""Failed to construct 'HTMLElement': Please use the 'new' operator"" when using with Angular/elements 8.2.0 HOT 2
- Refreshing a document inside an iframe which loads d-r-e breaks the polyfill and leaves document.createElement as undefined HOT 15
- `attributeChangedCallback()` bound value is invalid HOT 15
- Add DRE to Polyfill.io service HOT 1
- [QUESTION] Unable to get property '_isMounted' of undefiened. HOT 1
- TypeError - Object doesn't support property or method 'registerElement' HOT 3
- Time to compare again? (webcompents/custom-elements) HOT 2
- Polyfill does not seem to be working in IE 11 HOT 6
- postinstall fails in noexec enviornment HOT 1
- We unable to install latest version @1.14.7 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from document-register-element.