drab 6.1.0 → 6.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -47,7 +47,7 @@ export type ContentElement = {
47
47
  */
48
48
  export declare class Editor extends Base {
49
49
  #private;
50
- /** The characters that will be automatically closed when typed. */
50
+ /** Characters that will be automatically closed when typed. */
51
51
  keyPairs: {
52
52
  [key: string]: string;
53
53
  };
@@ -29,9 +29,11 @@ import { Base } from "../base/index.js";
29
29
  * - When text is highlighted and a `wrap` character `keyPair` is typed, the highlighted text will be wrapped with the character instead of removing it. For example, if a word is highlighted and the `"` character is typed, the work will be surrounded by `"`s.
30
30
  */
31
31
  export class Editor extends Base {
32
- /** Array of keyPair characters that have been opened. */
32
+ /** Array of `keyPair` characters that have been opened. */
33
33
  #openChars = [];
34
- /** The characters that will be automatically closed when typed. */
34
+ /** Keys that will reset the type over for keyPairs */
35
+ #resetKeys = new Set(["ArrowUp", "ArrowDown", "Delete"]);
36
+ /** Characters that will be automatically closed when typed. */
35
37
  keyPairs = {
36
38
  "(": ")",
37
39
  "{": "}",
@@ -44,9 +46,8 @@ export class Editor extends Base {
44
46
  super();
45
47
  // add any `type: "wrap"` values from `contentElements` to `keyPairs`
46
48
  for (const element of this.#contentElements) {
47
- if (element.type === "wrap") {
49
+ if (element.type === "wrap")
48
50
  this.keyPairs[element.value] = element.value;
49
- }
50
51
  }
51
52
  }
52
53
  /** The `content`, expects an `HTMLTextAreaElement`. */
@@ -60,221 +61,150 @@ export class Editor extends Base {
60
61
  set text(value) {
61
62
  this.textArea.value = value;
62
63
  }
63
- /** An array of `ContentElement`s derived from each `trigger`'s data attributes. */
64
+ /** Array of `ContentElement`s derived from each `trigger`'s data attributes. */
64
65
  get #contentElements() {
65
66
  const contentElements = [];
66
67
  for (const trigger of this.getTrigger()) {
67
- contentElements.push(this.#getContentElement(trigger));
68
+ contentElements.push(trigger.dataset);
68
69
  }
69
70
  return contentElements;
70
71
  }
71
- /**
72
- * - splits the content by "```" and finds the current index
73
- * of the selectionStart
74
- *
75
- * @returns current codeblock (index) of selectionStart
76
- */
77
- get #currentBlock() {
78
- const blocks = this.text.split("```");
79
- let totalChars = 0;
80
- for (const [i, block] of blocks.entries()) {
81
- totalChars += block.length + 3;
82
- if (this.#selectionStart < totalChars) {
83
- return i;
84
- }
85
- }
86
- return 0;
87
- }
88
72
  /** Gets the end position of the selection */
89
- get #selectionEnd() {
73
+ get #selEnd() {
90
74
  return this.textArea.selectionEnd;
91
75
  }
92
76
  /** Gets the start position of the selection. */
93
- get #selectionStart() {
77
+ get #selStart() {
94
78
  return this.textArea.selectionStart;
95
79
  }
96
- /** Sets the current cursor selection in the `textarea` */
97
- #setSelectionRange(start, end) {
98
- this.textArea.setSelectionRange(start, end);
80
+ /**
81
+ * @param str string to insert into `text`
82
+ * @param index where to insert the string
83
+ */
84
+ #insertStr(str, index) {
85
+ this.text = this.text.slice(0, index) + str + this.text.slice(index);
99
86
  }
100
87
  /**
101
- * @param trigger The trigger html element.
102
- * @returns The ContentElement based on the `trigger`'s attributes.
88
+ * @param start Starting index for removal.
89
+ * @param end Optional ending index - defaults to start + 1 to remove 1 character.
103
90
  */
104
- #getContentElement(trigger) {
105
- const type = trigger.dataset.type;
106
- const value = trigger.dataset.value;
107
- const key = trigger.dataset.key ?? undefined;
108
- return { type, value, key };
91
+ #removeStr(start, end = start + 1) {
92
+ this.text = this.text.slice(0, start) + this.text.slice(end);
93
+ }
94
+ /** Sets the current cursor selection in the `textarea` */
95
+ #setSelection(start, end = start) {
96
+ this.textArea.setSelectionRange(start, end);
97
+ this.textArea.focus();
109
98
  }
110
99
  /**
111
- * - Inserts text into the `textarea` based on the `display` property of
112
- * the `ContentElement`.
100
+ * Inserts text and sets selection based on the `ContentElement` selected.
113
101
  *
114
- * @param el the content element
115
- * @param selectionStart current start position the selection
116
- * @param selectionEnd current end position of the selection
102
+ * @param content
117
103
  */
118
- async #insertText(el, selectionStart, selectionEnd) {
119
- if (el.type === "inline") {
104
+ #addContent({ value, type }) {
105
+ let start = this.#selStart;
106
+ if (type === "inline") {
120
107
  // insert at current position
121
- this.text = `${this.text.slice(0, selectionEnd)}${el.value}${this.text.slice(selectionEnd)}`;
108
+ this.#insertStr(value, start);
109
+ const match = /[a-z]+/i.exec(value);
110
+ if (match?.index != null) {
111
+ start += match.index;
112
+ this.#setSelection(start, start + match[0].length);
113
+ }
114
+ else {
115
+ this.#setSelection(start + value.length);
116
+ }
122
117
  }
123
- else if (el.type === "wrap") {
124
- this.text = insertChar(this.text, el.value, selectionStart);
125
- this.text = insertChar(this.text, this.keyPairs[el.value], selectionEnd + el.value.length);
118
+ else if (type === "wrap") {
119
+ const end = this.#selEnd + value.length;
120
+ this.#insertStr(value, start);
121
+ this.#insertStr(this.keyPairs[value], end);
122
+ this.#setSelection(start + value.length, end);
126
123
  // if single char, add to opened
127
- if (el.value.length < 2)
128
- this.#openChars.push(el.value);
124
+ if (value.length === 1)
125
+ this.#openChars.push(value);
129
126
  }
130
- else if (el.type === "block") {
131
- const { lines, lineNumber } = this.#getLineInfo();
132
- const firstChar = el.value.at(0);
133
- // add the string to the beginning of the line
127
+ else {
128
+ // "block"
129
+ const { lines, lineNumber } = this.#lineMeta();
130
+ // avoids `# # # `, instead adds trimmed => `### `
131
+ const firstChar = value[0];
134
132
  if (firstChar && lines[lineNumber]?.startsWith(firstChar)) {
135
- // avoids `# # # `, instead adds trimmed => `### `
136
- lines[lineNumber] = el.value.trim() + lines[lineNumber];
137
- }
138
- else {
139
- lines[lineNumber] = el.value + lines[lineNumber];
133
+ value = value.trim();
140
134
  }
135
+ // add the string to the beginning of the line
136
+ lines[lineNumber] = value + lines[lineNumber];
141
137
  this.text = lines.join("\n");
138
+ this.#setSelection(start + value.length);
142
139
  }
143
140
  }
144
141
  /**
145
- * - Sets the caret position after text is inserted based on
146
- * the length of the text.
147
- * - Highlights text if the content contains any letters.
142
+ * Checks if there is a block element at the beginning of the string.
148
143
  *
149
- * @param text
150
- * @param selectionStart current start position the selection
151
- * @param selectionEnd current end position of the selection
144
+ * @param line
145
+ * @returns Whatever is found, otherwise null
152
146
  */
153
- async #setCaretPosition(text, selectionStart, selectionEnd) {
154
- let startPos = 0;
155
- let endPos = 0;
156
- if (/[a-z]/i.test(text)) {
157
- // if string contains letters, highlight the first word
158
- for (let i = selectionEnd; i < this.text.length; i++) {
159
- if (this.text[i]?.match(/[a-z]/i)) {
160
- if (!startPos) {
161
- startPos = i;
162
- }
163
- else {
164
- endPos = i + 1;
165
- }
166
- }
167
- else if (startPos) {
168
- break;
169
- }
170
- }
171
- }
172
- else {
173
- // leave the cursor in place
174
- startPos = selectionStart + text.length;
175
- endPos = selectionEnd + text.length;
147
+ #startsWithBlock(line) {
148
+ for (const blockString of this.#contentElements
149
+ .filter((el) => el.type === "block")
150
+ .map((el) => el.value)) {
151
+ if (line.startsWith(blockString))
152
+ return blockString;
176
153
  }
177
- this.#setSelectionRange(startPos, endPos);
178
- this.textArea.focus();
179
- }
180
- /**
181
- * - Inserts the text and then sets the caret position
182
- * based on the `ContentElement` selected.
183
- *
184
- * @param el selected content element
185
- */
186
- async #addContent(el) {
187
- const selectionEnd = this.#selectionEnd;
188
- const selectionStart = this.#selectionStart;
189
- await this.#insertText(el, selectionStart, selectionEnd);
190
- this.#setCaretPosition(el.value, selectionStart, selectionEnd);
154
+ return null;
191
155
  }
192
156
  /**
193
- * - checks if there is a block element or a number
194
- * at the beginning of the string
195
- *
196
- * @param str
197
- * @returns what is found, or the empty string
157
+ * @param line
158
+ * @returns The number, if the line starts with a number and a period.
198
159
  */
199
- #getRepeat(str) {
200
- if (str) {
201
- const blockStrings = [];
202
- this.#contentElements.forEach((el) => {
203
- if (el.type === "block")
204
- blockStrings.push(el.value);
205
- });
206
- for (let i = 0; i < blockStrings.length; i++) {
207
- const repeatString = blockStrings[i];
208
- if (repeatString && str.startsWith(repeatString)) {
209
- return repeatString;
210
- }
211
- }
212
- const repeatNum = startsWithNumberAndPeriod(str);
213
- if (repeatNum)
214
- return `${repeatNum}. `;
215
- }
216
- return "";
160
+ #startsWithNumberAndPeriod(line) {
161
+ const match = line.match(/^(\d+)\./);
162
+ return match ? Number(match[1]) : null;
217
163
  }
218
164
  /**
219
- * @returns lines as an array, current line number, current column number
220
- *
221
- * @example
222
- *
223
- * ```js
224
- * const { lines, lineNumber, columnNumber } = getLineInfo();
225
- * ```
165
+ * @returns Metadata describing the current position of the selection.
226
166
  */
227
- #getLineInfo() {
167
+ #lineMeta() {
228
168
  const lines = this.text.split("\n");
229
- let characterCount = 0;
230
- for (let i = 0; i < lines.length; i++) {
231
- const lineLength = lines.at(i)?.length ?? 0;
232
- // for each line
233
- characterCount++; // account for removed "\n" due to .split()
234
- characterCount += lineLength;
169
+ let charCount = 0;
170
+ for (let lineNumber = 0; lineNumber < lines.length; lineNumber++) {
171
+ const line = lines[lineNumber];
172
+ const len = line.length + 1; // account for removed "\n" due to .split()
173
+ charCount += len;
235
174
  // find the line that the cursor is on
236
- if (characterCount > this.#selectionEnd) {
175
+ if (charCount > this.#selEnd) {
237
176
  return {
177
+ line,
238
178
  lines,
239
- lineNumber: i,
240
- columnNumber: this.#selectionEnd - (characterCount - lineLength - 1),
179
+ lineNumber,
180
+ columnNumber: this.#selEnd - (charCount - len),
241
181
  };
242
182
  }
243
183
  }
244
- return { lines, lineNumber: 0, columnNumber: 0 };
184
+ return { line: lines[0], lines, lineNumber: 0, columnNumber: 0 };
245
185
  }
246
186
  /**
247
- * - Increments/decrements the start of following lines if they are numbers
187
+ * Increments/decrements the start of following lines if they are numbers.
248
188
  *
249
- * Prevents this:
189
+ * @param decrement if following lines should be decremented instead of incremented
250
190
  *
251
- * ```
252
- * 1. presses enter here when two items in list
253
- * 2.
254
- * 2.
255
- * ```
191
+ * @example
256
192
  *
257
- * Instead:
193
+ * ```md
194
+ * Prevents this, instead fixes the following lines.
258
195
  *
259
- * ```
260
- * 1.
196
+ * 1. presses enter here when two items in list
261
197
  * 2.
262
- * 3.
198
+ * 2. (repeat of 2)
263
199
  * ```
264
- *
265
- * @param currentLineNumber
266
- * @param decrement if following lines should be decremented instead of incremented
267
200
  */
268
- #correctFollowing(currentLineNumber, decrement = false) {
269
- const { lines } = this.#getLineInfo();
270
- for (let i = currentLineNumber + 1; i < lines.length; i++) {
271
- const line = lines[i];
201
+ #correctFollowing(decrement = false) {
202
+ let { lines, lineNumber } = this.#lineMeta();
203
+ for (; ++lineNumber < lines.length;) {
204
+ let line = lines[lineNumber];
272
205
  if (line) {
273
- const num = startsWithNumberAndPeriod(line);
274
- if (!num) {
275
- break;
276
- }
277
- else {
206
+ const num = this.#startsWithNumberAndPeriod(line);
207
+ if (num) {
278
208
  let newNum;
279
209
  if (decrement) {
280
210
  if (num > 1) {
@@ -287,194 +217,135 @@ export class Editor extends Base {
287
217
  else {
288
218
  newNum = num + 1;
289
219
  }
290
- lines[i] = line.slice(String(num).length); // remove number from start
291
- lines[i] = String(newNum) + lines[i];
220
+ lines[lineNumber] = String(newNum) + line.slice(String(num).length);
221
+ }
222
+ else {
223
+ break;
292
224
  }
293
225
  }
294
226
  }
227
+ const start = this.#selStart;
295
228
  this.text = lines.join("\n");
229
+ this.#setSelection(start);
296
230
  }
297
231
  mount() {
298
- this.textArea.addEventListener("keydown", async (e) => {
299
- // these keys will reset the type over for characters like "
300
- const resetKeys = ["ArrowUp", "ArrowDown", "Delete"];
301
- const nextChar = this.text[this.#selectionEnd] ?? "";
302
- if (resetKeys.includes(e.key)) {
303
- // reset
232
+ this.textArea.addEventListener("keydown", (e) => {
233
+ const nextChar = this.text[this.#selEnd] ?? "";
234
+ const notHighlighted = this.#selStart === this.#selEnd;
235
+ if (this.#resetKeys.has(e.key)) {
304
236
  this.#openChars = [];
305
237
  }
306
238
  else if (e.key === "Backspace") {
307
- const prevChar = this.text[this.#selectionStart - 1];
239
+ const prevChar = this.text[this.#selStart - 1];
308
240
  if (prevChar &&
309
241
  prevChar in this.keyPairs &&
310
242
  nextChar === this.keyPairs[prevChar]) {
311
243
  // remove both characters if the next one is the match of the prev
312
244
  e.preventDefault();
313
- const start = this.#selectionStart - 1;
314
- const end = this.#selectionEnd - 1;
315
- this.text = removeChar(this.text, start);
316
- this.text = removeChar(this.text, end);
317
- setTimeout(() => {
318
- this.#setSelectionRange(start, end);
319
- }, 0);
245
+ const start = this.#selStart - 1;
246
+ const end = this.#selEnd - 1;
247
+ this.#removeStr(start);
248
+ this.#removeStr(end);
249
+ this.#setSelection(start, end);
320
250
  this.#openChars.pop();
321
251
  }
322
- if (prevChar === "\n" && this.#selectionStart === this.#selectionEnd) {
323
- // see `correctFollowing`
252
+ else if (prevChar === "\n" && this.#selStart === this.#selEnd) {
324
253
  e.preventDefault();
325
- const newPos = this.#selectionStart - 1;
326
- const { lineNumber } = this.#getLineInfo();
327
- this.#correctFollowing(lineNumber, true);
328
- this.text = removeChar(this.text, newPos);
329
- setTimeout(async () => {
330
- this.#setSelectionRange(newPos, newPos);
331
- }, 0);
254
+ const newPos = this.#selStart - 1;
255
+ this.#correctFollowing(true);
256
+ this.#removeStr(newPos);
257
+ this.#setSelection(newPos, newPos);
332
258
  }
333
259
  }
334
260
  else if (e.key === "Tab") {
335
- if (this.#currentBlock % 2 !== 0) {
336
- // if caret is inside of a codeblock, indent
337
- e.preventDefault();
338
- await this.#addContent({
339
- type: "inline",
340
- value: "\t",
341
- });
261
+ const blocks = this.text.split("```");
262
+ let totalChars = 0;
263
+ for (const [i, block] of blocks.entries()) {
264
+ totalChars += block.length + 3;
265
+ if (totalChars > this.#selStart) {
266
+ // found
267
+ if (i % 2) {
268
+ // if caret is inside of a codeblock, indent
269
+ e.preventDefault();
270
+ this.#addContent({ type: "inline", value: "\t" });
271
+ }
272
+ break;
273
+ }
342
274
  }
275
+ // TODO add shift tab backwards
343
276
  }
344
- else if (e.key === "Enter") {
277
+ else if (e.key === "Enter" && notHighlighted) {
345
278
  // autocomplete start of next line if block or number
346
- const { lines, lineNumber, columnNumber } = this.#getLineInfo();
347
- const currentLine = lines.at(lineNumber);
348
- let repeat = this.#getRepeat(currentLine);
349
- const original = repeat;
350
- const num = startsWithNumberAndPeriod(repeat);
351
- // line starts with number and period? - increment
352
- if (num)
353
- repeat = `${num + 1}. `;
354
- if (repeat && original.length < columnNumber) {
355
- e.preventDefault();
279
+ const { line, columnNumber } = this.#lineMeta();
280
+ let repeat = this.#startsWithBlock(line);
281
+ if (!repeat) {
282
+ const num = this.#startsWithNumberAndPeriod(line);
356
283
  if (num)
357
- this.#correctFollowing(lineNumber);
358
- await this.#addContent({
359
- type: "inline",
360
- value: `\n${repeat}`,
361
- });
284
+ repeat = `${num + 1}. `;
362
285
  }
363
- else if (repeat && original.length === columnNumber) {
364
- // remove if the repeat and caret at the end of the original
286
+ if (repeat) {
365
287
  e.preventDefault();
366
- // have to set a placeholder since `this.#selectionEnd` will change
367
- // as characters are being removed
368
- const originalSelectionEnd = this.#selectionEnd;
369
- // go back the the length of the original
370
- const newPos = originalSelectionEnd - original.length;
371
- // for each character in the original
372
- for (let i = 0; i < original.length; i++) {
373
- this.text = removeChar(this.text, originalSelectionEnd - (i + 1));
288
+ if (repeat.length < columnNumber) {
289
+ // repeat same on next line
290
+ this.#addContent({ type: "inline", value: "\n" + repeat });
291
+ this.#correctFollowing();
374
292
  }
375
- setTimeout(async () => {
376
- this.#setSelectionRange(newPos, newPos);
377
- this.textArea.focus();
378
- await this.#addContent({
379
- type: "inline",
380
- value: `\n`,
381
- });
382
- }, 0);
383
- }
384
- }
385
- else {
386
- const nextCharIsClosing = Object.values(this.keyPairs).includes(nextChar);
387
- const highlighted = this.#selectionStart !== this.#selectionEnd;
388
- if (e.ctrlKey || e.metaKey) {
389
- if (this.#selectionStart === this.#selectionEnd) {
390
- // no selection
391
- if (e.key === "c" || e.key === "x") {
392
- // copy or cut entire line
393
- e.preventDefault();
394
- const { lines, lineNumber, columnNumber } = this.#getLineInfo();
395
- await navigator.clipboard.writeText(`${lineNumber === 0 && e.key === "x" ? "" : "\n"}${lines[lineNumber]}`);
396
- if (e.key === "x") {
397
- const newPos = this.#selectionStart - columnNumber;
398
- lines.splice(lineNumber, 1);
399
- this.text = lines.join("\n");
400
- setTimeout(() => {
401
- this.#setSelectionRange(newPos, newPos);
402
- }, 0);
403
- }
404
- }
293
+ else {
294
+ // remove repeat from current line
295
+ const end = this.#selEnd;
296
+ const newPos = end - repeat.length;
297
+ this.#removeStr(newPos, end);
298
+ this.#setSelection(newPos);
405
299
  }
406
300
  }
407
- if ((e.ctrlKey || e.metaKey) && e.key) {
408
- // keyboard shortcut
409
- const matchedEl = this.#contentElements.find((el) => el.key === e.key);
410
- if (matchedEl)
411
- this.#addContent(matchedEl);
412
- }
413
- else if (nextCharIsClosing &&
414
- (nextChar === e.key || e.key === "ArrowRight") &&
415
- this.#openChars.length &&
416
- !highlighted) {
417
- // type over the next character instead of inserting
418
- e.preventDefault();
419
- this.#setSelectionRange(this.#selectionStart + 1, this.#selectionEnd + 1);
420
- this.#openChars.pop();
421
- }
422
- else if (e.key in this.keyPairs) {
301
+ }
302
+ else if ((e.ctrlKey || e.metaKey) && e.key) {
303
+ if (notHighlighted && (e.key === "c" || e.key === "x")) {
304
+ // copy or cut entire line
423
305
  e.preventDefault();
424
- await this.#addContent({
425
- type: "wrap",
426
- value: e.key,
427
- });
428
- this.#openChars.push(e.key);
306
+ const { line, lines, lineNumber, columnNumber } = this.#lineMeta();
307
+ navigator.clipboard.writeText(line);
308
+ if (e.key === "x") {
309
+ const newPos = this.#selStart - columnNumber;
310
+ lines.splice(lineNumber, 1);
311
+ this.text = lines.join("\n");
312
+ this.#setSelection(newPos, newPos);
313
+ }
429
314
  }
315
+ const shortcut = this.#contentElements.find((el) => el.key === e.key);
316
+ if (shortcut)
317
+ this.#addContent(shortcut);
318
+ }
319
+ else if (this.#openChars.length &&
320
+ notHighlighted &&
321
+ (nextChar === e.key || e.key === "ArrowRight") &&
322
+ Object.values(this.keyPairs).includes(nextChar)) {
323
+ // type over the next character instead of inserting
324
+ e.preventDefault();
325
+ this.#setSelection(this.#selStart + 1, this.#selEnd + 1);
326
+ this.#openChars.pop();
327
+ }
328
+ else if (e.key in this.keyPairs) {
329
+ e.preventDefault();
330
+ this.#addContent({ type: "wrap", value: e.key });
331
+ this.#openChars.push(e.key);
430
332
  }
431
333
  });
432
334
  // trims the selection if there is an extra space around it
433
335
  this.textArea.addEventListener("dblclick", () => {
434
- if (this.#selectionStart !== this.#selectionEnd) {
435
- if (this.text[this.#selectionStart] === " ") {
436
- this.#setSelectionRange(this.#selectionStart + 1, this.#selectionEnd);
336
+ if (this.#selStart !== this.#selEnd) {
337
+ if (this.text[this.#selStart] === " ") {
338
+ this.#setSelection(this.#selStart + 1, this.#selEnd);
437
339
  }
438
- if (this.text[this.#selectionEnd - 1] === " ") {
439
- this.#setSelectionRange(this.#selectionStart, this.#selectionEnd - 1);
340
+ if (this.text[this.#selEnd - 1] === " ") {
341
+ this.#setSelection(this.#selStart, this.#selEnd - 1);
440
342
  }
441
343
  }
442
344
  });
443
345
  // reset #openChars on click since the cursor has changed position
444
346
  this.textArea.addEventListener("click", () => (this.#openChars = []));
445
347
  for (const trigger of this.getTrigger()) {
446
- trigger.addEventListener(this.event, () => {
447
- this.#addContent(this.#getContentElement(trigger));
448
- });
348
+ trigger.addEventListener(this.event, () => this.#addContent(trigger.dataset));
449
349
  }
450
350
  }
451
351
  }
452
- /**
453
- * @param str
454
- * @returns the number, if the string starts with a number and a period
455
- */
456
- const startsWithNumberAndPeriod = (str) => {
457
- const result = str.match(/^(\d+)\./);
458
- return result ? Number(result[1]) : null;
459
- };
460
- /**
461
- * - insert character into string at index
462
- *
463
- * @param str string to insert into
464
- * @param char characters to insert into `str`
465
- * @param index where to insert the characters
466
- * @returns the new string
467
- */
468
- const insertChar = (str, char, index) => {
469
- return str.slice(0, index) + char + str.slice(index);
470
- };
471
- /**
472
- * - remove char from string at index
473
- *
474
- * @param str string to remove the character from
475
- * @param index index of character to remove
476
- * @returns the new string
477
- */
478
- const removeChar = (str, index) => {
479
- return str.slice(0, index) + str.slice(index + 1);
480
- };
@@ -54,9 +54,7 @@ export class Intersect extends Base {
54
54
  }
55
55
  }
56
56
  }
57
- }, {
58
- threshold: this.#threshold,
59
- });
57
+ }, { threshold: this.#threshold });
60
58
  for (const trigger of this.getTrigger()) {
61
59
  observer.observe(trigger);
62
60
  }
@@ -61,12 +61,7 @@ export class Prefetch extends Base {
61
61
  // Currently, adding `prefetch` is required to fallback if `prerender` fails.
62
62
  // Possibly will be automatic in the future, in which case it can be removed.
63
63
  // https://github.com/WICG/nav-speculation/issues/162#issuecomment-1977818473
64
- prefetch: [
65
- {
66
- source: "list",
67
- urls: [url],
68
- },
69
- ],
64
+ prefetch: [{ source: "list", urls: [url] }],
70
65
  };
71
66
  if (prerender) {
72
67
  rules.prerender = rules.prefetch;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "drab",
3
3
  "description": "Interactivity for You",
4
- "version": "6.1.0",
4
+ "version": "6.1.2",
5
5
  "homepage": "https://drab.robino.dev",
6
6
  "license": "MIT",
7
7
  "author": {