-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
145 lines (145 loc) · 5.6 KB
/
index.js
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
let options = {
legacyMode: false,
};
/** Sets config options. Supply a name, and a value. Will apply to future calls for the function(s) */
export const setOption = (optionName, value) => {
options[optionName] = value;
};
/** Supply an entirely new options object. */
export const setOptions = (newOptions) => {
options = newOptions;
};
/**
* The `mk` function creates a new HTML element with specified attributes, children, and event
* listeners.
* @param {mkElement[]} children - The `children` parameter is a rest parameter that allows the
* function to accept an arbitrary number of arguments, each of which must be an instance of the
* `mkElement` type. These arguments represent the child elements that will be appended to the newly
* created `div` element.
* Note, if an attribute is supplied (from the `attribute` or `a` function), it will be applied to the **first** child.
* @returns The `mk` function returns an HTML element (`HTMLElement`).
*/
export const mk = (...children) => {
const div = !options.legacyMode ? document.createDocumentFragment() : document.createElement("div");
children.forEach(child => {
if (child instanceof HTMLElement || child instanceof Text) {
div.append(child);
}
else if (child instanceof Function) {
const evt = child();
div.addEventListener(evt.name, evt.callback, evt.options);
}
else {
for (const key in child) {
const val = child[key];
if (options.legacyMode && div instanceof HTMLElement) {
div.setAttribute(key, val);
}
else
div.children[0].setAttribute(key, val);
}
;
}
;
});
options.legacyMode && div instanceof HTMLElement && div.classList.add("micromarkup");
return div;
};
/**
* This is function creates and returns a new HTML element with specified tag name,
* attributes, and children.
* @param tagName - a string representing the HTML tag name of the element to be created
* @param {mkElement[]} children - an array of mkElement, which can be either HTMLElement, Text,
* event (function), or attributes
* @returns {mkElement} The function `n` returns an `mkElement`.
*/
export const n = (tagName, ...children) => {
const el = document.createElement(tagName);
children.forEach((child) => {
if (child instanceof HTMLElement || child instanceof Text) {
el.append(child);
}
else if (child instanceof Function) {
const evt = child();
el.addEventListener(evt.name, evt.callback);
}
else {
for (const key in child) {
const val = child[key];
if (key === "class") {
el.classList.add(val);
continue;
}
el.setAttribute(key, val);
}
;
}
;
});
return el;
};
/**
* The function "t" creates a new text node with the given string as its content.
* @param {string} text - The parameter "text" is a string that represents the text content that we
* want to create a Text node for.
* @returns {mkElement}
*/
export const t = (text) => {
return document.createTextNode(text);
};
/**
* The function takes in two string parameters and returns an object with a property named after the
* first parameter and a value of the second parameter.
* @param {string} name - The name parameter is a string that represents the name of a property.
* @param {string} value - The `value` parameter is a string type and represents the value that will be
* assigned to the property.
* @returns Returns the @see Prop , which can be used in `n`, `node`, `mk`, `microMarkup`.
*/
export const a = (name, value) => {
if (typeof name === "string") {
if (!value)
throw new Error("Micromarkup: Since you passed a string to the name parameter of the attribute function, the value must be defined. You did not define the value.");
return { [name]: value };
}
else if (name instanceof Object) {
let returnValue = {};
for (const key in name) {
returnValue = { ...returnValue, [key]: name[key] };
}
return returnValue;
}
else {
throw new TypeError(`Micromarkup: Invalid type for attribute function. Expected Type: string or object, type given: ${typeof name}`);
}
};
/**
* This function creates an event listener with a specified type, callback function, and
* options.
* @param {T} type - The type of event to listen for, which is a key of the `DocumentEventMap`
* interface.
* @param callback - The function that will be called when the event of type `T` is triggered. It takes
* an optional parameter `e` of type `DocumentEventMap[T]`, which represents the event object
* associated with the triggered event.
* @param {EventListenerOptions} [options] - `options` is an optional parameter of type
* `EventListenerOptions` that specifies options for the event listener.
* @returns A function for use in `n` or `node`.
*/
export const e = (type, callback, options) => {
//@ts-expect-error It works.
return () => {
return {
name: type,
callback,
options
};
};
};
// Aliases. I know that `import as` exists, but this is fewer lines of code at the end if using Micromarkup for larger projects.
export const event = e;
export const on = event;
export const node = n;
export const createNode = n;
export const attribute = a;
export const setAttribute = a;
export const text = t;
export const microMarkup = mk;