From 71c48fc14dafae54343e798ca2eecb8695a9e384 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 29 Oct 2023 19:19:29 +0100 Subject: [PATCH] Create CSS module-like structure Doesn't currently work; @import rules are not yet valid in constructed stylesheets. --- index.html | 113 +------------------------- src/elements/base.mjs | 25 +++++- src/elements/canvas/canvas.css | 11 +++ src/elements/canvas/canvas.mjs | 4 + src/elements/canvas/canvasitem.css | 3 + src/elements/canvas/canvasitem.mjs | 4 + src/elements/canvas/edge/base.css | 3 + src/elements/canvas/edge/base.mjs | 4 + src/elements/canvas/node/base.css | 6 ++ src/elements/canvas/node/base.mjs | 4 + src/elements/canvas/node/file.css | 10 +++ src/elements/canvas/node/file.mjs | 4 + src/elements/canvas/node/group.css | 17 ++++ src/elements/canvas/node/group.mjs | 4 + src/elements/canvas/node/text.css | 4 + src/elements/canvas/node/text.mjs | 4 + src/elements/markdown/frontmatter.css | 3 + src/elements/markdown/frontmatter.mjs | 4 + src/elements/markdown/hashtag.css | 4 + src/elements/markdown/hashtag.mjs | 4 + src/elements/markdown/renderer.css | 3 + src/elements/markdown/renderer.mjs | 4 + src/elements/markdown/wikilink.css | 5 ++ src/elements/markdown/wikilink.mjs | 4 + src/elements/vault.css | 4 + 25 files changed, 144 insertions(+), 111 deletions(-) create mode 100644 src/elements/canvas/canvas.css create mode 100644 src/elements/canvas/canvasitem.css create mode 100644 src/elements/canvas/edge/base.css create mode 100644 src/elements/canvas/node/base.css create mode 100644 src/elements/canvas/node/file.css create mode 100644 src/elements/canvas/node/group.css create mode 100644 src/elements/canvas/node/text.css create mode 100644 src/elements/markdown/frontmatter.css create mode 100644 src/elements/markdown/hashtag.css create mode 100644 src/elements/markdown/renderer.css create mode 100644 src/elements/markdown/wikilink.css create mode 100644 src/elements/vault.css diff --git a/index.html b/index.html index f5ebb09..2b6fa2e 100644 --- a/index.html +++ b/index.html @@ -7,37 +7,16 @@ - + + + diff --git a/src/elements/base.mjs b/src/elements/base.mjs index 626c2f5..33aee03 100644 --- a/src/elements/base.mjs +++ b/src/elements/base.mjs @@ -22,6 +22,27 @@ export class CustomElement extends HTMLElement { throw new NotImplementedError("template has not been overridden.") } + /** + * Create a stylesheet which imports the stylesheet located at this module's path with `.mjs` replaced by `.css`. + * @param importMetaURL The value of `import.meta.url` for the calling module. + * @returns {CSSStyleSheet} The created stylesheet. + */ + static makeModuleLikeStyleSheet(importMetaURL) { + const importURL = importMetaURL.replace(/[.]mjs$/, ".css") + const stylesheet = new CSSStyleSheet() + stylesheet.replaceSync(`@import "${importURL}";`) + return stylesheet + } + + /** + * A way to use inheritance with custom stylesheets. + * @abstract Implementors should add their own stylesheets via this function. + * @returns {CSSStyleSheet[]} An array of stylesheets that should be added to the {@link shadowRoot}. + */ + static createStyleSheets() { + return [] + } + /** * The local cloned instance of the template node. * @type {Node} @@ -41,8 +62,10 @@ export class CustomElement extends HTMLElement { * Callback automatically called when this element is added to the DOM. */ connectedCallback() { - // The shadow root, the inner contents of the element.. + // The shadow root, the inner contents of the element. const shadow = this.attachShadow({ mode: "open" }) + // Attach stylesheets to the shadow root. + shadow.adoptedStyleSheets.push(...this.constructor.createStyleSheets()) // The element contained inside the shadow root.. this.#instance = this.constructor.template.content.cloneNode(true) // Call the custom callback. diff --git a/src/elements/canvas/canvas.css b/src/elements/canvas/canvas.css new file mode 100644 index 0000000..01063d4 --- /dev/null +++ b/src/elements/canvas/canvas.css @@ -0,0 +1,11 @@ +.canvas { + position: relative; + + display: flex; + + width: max-content; + height: max-content; + + margin-top: 64px; + margin-bottom: 64px; +} diff --git a/src/elements/canvas/canvas.mjs b/src/elements/canvas/canvas.mjs index 3465432..85de080 100644 --- a/src/elements/canvas/canvas.mjs +++ b/src/elements/canvas/canvas.mjs @@ -10,6 +10,10 @@ export class CanvasElement extends CustomElement { return document.getElementById("template-canvas") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * The contents of the Canvas, as they were the last time they were updated. * @type {string} diff --git a/src/elements/canvas/canvasitem.css b/src/elements/canvas/canvasitem.css new file mode 100644 index 0000000..f2b8a7d --- /dev/null +++ b/src/elements/canvas/canvasitem.css @@ -0,0 +1,3 @@ +.canvas-item { + +} diff --git a/src/elements/canvas/canvasitem.mjs b/src/elements/canvas/canvasitem.mjs index 1bc4637..eb63d1d 100644 --- a/src/elements/canvas/canvasitem.mjs +++ b/src/elements/canvas/canvasitem.mjs @@ -7,6 +7,10 @@ import {MalformedError} from "../../utils/errors.mjs"; * @abstract */ export class CanvasItemElement extends CustomElement { + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * @returns {number} The X coordinate of the top left vertex of this element. */ diff --git a/src/elements/canvas/edge/base.css b/src/elements/canvas/edge/base.css new file mode 100644 index 0000000..c0c7572 --- /dev/null +++ b/src/elements/canvas/edge/base.css @@ -0,0 +1,3 @@ +.edge { + +} diff --git a/src/elements/canvas/edge/base.mjs b/src/elements/canvas/edge/base.mjs index 13a9e62..fa1eb71 100644 --- a/src/elements/canvas/edge/base.mjs +++ b/src/elements/canvas/edge/base.mjs @@ -11,6 +11,10 @@ export class EdgeElement extends CanvasItemElement { return document.getElementById("template-edge") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * The canvas this element is contained in. * Can be recalculated with {@link recalculateCanvas}. diff --git a/src/elements/canvas/node/base.css b/src/elements/canvas/node/base.css new file mode 100644 index 0000000..50fa0aa --- /dev/null +++ b/src/elements/canvas/node/base.css @@ -0,0 +1,6 @@ +.node { + outline: var(--node-group-border-width) solid var(--color-node); + background-color: color-mix(in srgb, var(--color-node) 20%, var(--color-background)); + border-radius: 0 8px 8px 8px; + padding: 12px; +} diff --git a/src/elements/canvas/node/base.mjs b/src/elements/canvas/node/base.mjs index 6cbc7be..04c8a5f 100644 --- a/src/elements/canvas/node/base.mjs +++ b/src/elements/canvas/node/base.mjs @@ -6,6 +6,10 @@ import { CanvasItemElement } from "../canvasitem.mjs"; * @abstract */ export class NodeElement extends CanvasItemElement { + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * Coordinates of the point where edges connected to the top of this node should attach to. * @type {[number, number]} diff --git a/src/elements/canvas/node/file.css b/src/elements/canvas/node/file.css new file mode 100644 index 0000000..6b40188 --- /dev/null +++ b/src/elements/canvas/node/file.css @@ -0,0 +1,10 @@ +.node-file { + overflow-x: clip; + overflow-y: scroll; +} + +.node-file-label { + font-size: 2em; + margin-block-start: .67em; + margin-block-end: .67em; +} diff --git a/src/elements/canvas/node/file.mjs b/src/elements/canvas/node/file.mjs index 4dcf38f..75c734d 100644 --- a/src/elements/canvas/node/file.mjs +++ b/src/elements/canvas/node/file.mjs @@ -8,6 +8,10 @@ export class NodeFileElement extends NodeElement { return document.getElementById("template-node-file") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * Get the path of the file displayed by this node, relative to the root of the vault, from the `path` attribute. * @returns {string} The path. diff --git a/src/elements/canvas/node/group.css b/src/elements/canvas/node/group.css new file mode 100644 index 0000000..254b645 --- /dev/null +++ b/src/elements/canvas/node/group.css @@ -0,0 +1,17 @@ +.node-group-label { + position: relative; + bottom: 14px; + left: -12px; + transform: translateY(-100%); + + display: inline-block; + + outline: var(--node-group-border-width) solid var(--color-node); + background-color: color-mix(in srgb, var(--color-node) 20%, var(--color-background)); + border-radius: 8px 8px 0 0; + padding: 12px; +} + +.node-group-label-title { + margin: 0; +} diff --git a/src/elements/canvas/node/group.mjs b/src/elements/canvas/node/group.mjs index bec40ae..6c72ee8 100644 --- a/src/elements/canvas/node/group.mjs +++ b/src/elements/canvas/node/group.mjs @@ -10,6 +10,10 @@ export class NodeGroupElement extends NodeElement { return document.getElementById("template-node-group") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * The label text of the group. * Obtained from the `label` attribute of the element. diff --git a/src/elements/canvas/node/text.css b/src/elements/canvas/node/text.css new file mode 100644 index 0000000..7b949f6 --- /dev/null +++ b/src/elements/canvas/node/text.css @@ -0,0 +1,4 @@ +.node-text { + overflow-x: clip; + overflow-y: scroll; +} diff --git a/src/elements/canvas/node/text.mjs b/src/elements/canvas/node/text.mjs index 6e7ec1d..03ea7e2 100644 --- a/src/elements/canvas/node/text.mjs +++ b/src/elements/canvas/node/text.mjs @@ -9,6 +9,10 @@ export class NodeTextElement extends NodeElement { return document.getElementById("template-node-text") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * Get the Markdown source of this node from the `document` attribute. */ diff --git a/src/elements/markdown/frontmatter.css b/src/elements/markdown/frontmatter.css new file mode 100644 index 0000000..fe507ca --- /dev/null +++ b/src/elements/markdown/frontmatter.css @@ -0,0 +1,3 @@ +.frontmatter { + opacity: 50%; +} diff --git a/src/elements/markdown/frontmatter.mjs b/src/elements/markdown/frontmatter.mjs index a205c0f..3d06bec 100644 --- a/src/elements/markdown/frontmatter.mjs +++ b/src/elements/markdown/frontmatter.mjs @@ -9,6 +9,10 @@ export class FrontMatterElement extends CustomElement { return document.getElementById("template-frontmatter") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * The programming language used to define this front matter, obtained from the `lang` attribute. * @type {string} diff --git a/src/elements/markdown/hashtag.css b/src/elements/markdown/hashtag.css new file mode 100644 index 0000000..4472906 --- /dev/null +++ b/src/elements/markdown/hashtag.css @@ -0,0 +1,4 @@ +.hashtag { + background-color: color-mix(in srgb, var(--color-accent) 20%, transparent); + color: var(--color-accent); +} diff --git a/src/elements/markdown/hashtag.mjs b/src/elements/markdown/hashtag.mjs index b8ddf6b..f5b3b1a 100644 --- a/src/elements/markdown/hashtag.mjs +++ b/src/elements/markdown/hashtag.mjs @@ -9,6 +9,10 @@ export class HashtagElement extends CustomElement { return document.getElementById("template-hashtag") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * The name of the hashtag, with no leading hash, obtained from the `tag` attribute. * @returns {string} diff --git a/src/elements/markdown/renderer.css b/src/elements/markdown/renderer.css new file mode 100644 index 0000000..b72bc8a --- /dev/null +++ b/src/elements/markdown/renderer.css @@ -0,0 +1,3 @@ +.markdown { + +} diff --git a/src/elements/markdown/renderer.mjs b/src/elements/markdown/renderer.mjs index 450201b..95ce3b4 100644 --- a/src/elements/markdown/renderer.mjs +++ b/src/elements/markdown/renderer.mjs @@ -10,6 +10,10 @@ export class MarkdownElement extends CustomElement { return document.getElementById("template-markdown") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * {@link Marked} Markdown renderer. * @type {Marked} diff --git a/src/elements/markdown/wikilink.css b/src/elements/markdown/wikilink.css new file mode 100644 index 0000000..96ceb78 --- /dev/null +++ b/src/elements/markdown/wikilink.css @@ -0,0 +1,5 @@ +.wikilink { + color: var(--color-accent); + text-decoration: underline 1px solid currentColor; + cursor: pointer; +} diff --git a/src/elements/markdown/wikilink.mjs b/src/elements/markdown/wikilink.mjs index 47d9659..1d9d057 100644 --- a/src/elements/markdown/wikilink.mjs +++ b/src/elements/markdown/wikilink.mjs @@ -14,6 +14,10 @@ export class WikilinkElement extends CustomElement { return document.getElementById("template-wikilink") } + static createStyleSheets() { + return [...super.createStyleSheets(), this.makeModuleLikeStyleSheet(import.meta.url)] + } + /** * Element displaying the this one. * Can be recalculated with {@link recalculateAncestors}. diff --git a/src/elements/vault.css b/src/elements/vault.css new file mode 100644 index 0000000..a87afd1 --- /dev/null +++ b/src/elements/vault.css @@ -0,0 +1,4 @@ +.vault { + margin-left: 64px; + margin-right: 64px; +}