-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.js
More file actions
124 lines (110 loc) · 2.86 KB
/
index.js
File metadata and controls
124 lines (110 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// @ts-check
import {
isPair,
car,
cdr,
cons,
} from '@hexlet/pairs';
import * as data from '@hexlet/pairs-data';
/**
* Make a list of nodes
* @example
* make(node('span', 'hello'), node('span', 'world'));
*/
export const make = (...elements) => data.reverse(data.l(...elements));
/**
* Append node to a list of nodes
* @example
* const dom = make();
* append(dom, node('h2', 'hello, world'));
*
*/
export const append = (dom, element) => data.cons(element, dom);
/**
* Make a node
* @example
* node('h2', 'hello, world');
* node('div', l(node('p', 'one'), node('p', 'two')));
*/
export const node = (tag, mix = data.l()) => cons(tag, mix);
/**
* Get node's name
* @example
* getName(node('p', 'hello, world')); // p
*/
export const getName = (element) => car(element);
/**
* Get node's value
* @example
* getValue(node('p', 'hello, world')); // hello, world
*/
export const getValue = (element) => cdr(element);
/**
* Check if node is tag
* @example
* is('h3', node('h3', 'hexlet')); // true
* is('h3', node('h6', 'hexlet')); // false
*/
export const is = (tagName, element) => tagName === getName(element);
/**
* Check if node has children
* @example
* hasChildren(node('h3', 'hexlet')); // false
* hasChildren(node('div', l(node('p', 'wow')))); // true
*/
export const hasChildren = (element) => isPair(cdr(element));
/**
* Get node's children
* @example
* const children = l(node('p', 'wow'), node('p', 'hey'));
* children(node('div', children)); // [('p', 'wow'), ('p', 'hey')]
*/
export const children = (element) => cdr(element);
/**
* Add child to node
* @example
* const node = node('div');
* addChild(node, node('p', 'html tags'));
*/
export const addChild = (element, child) => data.cons(
getName(element),
data.cons(child, children(element)),
);
/**
* Convert list of nodes to string
* @example
* const tags = make(node('p', 'text'), node('p', 'text2'));
* toString(tags); // <p>text</p><p>text2</p>
*/
export const toString = (elements) => {
if (data.isEmpty(elements)) {
return '';
}
const element = data.head(elements);
const tag = getName(element);
const body = hasChildren(element) ? toString(children(element)) : getValue(element);
return `${toString(data.tail(elements))}<${tag}>${body}</${tag}>`;
};
/**
* Map a list of nodes
* @example
* map(element => {
* if (is('h2', element)) {
* return node('h3', getValue(element));
* }
* return element;
* }, dom);
*/
export const map = (callbackFn, elements) => data.map(callbackFn, elements);
/**
* Filter a list of nodes
* @example
* filter(element => is('h2', element), dom);
*/
export const filter = (callbackFn, elements) => data.filter(callbackFn, elements);
/**
* Reduce a list of nodes
* @example
* reduce((element, acc) => acc + 1, 0, dom);
*/
export const reduce = (callbackFn, init, elements) => data.reduce(callbackFn, init, elements);