Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/peixin/vue3-custom-component
Vue3 custom element does not render below chrome 66
https://github.com/peixin/vue3-custom-component
chrome chromium custom-elements vue vue3 web-components
Last synced: about 1 month ago
JSON representation
Vue3 custom element does not render below chrome 66
- Host: GitHub
- URL: https://github.com/peixin/vue3-custom-component
- Owner: peixin
- Created: 2023-11-16T09:23:46.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2023-11-16T13:46:05.000Z (about 1 year ago)
- Last Synced: 2024-10-12T17:24:33.853Z (2 months ago)
- Topics: chrome, chromium, custom-elements, vue, vue3, web-components
- Language: TypeScript
- Homepage: https://vue3-custom-component.vercel.app/
- Size: 2.04 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Demo https://vue3-custom-component.vercel.app/
# Issue
Vue3 custom element (Web Component) does not render below Chrome 65 (Android 8 built-in webview)# Reason
When `isCustomizedBuiltIn` is false, Vue3 passes `undefined` as the second argument to `document.createElement` through `nodeOps.createElement` when the built-in tag name is not used as a custom element. This usage does not work in Chrome versions prior to 66, meaning that the `constructor` and `connectedCallback` of the custom element will not be triggered.Interestingly, starting from version 66, the `constructor` will not be triggered upon creation, but when appended to the DOM, the `constructor` and `connectedCallback` will be triggered in sequence, allowing it to function properly. In the latest version, the `constructor` will be triggered upon creation, and when appended to the DOM, the `connectedCallback` will be triggered.
# Temporary solution
```javascript
// file: index.html
// patch the createElement to avoid options is nullish
var _createElement = window.document.createElement;
window.document.createElement = function (tagName, options) {
if (options) {
return _createElement.call(window.document, tagName, options);
} else {
return _createElement.call(window.document, tagName);
}
}
```# Debug Progress
### Demo Showcase
#### Demo custom element code
```javascript
// file: src/custom-element.ts
class CustomElement extends HTMLElement {
constructor() {
super();
console.log("Custom element created");
}connectedCallback() {
const text = this.dataset["text"];
console.log("Custom element added to page --> ", text);
const div = document.createElement("div");
div.innerText = "custom-element with text: " + text;this.appendChild(div);
}
}customElements.define("custom-element", CustomElement);
```#### Demo Result
**Chrome/65.0.3325.144**
![Chrome/65.0.3325.144](./docs/images/demo-result-chrome-65.png)
**Chrome/66.0.3347.0**
![Chrome/66.0.3347.0](./docs/images/demo-result-chrome-66.png)
**Chrome/118.0.0.0**
![Chrome/118.0.0.0](./docs/images/demo-result-chrome-118.png)
### Chromium Source Code Changes
[chromium version: 65.0.3323.3](https://chromium.googlesource.com/chromium/src/+/470d3a6be2f380affa8de3dc0dd1508f3eeba9f7/third_party/WebKit/Source/core/dom/Document.cpp#908)![chromium version: 65.0.3323.3](./docs/images/code-chromium-65.png)
[chromium version: 66.0.3347.3](https://chromium.googlesource.com/chromium/src/+/3b9cfdda2eb80dab7457ec61e619dd910d194248/third_party/WebKit/Source/core/dom/Document.cpp#1075)
![chromium version: 66.0.3347.3](./docs/images/code-chromium-66.png)
[chromium version 121.0.61313.1](https://chromium.googlesource.com/chromium/src/+/refs/tags/121.0.6131.1/third_party/blink/renderer/core/dom/document.cc#1282)
![chromium version 121.0.61313.1](./docs/images/code-chromium-118.png)
### Console Debug
**Chrome/65.0.3325.144**
![Chrome/65.0.3325.144](./docs/images/console-debug-chrome-65.png)
**Chrome/66.0.3347.0**
![Chrome/66.0.3347.0](./docs/images/console-debug-chrome-66.png)
**Chrome/118.0.0.0**
![Chrome/118.0.0.0](./docs/images/console-debug-chrome-118.png)
**Test Code**
```javascript
// define custom element
class CustomElement extends HTMLElement {
constructor() {
super();
console.log("Custom element created");
}connectedCallback() {
const text = this.dataset["text"];
console.log("Custom element added to page --> ", text);
const div = document.createElement("div");
div.innerText = "custom-element with text: " + text;this.appendChild(div);
}
}
customElements.define("custom-element", CustomElement);// create element with options undefined
e = document.createElement("custom-element", undefined)
// Chrome/65.0.3325.144 ❌ constructor not executed
// Chrome/66.0.3347.0 ⚠️ constructor not executed
// Chrome/118.0.0.0 ✅ constructor executed// create element with options null
document.createElement("custom-element", null)
// Chrome/65.0.3325.144 ❌ constructor not executed
// Chrome/66.0.3347.0 ⚠️ constructor not executed
// Chrome/118.0.0.0 ✅ constructor executed// create element with options string empty
document.createElement("custom-element", "")
// Chrome/65.0.3325.144 ❌ constructor not executed
// Chrome/66.0.3347.0 ⚠️ constructor not executed
// Chrome/118.0.0.0 ✅ constructor executed// create element with out options
document.createElement("custom-element")
// Chrome/65.0.3325.144 ✅ constructor executed
// Chrome/66.0.3347.0 ✅ constructor executed
// Chrome/118.0.0.0 ✅ constructor executed// create element with options {is: ""}
document.createElement("custom-element", {is: ""})
// Chrome/65.0.3325.144 ✅ constructor executed
// Chrome/66.0.3347.0 ✅ constructor executed
// Chrome/118.0.0.0 ✅ constructor executed// create element with options empty object
document.createElement("custom-element", {})
// Chrome/65.0.3325.144 ✅ constructor executed
// Chrome/66.0.3347.0 ✅ constructor executed
// Chrome/118.0.0.0 ✅ constructor executed// test appent to dom
testDiv = document.getElementById("testDiv")testDiv.appendChild(e)
// Chrome/65.0.3325.144 ❌ constructor not executed && connectedCallback not executed
// Chrome/66.0.3347.0 ✅ constructor executed && connectedCallback executed
// Chrome/118.0.0.0 ✅ connectedCallback executed
```