@stacksjs/stx 0.2.113 → 0.2.115

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.
package/dist/slots.js CHANGED
@@ -27,32 +27,117 @@ function findMatchingTemplateClose(content, startIndex) {
27
27
  }
28
28
  return depth === 0 ? i : -1;
29
29
  }
30
+ const VOID_ELEMENTS = new Set([
31
+ "area",
32
+ "base",
33
+ "br",
34
+ "col",
35
+ "embed",
36
+ "hr",
37
+ "img",
38
+ "input",
39
+ "link",
40
+ "meta",
41
+ "param",
42
+ "source",
43
+ "track",
44
+ "wbr"
45
+ ]);
46
+ function findTagEnd(content, startIndex) {
47
+ let quote = null;
48
+ for (let index = startIndex;index < content.length; index++) {
49
+ const character = content[index];
50
+ if (quote) {
51
+ if (character === "\\") {
52
+ index++;
53
+ continue;
54
+ }
55
+ if (character === quote)
56
+ quote = null;
57
+ continue;
58
+ }
59
+ if (character === '"' || character === "'") {
60
+ quote = character;
61
+ continue;
62
+ }
63
+ if (character === ">")
64
+ return index + 1;
65
+ }
66
+ return -1;
67
+ }
68
+ function findDirectNamedSlotTemplates(content) {
69
+ const slots = [], stack = [], slotOpenPattern = /^<template\s+(?:#([a-zA-Z][\w-]*)|v-slot:([a-zA-Z][\w-]*)|slot="([a-zA-Z][\w-]*)")(?:\s*=\s*"([^"]*)")?[^>]*>$/i;
70
+ let cursor = 0;
71
+ while (cursor < content.length) {
72
+ const tagStart = content.indexOf("<", cursor);
73
+ if (tagStart === -1)
74
+ break;
75
+ if (content.startsWith("<!--", tagStart)) {
76
+ const commentEnd = content.indexOf("-->", tagStart + 4);
77
+ cursor = commentEnd === -1 ? content.length : commentEnd + 3;
78
+ continue;
79
+ }
80
+ const tagEnd = findTagEnd(content, tagStart + 1);
81
+ if (tagEnd === -1)
82
+ break;
83
+ const tag = content.slice(tagStart, tagEnd), tagMatch = tag.match(/^<\s*(\/?)\s*([a-zA-Z][\w-]*)/);
84
+ if (!tagMatch) {
85
+ cursor = tagEnd;
86
+ continue;
87
+ }
88
+ const closing = tagMatch[1] === "/", tagName = tagMatch[2].toLowerCase();
89
+ if (closing) {
90
+ const matchingIndex = stack.lastIndexOf(tagName);
91
+ if (matchingIndex !== -1)
92
+ stack.splice(matchingIndex);
93
+ cursor = tagEnd;
94
+ continue;
95
+ }
96
+ if (tagName === "template" && stack.length === 0) {
97
+ const slotMatch = tag.match(slotOpenPattern);
98
+ if (slotMatch) {
99
+ const closeEnd = findMatchingTemplateClose(content, tagEnd);
100
+ if (closeEnd !== -1) {
101
+ const slotName = slotMatch[1] || slotMatch[2] || slotMatch[3];
102
+ slots.push({
103
+ start: tagStart,
104
+ end: closeEnd,
105
+ slotName,
106
+ content: content.slice(tagEnd, closeEnd - 11).trim(),
107
+ propsBinding: slotMatch[4] || void 0
108
+ });
109
+ cursor = closeEnd;
110
+ continue;
111
+ }
112
+ }
113
+ }
114
+ if (!/\/\s*>$/.test(tag) && !VOID_ELEMENTS.has(tagName)) {
115
+ stack.push(tagName);
116
+ if (tagName === "script" || tagName === "style") {
117
+ const rawClose = content.toLowerCase().indexOf(`</${tagName}>`, tagEnd);
118
+ if (rawClose !== -1) {
119
+ cursor = rawClose;
120
+ continue;
121
+ }
122
+ }
123
+ }
124
+ cursor = tagEnd;
125
+ }
126
+ return slots;
127
+ }
30
128
  export function parseSlots(childContent) {
31
129
  const result = {
32
130
  default: "",
33
131
  named: new Map
34
132
  };
35
133
  let workingContent = childContent;
36
- const slotOpenRegex = /<template\s+(?:#([a-zA-Z][\w-]*)|v-slot:([a-zA-Z][\w-]*)|slot="([a-zA-Z][\w-]*)")(?:\s*=\s*"([^"]*)")?[^>]*>/gi, slotsToRemove = [];
37
- let match;
38
- while ((match = slotOpenRegex.exec(childContent)) !== null) {
39
- const [fullOpenTag, hashName, vSlotName, slotAttrName, propsBinding] = match, slotName = hashName || vSlotName || slotAttrName, openTagEnd = match.index + fullOpenTag.length, closeEnd = findMatchingTemplateClose(childContent, openTagEnd);
40
- if (closeEnd !== -1) {
41
- const content = childContent.slice(openTagEnd, closeEnd - 11).trim();
42
- slotsToRemove.push({
43
- start: match.index,
44
- end: closeEnd,
45
- slotName,
46
- content,
47
- propsBinding: propsBinding || void 0
48
- });
49
- result.named.set(slotName, {
50
- name: slotName,
51
- content,
52
- propsBinding: propsBinding || void 0
53
- });
54
- }
55
- }
134
+ const slotsToRemove = findDirectNamedSlotTemplates(childContent);
135
+ for (const slot of slotsToRemove)
136
+ result.named.set(slot.slotName, {
137
+ name: slot.slotName,
138
+ content: slot.content,
139
+ propsBinding: slot.propsBinding
140
+ });
56
141
  slotsToRemove.sort((a, b) => b.start - a.start);
57
142
  for (const slot of slotsToRemove)
58
143
  workingContent = workingContent.slice(0, slot.start) + workingContent.slice(slot.end);