|
1 |
| -export function updateDomProperties(dom, prevProps, nextProps) { |
2 |
| - const isEvent = name => name.startsWith("on"); |
3 |
| - const isAttribute = name => !isEvent(name) && name != "children"; |
| 1 | +import { TEXT_ELEMENT } from "./element"; |
| 2 | + |
| 3 | +const isEvent = name => name.startsWith("on"); |
| 4 | +const isAttribute = name => |
| 5 | + !isEvent(name) && name != "children" && name != "style"; |
| 6 | +const isNew = (prev, next) => key => prev[key] !== next[key]; |
| 7 | +const isGone = (prev, next) => key => !(key in next); |
4 | 8 |
|
| 9 | +export function updateDomProperties(dom, prevProps, nextProps) { |
5 | 10 | // Remove event listeners
|
6 |
| - Object.keys(prevProps).filter(isEvent).forEach(name => { |
7 |
| - const eventType = name.toLowerCase().substring(2); |
8 |
| - dom.removeEventListener(eventType, prevProps[name]); |
9 |
| - }); |
| 11 | + Object.keys(prevProps) |
| 12 | + .filter(isEvent) |
| 13 | + .filter(key => !(key in nextProps) || isNew(prevProps, nextProps)(key)) |
| 14 | + .forEach(name => { |
| 15 | + const eventType = name.toLowerCase().substring(2); |
| 16 | + dom.removeEventListener(eventType, prevProps[name]); |
| 17 | + }); |
10 | 18 |
|
11 | 19 | // Remove attributes
|
12 |
| - Object.keys(prevProps).filter(isAttribute).forEach(name => { |
13 |
| - dom[name] = null; |
14 |
| - }); |
| 20 | + Object.keys(prevProps) |
| 21 | + .filter(isAttribute) |
| 22 | + .filter(isGone(prevProps, nextProps)) |
| 23 | + .forEach(name => { |
| 24 | + dom[name] = null; |
| 25 | + }); |
15 | 26 |
|
16 | 27 | // Set attributes
|
17 |
| - Object.keys(nextProps).filter(isAttribute).forEach(name => { |
18 |
| - dom[name] = nextProps[name]; |
19 |
| - }); |
| 28 | + Object.keys(nextProps) |
| 29 | + .filter(isAttribute) |
| 30 | + .filter(isNew(prevProps, nextProps)) |
| 31 | + .forEach(name => { |
| 32 | + dom[name] = nextProps[name]; |
| 33 | + }); |
| 34 | + |
| 35 | + // Set style |
| 36 | + prevProps.style = prevProps.style || {}; |
| 37 | + nextProps.style = nextProps.style || {}; |
| 38 | + Object.keys(nextProps.style) |
| 39 | + .filter(isNew(prevProps.style, nextProps.style)) |
| 40 | + .forEach(key => { |
| 41 | + dom.style[key] = nextProps.style[key]; |
| 42 | + }); |
| 43 | + Object.keys(prevProps.style) |
| 44 | + .filter(isGone(prevProps.style, nextProps.style)) |
| 45 | + .forEach(key => { |
| 46 | + dom.style[key] = ""; |
| 47 | + }); |
20 | 48 |
|
21 | 49 | // Add event listeners
|
22 |
| - Object.keys(nextProps).filter(isEvent).forEach(name => { |
23 |
| - const eventType = name.toLowerCase().substring(2); |
24 |
| - dom.addEventListener(eventType, nextProps[name]); |
25 |
| - }); |
| 50 | + Object.keys(nextProps) |
| 51 | + .filter(isEvent) |
| 52 | + .filter(isNew(prevProps, nextProps)) |
| 53 | + .forEach(name => { |
| 54 | + const eventType = name.toLowerCase().substring(2); |
| 55 | + dom.addEventListener(eventType, nextProps[name]); |
| 56 | + }); |
| 57 | +} |
| 58 | + |
| 59 | +export function createDomElement(fiber) { |
| 60 | + const isTextElement = fiber.type === TEXT_ELEMENT; |
| 61 | + const dom = isTextElement |
| 62 | + ? document.createTextNode("") |
| 63 | + : document.createElement(fiber.type); |
| 64 | + updateDomProperties(dom, [], fiber.props); |
| 65 | + return dom; |
26 | 66 | }
|
0 commit comments