diff --git a/README.md b/README.md index 349360f..b026173 100644 --- a/README.md +++ b/README.md @@ -23,15 +23,15 @@ It also integrates well with module bundlers like [Webpack](https://webpack.js.o ## Todo App Example -Below is an extremely simple implementation of a todo app using Lucia, utilizing zero JavaScript. Tasks can be added by submitting the form with the input. No, your eyes aren't fooling you - it's really that simple. +Below is an extremely simple implementation of a todo app using Lucia, utilizing zero JavaScript. Tasks can be added by submitting the form with the input. No, your eyes aren't fooling you—it's really that simple. ```html
- + - + - + @@ -42,7 +42,7 @@ Below is an extremely simple implementation of a todo app using Lucia, utilizing ## Sponsors -Hack Club Bank +Hack Club Bank **Want your logo here? [→ Sponsor Lucia](https://bank.hackclub.com/donations/start/lucia)** diff --git a/docs/codebase/WORKFLOW.md b/docs/codebase/WORKFLOW.md index 9bc8977..9660bf2 100644 --- a/docs/codebase/WORKFLOW.md +++ b/docs/codebase/WORKFLOW.md @@ -14,13 +14,13 @@ Lucia is written in [TypeScript](https://www.typescriptlang.org) and should be r ### Iterating -You can create a `*.html` (e.g. `test.html`) file at root to test changes in realtime. We recommend using `live-server` to hot-reload the webpage on change, and edit as necessary. +You can create a `*.html` (e.g. `test.html`) file at root to test changes in realtime. We recommend using [`live-server`](https://www.npmjs.com/package/live-server) to hot-reload the webpage on change, and edit as necessary. Below is a sample for a Lucia starter: ```html - + diff --git a/scripts/dev.sh b/scripts/dev.sh index 7b9d27d..77a871a 100644 --- a/scripts/dev.sh +++ b/scripts/dev.sh @@ -1 +1 @@ -esbuild src/browser.ts --bundle --watch --sourcemap --outfile=dist/lucia.js +esbuild src/browser.ts --bundle --watch --sourcemap --outfile=dist/lucia.dev.js diff --git a/src/core/directives/bind.ts b/src/core/directives/bind.ts index d168c66..b18fe6f 100644 --- a/src/core/directives/bind.ts +++ b/src/core/directives/bind.ts @@ -38,7 +38,7 @@ export const bindDirective = ({ el, parts, data, state }: DirectiveProps): void return el.setAttribute('class', formatAcceptableWhitespace(rawClasses)); } else if (el.hasAttribute('class')) { /* istanbul ignore next */ - return el.removeAttribute('class'); + if (el.hasAttribute('class')) return el.removeAttribute('class'); } } break; @@ -47,7 +47,7 @@ export const bindDirective = ({ el, parts, data, state }: DirectiveProps): void case 'style': { // Accept object and set properties based on boolean state value const styles = data.compute(state); - el.removeAttribute('style'); + if (el.hasAttribute('style')) el.removeAttribute('style'); Object.entries(styles).forEach(([styleName, styleValue]) => { el.style[styleName] = styleValue; }); @@ -70,7 +70,7 @@ export const bindDirective = ({ el, parts, data, state }: DirectiveProps): void } else if (attributes) { el.setAttribute(parts[1], attributes); } else { - el.removeAttribute(parts[1]); + if (el.hasAttribute(parts[1])) el.removeAttribute(parts[1]); } break; } diff --git a/src/core/directives/html.ts b/src/core/directives/html.ts index 6b4c020..b9dc2ff 100644 --- a/src/core/directives/html.ts +++ b/src/core/directives/html.ts @@ -9,15 +9,17 @@ import { getElementCustomProp, setElementCustomProp } from '../utils/elementCust export const htmlDirective = ({ el, data, state, node }: DirectiveProps): void => { node = node!; const marker = getElementCustomProp(el, COMPONENT_FLAG); + const ret = data.compute(state) ?? data.value; - // Handle naked prop in expression case - el.innerHTML = data.compute(state) ?? data.value; + if (ret !== el.innerHTML) { + el.innerHTML = ret; - const ast = compile(el, state, true); + const ast = compile(el, state, true); - if (!marker) adjustDeps(ast, data.deps, node, 'html'); + if (!marker) adjustDeps(ast, data.deps, node, 'html'); - render(ast, directives, state, data.deps); + render(ast, directives, state, data.deps); - setElementCustomProp(el, COMPONENT_FLAG, true); + setElementCustomProp(el, COMPONENT_FLAG, true); + } }; diff --git a/src/core/directives/show.ts b/src/core/directives/show.ts index e31a123..19ef8ff 100644 --- a/src/core/directives/show.ts +++ b/src/core/directives/show.ts @@ -1,6 +1,7 @@ import { DirectiveProps } from '../../models/structs'; export const showDirective = ({ el, data, state }: DirectiveProps): void => { - el.style.display = data.compute(state) ? '' : 'none'; + const ret = data.compute(state); + if (ret !== el.style.display) el.style.display = ret ? '' : 'none'; if (el.style.length === 0) el.removeAttribute('style'); }; diff --git a/src/core/directives/text.ts b/src/core/directives/text.ts index c7d1675..bdfbf43 100644 --- a/src/core/directives/text.ts +++ b/src/core/directives/text.ts @@ -1,5 +1,8 @@ import { DirectiveProps } from '../../models/structs'; export const textDirective = ({ el, data, state }: DirectiveProps): void => { - el.textContent = data.compute(state) ?? data.value; + const ret = data.compute(state) ?? data.value; + if (ret !== el.textContent) { + el.textContent = ret; + } };