Skip to content
This repository has been archived by the owner on May 19, 2023. It is now read-only.

Commit

Permalink
feat: only render if value changed
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenybai committed Apr 23, 2021
1 parent 50eb142 commit e835cce
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 19 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 youit's really that simple.

```html
<div l-state="{ value: '', todo: [] }">
<!-- two-way-binds `value` prop to value -->
<!-- oninput: set `value` to input.value -->
<input l-model="value" />
<!-- captures click event, pushing current `value` to `todo` -->
<!-- onclick: add the current `value` to the `todo` array -->
<button @click="todo.push(value)">Create</button>
<!-- joins array together -->
<!-- joins `todo` array together -->
<ul l-for="task in todo">
<li l-text="this.task"></li>
</ul>
Expand All @@ -42,7 +42,7 @@ Below is an extremely simple implementation of a todo app using Lucia, utilizing

## Sponsors

<a href="https://hackclub.com/bank" target="_blank"><img width="30%" src="https://cdn.glitch.com/747f5921-6fdc-45db-8eaa-ac12523e0e6c%2Fhackclub-bank.svg?v=1566159701206" alt="Hack Club Bank"></a>
<a href="https://hackclub.com/bank" target="_blank"><img height="60" src="https://cdn.glitch.com/747f5921-6fdc-45db-8eaa-ac12523e0e6c%2Fhackclub-bank.svg?v=1566159701206" alt="Hack Club Bank"></a>

**Want your logo here? [→ Sponsor Lucia](https://bank.hackclub.com/donations/start/lucia)**

Expand Down
4 changes: 2 additions & 2 deletions docs/codebase/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<script src="./dist/lucia.dev.js"></script>
</head>
Expand Down
2 changes: 1 addition & 1 deletion scripts/dev.sh
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions src/core/directives/bind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
});
Expand All @@ -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;
}
Expand Down
14 changes: 8 additions & 6 deletions src/core/directives/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
};
3 changes: 2 additions & 1 deletion src/core/directives/show.ts
Original file line number Diff line number Diff line change
@@ -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');
};
5 changes: 4 additions & 1 deletion src/core/directives/text.ts
Original file line number Diff line number Diff line change
@@ -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;
}
};

0 comments on commit e835cce

Please sign in to comment.