:adhesive_bandage: anchor html events first render · nullstack/nullstack@5166022 · GitHub
Skip to content

Commit 5166022

Browse files
committed
🩹 anchor html events first render
1 parent 8777337 commit 5166022

6 files changed

Lines changed: 82 additions & 32 deletions

File tree

client/anchorableNode.js

Lines changed: 8 additions & 5 deletions

client/render.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,62 @@
1-
import {isFalse, isText} from '../shared/nodes';
2-
import {anchorableElement} from './anchorableNode';
1+
import { isFalse, isText } from '../shared/nodes';
2+
import { anchorableElement } from './anchorableNode';
33

44
export default function render(node, options) {
55

6-
if(isFalse(node) || node.type === 'head') {
6+
if (isFalse(node) || node.type === 'head') {
77
return document.createComment("");
88
}
99

10-
if(isText(node)) {
10+
if (isText(node)) {
1111
return document.createTextNode(node);
1212
}
1313

1414
const svg = (options && options.svg) || node.type === 'svg';
1515

1616
let element;
17-
if(svg) {
17+
if (svg) {
1818
element = document.createElementNS("http://www.w3.org/2000/svg", node.type);
1919
} else {
2020
element = document.createElement(node.type);
2121
}
2222

23-
if(node.instance) {
23+
if (node.instance) {
2424
node.instance._self.element = element;
2525
}
2626

27-
for(let name in node.attributes) {
28-
if(name === 'html') {
27+
for (let name in node.attributes) {
28+
if (name === 'html') {
2929
element.innerHTML = node.attributes[name];
3030
anchorableElement(element);
31-
} else if(name.startsWith('on')) {
31+
} else if (name.startsWith('on')) {
3232
const eventName = name.replace('on', '');
3333
const key = '_event.' + eventName;
3434
node[key] = (event) => {
35-
if(node.attributes.default !== true) {
35+
if (node.attributes.default !== true) {
3636
event.preventDefault();
3737
}
38-
node.attributes[name]({...node.attributes, event});
38+
node.attributes[name]({ ...node.attributes, event });
3939
};
4040
element.addEventListener(eventName, node[key]);
4141
} else {
42-
const type = typeof(node.attributes[name]);
43-
if(type !== 'object' && type !== 'function') {
44-
if(name != 'value' && node.attributes[name] === true) {
42+
const type = typeof (node.attributes[name]);
43+
if (type !== 'object' && type !== 'function') {
44+
if (name != 'value' && node.attributes[name] === true) {
4545
element.setAttribute(name, '');
46-
} else if(name == 'value' || (node.attributes[name] !== false && node.attributes[name] !== null && node.attributes[name] !== undefined)) {
46+
} else if (name == 'value' || (node.attributes[name] !== false && node.attributes[name] !== null && node.attributes[name] !== undefined)) {
4747
element.setAttribute(name, node.attributes[name]);
4848
}
4949
}
5050
}
5151
}
5252

53-
if(!node.attributes.html) {
54-
for(let i = 0; i < node.children.length; i++) {
55-
const child = render(node.children[i], {svg});
53+
if (!node.attributes.html) {
54+
for (let i = 0; i < node.children.length; i++) {
55+
const child = render(node.children[i], { svg });
5656
element.appendChild(child);
5757
}
58-
59-
if(node.type == 'select') {
58+
59+
if (node.type == 'select') {
6060
element.value = node.attributes.value;
6161
}
6262
}

client/rerender.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ export default function rerender(selector, current, next) {
6060
if (name === 'html') {
6161
if (next.attributes[name] !== current.attributes[name]) {
6262
selector.innerHTML = next.attributes[name];
63-
anchorableElement(selector);
6463
}
64+
anchorableElement(selector);
6565
} else if (name === 'checked') {
6666
if (next.attributes[name] !== selector.value) {
6767
selector.checked = next.attributes[name];

plugins/anchorable.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ function transform({ node, router }) {
1313
const originalEvent = node.attributes.onclick
1414
node.attributes.default = true
1515
node.attributes.onclick = ({ event }) => {
16-
if (event.ctrlKey || event.shiftKey) return
17-
event.preventDefault()
18-
router.url = node.attributes.href
16+
if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
17+
event.preventDefault()
18+
router.url = node.attributes.href
19+
}
1920
if (originalEvent) {
2021
setTimeout(() => {
2122
originalEvent({ ...node.attributes, event })

tests/src/AnchorModifiers.njs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,23 @@ class AnchorModifiers extends Nullstack {
66
<a href="/anchor-modifiers?source=html">html</a>
77
`
88

9-
render() {
9+
hydrate(context) {
10+
context.self.element.querySelector('a').addEventListener('click', () => {
11+
context.clickedHTML = true
12+
})
13+
}
14+
15+
clickJSX(context) {
16+
context.clickedJSX = true
17+
}
18+
19+
render({ clickedJSX, clickedHTML }) {
1020
return (
11-
<div>
21+
<div data-clicked-jsx={clickedJSX} data-clicked-html={clickedHTML}>
1222
<div html={this.html} />
13-
<a href="/anchor-modifiers?source=jsx">jsx</a>
23+
<a href="/anchor-modifiers?source=jsx" onclick={this.clickJSX}>
24+
jsx
25+
</a>
1426
</div>
1527
)
1628
}

tests/src/AnchorModifiers.test.js

Lines changed: 34 additions & 0 deletions

0 commit comments

Comments
 (0)