|
16 | 16 |
|
17 | 17 | const sel = document.querySelector.bind(document);
|
18 | 18 | const selAll = document.querySelectorAll.bind(document);
|
19 |
| - const selIn = (el, selector) => el.querySelector(selector); |
20 |
| - const dom = (tag, attrs, ...children) => { |
| 19 | + const selIn = (el: Element, selector: string) => el.querySelector(selector); |
| 20 | + const dom = ( |
| 21 | + tag: string, |
| 22 | + attrs: Record<string, string>, |
| 23 | + ...children: Array<HTMLElement | string> |
| 24 | + ) => { |
21 | 25 | const el = document.createElement(tag);
|
22 | 26 | if (attrs)
|
23 | 27 | Object.keys(attrs).forEach((attr) => el.setAttribute(attr, attrs[attr]));
|
|
32 | 36 | let i = 0;
|
33 | 37 | return () => i++;
|
34 | 38 | };
|
35 |
| - const flatten = (list) => |
| 39 | + const flatten = <T>(list: T[]) => |
36 | 40 | list.reduce(
|
37 | 41 | (r, item) =>
|
38 | 42 | Array.isArray(item) ? r.concat(flatten(item)) : r.concat([item]),
|
|
102 | 106 | const updateForm = () => {
|
103 | 107 | // Get values.
|
104 | 108 |
|
105 |
| - const values = Array.from(table.querySelectorAll("tr")).reduce( |
106 |
| - (r, el) => { |
107 |
| - const label = selIn(el, "th").textContent.trim(); |
108 |
| - const value = selIn(el, "td").textContent.trim(); |
| 109 | + type Track = { |
| 110 | + title: string; |
| 111 | + length: string; |
| 112 | + }; |
| 113 | + |
| 114 | + type Values = { |
| 115 | + artist?: string; |
| 116 | + title?: string; |
| 117 | + label?: string; |
| 118 | + cat?: string; |
| 119 | + barcode?: string; |
| 120 | + date?: string[]; |
| 121 | + tracks?: Track[]; |
| 122 | + }; |
| 123 | + |
| 124 | + const values = Array.from(table?.querySelectorAll("tr") ?? []).reduce( |
| 125 | + (r: Values, el) => { |
| 126 | + const label = selIn(el, "th")?.textContent?.trim() ?? ""; |
| 127 | + const value = selIn(el, "td")?.textContent?.trim() ?? ""; |
109 | 128 | console.log({ el, label, value });
|
110 | 129 | if (/表演者/.test(label)) r.artist = value;
|
111 | 130 | else if (/樂團名稱/.test(label)) r.artist = value;
|
|
119 | 138 | {}
|
120 | 139 | );
|
121 | 140 |
|
122 |
| - values.tracks = Array.from(songsTable.querySelectorAll("tr")).map( |
123 |
| - (el) => { |
124 |
| - const [hours, minutes, seconds] = el |
125 |
| - .querySelector("td.text-right") |
126 |
| - .textContent.trim() |
127 |
| - .split(".") |
128 |
| - .map(Number); |
129 |
| - const paddedSeconds = seconds.toString().padStart(2, "0"); |
| 141 | + values.tracks = Array.from(songsTable?.querySelectorAll("tr") ?? []).map( |
| 142 | + (el): Track => { |
| 143 | + const [hours, minutes, seconds] = |
| 144 | + el |
| 145 | + .querySelector("td.text-right") |
| 146 | + ?.textContent?.trim() |
| 147 | + .split(".") |
| 148 | + .map(Number) ?? []; |
| 149 | + const paddedSeconds = seconds?.toString().padStart(2, "0"); |
130 | 150 | return {
|
131 |
| - title: el |
132 |
| - .querySelector("a") |
133 |
| - .textContent.trim() |
134 |
| - .replace(/^\[\S+\] \d+[.](.*)$/, "$1"), |
135 |
| - length: `${hours * 60 + minutes}:${paddedSeconds}`, |
| 151 | + title: |
| 152 | + el |
| 153 | + .querySelector("a") |
| 154 | + ?.textContent?.trim() |
| 155 | + .replace(/^\[\S+\] \d+[.](.*)$/, "$1") ?? "", |
| 156 | + length: |
| 157 | + hours && minutes |
| 158 | + ? `${hours * 60 + minutes}:${paddedSeconds}` |
| 159 | + : "0:00", |
136 | 160 | };
|
137 | 161 | }
|
138 | 162 | );
|
|
160 | 184 | ];
|
161 | 185 |
|
162 | 186 | const trackCount = counter();
|
163 |
| - const trackInputs = flatten( |
164 |
| - values.tracks.map(({ title, length }) => { |
165 |
| - const i = trackCount(); |
166 |
| - return [ |
167 |
| - input(`mediums.0.track.${i}.name`, title), |
168 |
| - input(`mediums.0.track.${i}.length`, length), |
169 |
| - input(`mediums.0.track.${i}.number`, i + 1), |
170 |
| - ]; |
171 |
| - }) |
172 |
| - ); |
| 187 | + const trackInputs = values.tracks.flatMap(({ title, length }) => { |
| 188 | + const i = trackCount(); |
| 189 | + return [ |
| 190 | + input(`mediums.0.track.${i}.name`, title), |
| 191 | + input(`mediums.0.track.${i}.length`, length), |
| 192 | + input(`mediums.0.track.${i}.number`, i + 1), |
| 193 | + ]; |
| 194 | + }); |
173 | 195 |
|
174 | 196 | // Replace form contents with new data.
|
175 | 197 |
|
|
0 commit comments