-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
infodusha
committed
Aug 23, 2023
1 parent
1697253
commit 72180ad
Showing
10 changed files
with
293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Merge | ||
on: | ||
push: | ||
branches: | ||
- main | ||
jobs: | ||
release: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
pull-requests: write | ||
id-token: write | ||
steps: | ||
- uses: google-github-actions/release-please-action@v3 | ||
id: release | ||
with: | ||
release-type: node | ||
pull-request-title-pattern: 'chore: release ${version}' | ||
- uses: actions/checkout@v3 | ||
if: ${{ steps.release.outputs.release_created }} | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: '20.x' | ||
registry-url: 'https://registry.npmjs.org' | ||
if: ${{ steps.release.outputs.release_created }} | ||
- run: npm install -g npm | ||
if: ${{ steps.release.outputs.release_created }} | ||
- run: npm ci | ||
if: ${{ steps.release.outputs.release_created }} | ||
- run: npm publish --provenance --access public | ||
env: | ||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
if: ${{ steps.release.outputs.release_created }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
".": "1.0.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,46 @@ | ||
# define-html | ||
|
||
Define custom element to import in html | ||
|
||
# Usage | ||
|
||
Add link to preload external html file and define-html script | ||
```html | ||
... | ||
<link rel="preload" href="content.html" as="fetch" crossorigin /> | ||
<script src="https://unpkg.com/define-html" type="module"></script> | ||
</head> | ||
``` | ||
Where `content.html` is | ||
```html | ||
<template data-selector="app-content"> | ||
Lorem ipsum | ||
</template> | ||
|
||
<style> | ||
:host { | ||
display: block; | ||
} | ||
</style> | ||
``` | ||
So later you can use include your template with | ||
```html | ||
<app-content></app-content> | ||
``` | ||
|
||
# Features | ||
|
||
* Read attribute values | ||
* Make conditional elements | ||
* Optionally enable shadow root | ||
* Partial style encapsulation (when not a shadow root mode) | ||
|
||
# TODO | ||
|
||
* Watch for attribute changes (from js) | ||
* Full style encapsulation (when not a shadow root mode) | ||
* Full slot support | ||
|
||
# License | ||
|
||
Apache-2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<template data-selector="app-content"> | ||
Lorem ipsum | ||
</template> | ||
|
||
<style> | ||
:host { | ||
display: block; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<template data-selector="app-header" data-shadow> | ||
<header> | ||
My name is: <b data-attr="name"></b> | ||
<span data-if="admin"> | ||
I AM THE ADMIN | ||
</span> | ||
<span data-if="admin" data-if-not> | ||
I am the user | ||
</span> | ||
<slot></slot> | ||
</header> | ||
</template> | ||
|
||
<style> | ||
:host { | ||
display: inline-block; | ||
} | ||
|
||
header { | ||
background-color: wheat; | ||
padding: 1rem; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>define-html example</title> | ||
<link rel="preload" href="header.html" as="fetch" crossorigin /> | ||
<link rel="preload" href="content.html" as="fetch" crossorigin /> | ||
<script src="../index.js" type="module"></script> | ||
</head> | ||
<body> | ||
<header> | ||
<h1>Hello there</h1> | ||
</header> | ||
<app-header name="Andrei" admin>extra data</app-header> | ||
<app-header name="Vika"></app-header> | ||
<app-content></app-content> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
const parser = new DOMParser(); | ||
const ignoreDataAttribute = 'data-define-html-ignore'; | ||
|
||
document.addEventListener('DOMContentLoaded', () => { | ||
fetchFromLinks(document).catch(console.error); | ||
}); | ||
|
||
async function fetchFromLinks(element) { | ||
const links = Array.from(element.querySelectorAll(`link[rel='preload'][as='fetch'][href$='.html']:not([${ignoreDataAttribute}])`)); | ||
await Promise.all(links.map(defineHtml)); | ||
} | ||
|
||
async function defineHtml(link) { | ||
const href = link.getAttribute('href'); | ||
const response = await fetch(href); | ||
const text = await response.text(); | ||
const definedElement = parser.parseFromString(text, 'text/html'); | ||
createCustomElement(definedElement); | ||
} | ||
|
||
function createCustomElement(definedElement) { | ||
const template = definedElement.querySelector('template'); | ||
const useShadow = template.hasAttribute('data-shadow'); | ||
const selector = template.getAttribute('data-selector'); | ||
const styles = definedElement.querySelectorAll('style'); | ||
|
||
function setEmulatedStyles() { | ||
for (const style of styles) { | ||
const cssRules = []; | ||
|
||
for (const rule of style.sheet.cssRules) { | ||
rule.selectorText = rule.selectorText.replace(/:host/g, selector); | ||
rule.selectorText = rule.selectorText.replace(/:host\((.+)\)/g, `${selector}$1`); | ||
const re = new RegExp(`^(?!${selector})(.+?)\\s*`,'g'); | ||
rule.selectorText = rule.selectorText.replace(re, `${selector} $1`); | ||
cssRules.push(rule); | ||
} | ||
|
||
const element = style.cloneNode(true); | ||
document.head.appendChild(element); | ||
|
||
while (element.sheet.cssRules.length !== 0) { | ||
element.sheet.deleteRule(0); | ||
} | ||
for (const rule of cssRules) { | ||
element.sheet.insertRule(rule.cssText); | ||
} | ||
} | ||
} | ||
|
||
if(!useShadow) { | ||
setEmulatedStyles(); | ||
} | ||
|
||
class DefineHTMLElement extends HTMLElement { | ||
constructor() { | ||
super(); | ||
const content = this.#getContent(); | ||
this.#attach(content); | ||
this.#setAttrs(); | ||
if (useShadow) { | ||
this.#setShadowStyles(); | ||
} | ||
} | ||
|
||
#getContent() { | ||
const content = template.content.cloneNode(true); | ||
for (const element of content.querySelectorAll(`[data-if]`)) { | ||
const hasIfNot = element.hasAttribute('data-if-not'); | ||
const name = element.getAttribute('data-if'); | ||
const hasAttr = this.hasAttribute(name); | ||
if (hasIfNot ? hasAttr : !hasAttr) { | ||
element.remove(); | ||
} | ||
} | ||
return content; | ||
} | ||
|
||
#attach(content) { | ||
if (useShadow) { | ||
const shadowRoot = this.attachShadow({ mode: 'closed' }); | ||
shadowRoot.appendChild(content); | ||
} else { | ||
const slotElements = content.querySelectorAll('slot'); | ||
if (slotElements.length === 0 && this.childNodes.length > 0) { | ||
throw new Error(`No slot found for ${selector}`) | ||
} | ||
// TODO probably handle full slot support | ||
for (const element of slotElements) { | ||
if (this.childNodes.length > 0) { | ||
element.before(...this.childNodes); | ||
} | ||
element.remove(); | ||
} | ||
this.appendChild(content); | ||
} | ||
} | ||
|
||
#setAttrs() { | ||
const root = useShadow ? this.shadowRoot : this; | ||
for (const { name, value } of this.attributes) { | ||
for (const element of root.querySelectorAll(`[data-attr='${name}']`)) { | ||
if (element.childNodes) { | ||
// TODO handle case when there are already nodes inside | ||
} | ||
element.innerText = value; | ||
} | ||
} | ||
} | ||
|
||
#setShadowStyles() { | ||
for (const style of styles) { | ||
const element = style.cloneNode(true); | ||
this.shadowRoot.appendChild(element); | ||
} | ||
} | ||
} | ||
|
||
customElements.define(selector, DefineHTMLElement); | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "define-html", | ||
"version": "1.0.0", | ||
"description": "Define custom element to import in html", | ||
"main": "index.js", | ||
"type": "module", | ||
"scripts": { | ||
"example": "npx http-server --cors" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/infodusha/define-html.git" | ||
}, | ||
"keywords": [ | ||
"html", | ||
"define", | ||
"import", | ||
"include" | ||
], | ||
"files": [ | ||
"index.js", | ||
"package.json", | ||
"LICENSE", | ||
"README.md", | ||
"CHANGELOG.md" | ||
], | ||
"author": "infodusha", | ||
"license": "Apache-2.0" | ||
} |