feat: code-block component & sample code
This commit is contained in:
parent
d12f6a5aa6
commit
9225fa662e
7 changed files with 80 additions and 9 deletions
3
public/prism.css
Normal file
3
public/prism.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
/* PrismJS 1.29.0
|
||||||
|
https://prismjs.com/download.html#themes=prism&languages=clike+javascript */
|
||||||
|
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
|
5
public/prism.js
Normal file
5
public/prism.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -62,6 +62,8 @@ async function insertRegistry(
|
||||||
key.replace(`.${type}`, "")
|
key.replace(`.${type}`, "")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log(">>> availableComponents", availableComponents);
|
||||||
|
|
||||||
const usedCustomElements = [];
|
const usedCustomElements = [];
|
||||||
|
|
||||||
walkSync(ast, (node) => {
|
walkSync(ast, (node) => {
|
||||||
|
@ -74,6 +76,7 @@ async function insertRegistry(
|
||||||
|
|
||||||
// insert registry script to head
|
// insert registry script to head
|
||||||
if (usedCustomElements.length > 0) {
|
if (usedCustomElements.length > 0) {
|
||||||
|
console.log(">>> usedCustomElements", usedCustomElements);
|
||||||
const registryScript = await buildRegistry(usedCustomElements, type);
|
const registryScript = await buildRegistry(usedCustomElements, type);
|
||||||
walkSync(ast, (node) => {
|
walkSync(ast, (node) => {
|
||||||
if (node.type === ELEMENT_NODE && node.name === "head") {
|
if (node.type === ELEMENT_NODE && node.name === "head") {
|
||||||
|
@ -95,7 +98,9 @@ import { WebComponent } from "https://unpkg.com/web-component-base@1.6.15/WebCom
|
||||||
`assets:components:${name}.${type}`
|
`assets:components:${name}.${type}`
|
||||||
);
|
);
|
||||||
registryScript += content;
|
registryScript += content;
|
||||||
const evalStore = eval(`class WebComponent {};(${content.toString()})`);
|
const evalStore = eval(
|
||||||
|
`class WebComponent {}; class HTMLElement {}; (${content.toString()})`
|
||||||
|
);
|
||||||
const className = new evalStore().constructor.name;
|
const className = new evalStore().constructor.name;
|
||||||
|
|
||||||
registryScript += `customElements.define("${name}", ${className});`;
|
registryScript += `customElements.define("${name}", ${className});`;
|
||||||
|
@ -224,13 +229,31 @@ async function useFragments(html: string) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (node.type === ELEMENT_NODE && !!usedFragment) {
|
if (node.type === ELEMENT_NODE && !!usedFragment) {
|
||||||
node.children.push(parse(usedFragment.text));
|
const value = replaceSlots(usedFragment.text, node);
|
||||||
|
node.children.push(parse(value));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return render(ast);
|
return render(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceSlots(text: string, sourceNode: UltraNode) {
|
||||||
|
const regex = /<slot \/>/g;
|
||||||
|
var match;
|
||||||
|
|
||||||
|
while ((match = regex.exec(text))) {
|
||||||
|
let [key, _value] = match;
|
||||||
|
const slotName = sourceNode.attributes.slot;
|
||||||
|
const h = sourceNode.children.find((node) => node.name === slotName);
|
||||||
|
if (h) {
|
||||||
|
text = text?.replace(key, h.value);
|
||||||
|
sourceNode.children.splice(sourceNode.children.indexOf(h), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
async function getFiles(type: string) {
|
async function getFiles(type: string) {
|
||||||
return (await useStorage().getKeys("assets:components"))
|
return (await useStorage().getKeys("assets:components"))
|
||||||
.map((key) => key.replace("assets:components:", ""))
|
.map((key) => key.replace("assets:components:", ""))
|
||||||
|
|
20
src/components/code-block.js
Normal file
20
src/components/code-block.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class CodeBlockComponent extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
let lang = this.classList.value;
|
||||||
|
lang = lang.replace("language-", "");
|
||||||
|
|
||||||
|
const trimmed = this.innerHTML.trim();
|
||||||
|
|
||||||
|
const template = `
|
||||||
|
<div>
|
||||||
|
<pre class="${this.classList}" id="pre"><code id="code">${trimmed}</code></pre>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
this.innerHTML = template;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,4 @@
|
||||||
class HelloWorld extends WebComponent {
|
class HelloWorld extends WebComponent {
|
||||||
name = "";
|
|
||||||
static properties = ["name"];
|
static properties = ["name"];
|
||||||
|
|
||||||
onInit() {
|
onInit() {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>McFly: Back to the Basics. Into the Future.</title>
|
<title>McFly: Back to the Basics. Into the Future.</title>
|
||||||
<link rel="stylesheet" href="./reset.css"></style>
|
<link rel="stylesheet" href="./reset.css" />
|
||||||
</head>
|
<link rel="stylesheet" href="./prism.css" />
|
||||||
|
<script src="./prism.js"></script>
|
||||||
|
<slot />
|
||||||
|
</head>
|
||||||
|
|
|
@ -12,6 +12,24 @@
|
||||||
Here's a sample interactive custom element:
|
Here's a sample interactive custom element:
|
||||||
<hello-world name="McFly"></hello-world>
|
<hello-world name="McFly"></hello-world>
|
||||||
</p>
|
</p>
|
||||||
|
<code-block class="language-js line-numbers" data-line="2">
|
||||||
|
<pre>
|
||||||
|
class HelloWorld extends WebComponent {
|
||||||
|
static properties = ["name"];
|
||||||
|
|
||||||
|
onInit() {
|
||||||
|
let count = 0;
|
||||||
|
this.onclick = () => {
|
||||||
|
this.setAttribute("name", `Clicked ${++count}x`);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get template() {
|
||||||
|
return `<button style="cursor:pointer">Hello ${this.name}!</button>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</code-block>
|
||||||
<p>
|
<p>
|
||||||
Start at the very basic of writing HTML files and enhance with standard
|
Start at the very basic of writing HTML files and enhance with standard
|
||||||
web technologies or go advanced as you like, at your own pace.
|
web technologies or go advanced as you like, at your own pace.
|
||||||
|
|
Loading…
Reference in a new issue