@torpor/view 0.0.12 → 0.0.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torpor/view",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "Torpor's view library, for writing and mounting components",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -146,6 +146,7 @@ function buildElementFragmentText(
146
146
  fragments: Fragment[],
147
147
  currentFragment: Fragment,
148
148
  ) {
149
+ let needsClass = node.scopeStyles;
149
150
  currentFragment.text += `<${node.tagName}`;
150
151
  let attributesText = node.attributes
151
152
  .filter((a) => !a.name.startsWith("on") && !a.name.includes(":"))
@@ -157,6 +158,7 @@ function buildElementFragmentText(
157
158
  return `${a.name}=""`;
158
159
  }
159
160
  } else if (a.name === "class" && node.scopeStyles) {
161
+ needsClass = false;
160
162
  let value = a.value
161
163
  ? `"${trimQuotes(a.value)} torp-${status.styleHash}"`
162
164
  : `"torp-${status.styleHash}"`;
@@ -170,6 +172,9 @@ function buildElementFragmentText(
170
172
  if (attributesText) {
171
173
  currentFragment.text += " " + attributesText;
172
174
  }
175
+ if (needsClass) {
176
+ currentFragment.text += ` class="torp-${status.styleHash}"`;
177
+ }
173
178
  currentFragment.text += ">";
174
179
  for (let child of node.children) {
175
180
  buildNodeFragmentText(child, status, fragments, currentFragment);
@@ -73,6 +73,11 @@ function buildServerTemplate(
73
73
  } else if (script.substring(i, i + "/* @start */".length) === "/* @start */") {
74
74
  b.append(script.substring(marker, i));
75
75
 
76
+ // Make sure we've got $props if we're going to be using it
77
+ if (current.props?.length) {
78
+ b.append(`$props ??= {};`);
79
+ }
80
+
76
81
  // Redefine $context so that any newly added properties will only be passed to children
77
82
  if (current.contextProps?.length) {
78
83
  b.append(`$context = Object.assign({}, $context);`);
@@ -40,6 +40,7 @@ export default function buildServerElementNode(
40
40
  }
41
41
 
42
42
  function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
43
+ let needsClass = node.scopeStyles;
43
44
  let attributes: string[] = [];
44
45
  for (let { name, value } of node.attributes) {
45
46
  if (name === "self" && node.tagName === ":element") {
@@ -96,6 +97,7 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
96
97
  status.imports.add("t_class");
97
98
  if (node.scopeStyles) {
98
99
  value += `, "torp-${status.styleHash}"`;
100
+ needsClass = false;
99
101
  }
100
102
  attributes.push(`class="\${t_class(${value})}"`);
101
103
  } else if (name === ":style") {
@@ -118,6 +120,7 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
118
120
  ? `"${trimQuotes(value)} torp-${status.styleHash}"`
119
121
  : `"torp-${status.styleHash}"`;
120
122
  attributes.push(`${name}="${trimQuotes(value).replaceAll('"', "&quot;")}"`);
123
+ needsClass = false;
121
124
  } else if (value != null) {
122
125
  // Just set the attribute
123
126
  // TODO: Probably check if it's a boolean attribute e.g. disabled
@@ -126,5 +129,8 @@ function buildElementAttributes(node: ElementNode, status: BuildServerStatus) {
126
129
  attributes.push(`${name}`);
127
130
  }
128
131
  }
132
+ if (needsClass) {
133
+ attributes.push(`class="torp-${status.styleHash}"`);
134
+ }
129
135
  return attributes.join(" ");
130
136
  }
@@ -217,17 +217,21 @@ function parseComponentStyle(status: ParseStatus) {
217
217
  // Skip block comments
218
218
  status.i = status.source.indexOf("*/", status.i) + 1;
219
219
  } else if (char === '"' || char === "'") {
220
+ styleSource += char;
220
221
  // Skip string contents
221
222
  for (let j = status.i + 1; j < status.source.length; j++) {
223
+ styleSource += status.source[j];
222
224
  if (status.source[j] === char && status.source[j - 1] !== "\\") {
223
225
  status.i = j;
224
226
  break;
225
227
  }
226
228
  }
227
229
  } else if (char === "`") {
230
+ styleSource += char;
228
231
  // Skip possibly interpolated string contents
229
232
  let level2 = 0;
230
233
  for (let j = status.i + 1; j < status.source.length; j++) {
234
+ styleSource += status.source[j];
231
235
  if (status.source[j] === char && status.source[j - 1] !== "\\" && level2 === 0) {
232
236
  status.i = j;
233
237
  break;
@@ -49,8 +49,13 @@ test("class -- hydrated", async () => {
49
49
  });
50
50
 
51
51
  function check(container: HTMLElement, state: State) {
52
+ expect(queryByText(container, "From id")).not.toBeNull();
53
+ expect(queryByText(container, "From id")).toHaveClass("torp-1ljxz83", {
54
+ exact: true,
55
+ });
56
+
52
57
  expect(queryByText(container, "From string")).not.toBeNull();
53
- expect(queryByText(container, "From string")).toHaveClass("yo torp-1ljxz83", {
58
+ expect(queryByText(container, "From string")).toHaveClass("divclass torp-1ljxz83", {
54
59
  exact: true,
55
60
  });
56
61
 
@@ -1,7 +1,11 @@
1
1
  export default function Class() {
2
2
  @render {
3
3
  <div>
4
- <div class="yo">
4
+ <div id="divid">
5
+ From id
6
+ </div>
7
+
8
+ <div class="divclass">
5
9
  From string
6
10
  </div>
7
11
 
@@ -21,10 +21,10 @@ export default function Class(
21
21
  /* User interface */
22
22
  const t_fragments: DocumentFragment[] = [];
23
23
 
24
- const t_fragment_0 = t_fragment($parent.ownerDocument!, t_fragments, 0, `<div> <div class="yo torp-1ljxz83"> From string </div> <a> From state </a> <div> From state with scope </div> <div> Class object </div> <div> Class array </div> <div> Class nested </div> </div>`);
24
+ const t_fragment_0 = t_fragment($parent.ownerDocument!, t_fragments, 0, `<div class="torp-1ljxz83"> <div id="divid" class="torp-1ljxz83"> From id </div> <div class="divclass torp-1ljxz83"> From string </div> <a class="torp-1ljxz83"> From state </a> <div class="torp-1ljxz83"> From state with scope </div> <div class="torp-1ljxz83"> Class object </div> <div class="torp-1ljxz83"> Class array </div> <div class="torp-1ljxz83"> Class nested </div> </div>`);
25
25
  // @ts-ignore
26
26
  const t_div_1 = t_root(t_fragment_0) as HTMLDivElement;
27
- const t_a_1 = t_next(t_next(t_next(t_child(t_div_1)))) as HTMLElement;
27
+ const t_a_1 = t_next(t_next(t_next(t_next(t_next(t_child(t_div_1)))))) as HTMLElement;
28
28
  const t_div_2 = t_next(t_next(t_a_1)) as HTMLDivElement;
29
29
  const t_div_3 = t_next(t_next(t_div_2)) as HTMLDivElement;
30
30
  const t_div_4 = t_next(t_next(t_div_3)) as HTMLDivElement;
@@ -11,7 +11,7 @@ export default function Class(
11
11
 
12
12
  /* User interface */
13
13
  let $output = "";
14
- $output += `<div> <div class="yo torp-1ljxz83"> From string </div> <a class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state </a> <div class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state with scope </div> <div class="${t_class({ foo: true, bar: false, baz: 5, qux: null }, "torp-1ljxz83")}"> Class object </div> <div class="${t_class([ "foo", false, true && "baz", undefined ], "torp-1ljxz83")}"> Class array </div> <div class="${t_class([ "foo", 0, { bar: true }, "", [1 && "baz", ["qux"]] ], "torp-1ljxz83")}"> Class nested </div> </div>`;
14
+ $output += `<div class="torp-1ljxz83"> <div id="divid" class="torp-1ljxz83"> From id </div> <div class="divclass torp-1ljxz83"> From string </div> <a class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state </a> <div class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state with scope </div> <div class="${t_class({ foo: true, bar: false, baz: 5, qux: null }, "torp-1ljxz83")}"> Class object </div> <div class="${t_class([ "foo", false, true && "baz", undefined ], "torp-1ljxz83")}"> Class array </div> <div class="${t_class([ "foo", 0, { bar: true }, "", [1 && "baz", ["qux"]] ], "torp-1ljxz83")}"> Class nested </div> </div>`;
15
15
 
16
16
  return $output;
17
17
  }
@@ -21,10 +21,10 @@ export default function Class(
21
21
  /* User interface */
22
22
  const t_fragments: DocumentFragment[] = [];
23
23
 
24
- const t_fragment_0 = t_fragment($parent.ownerDocument!, t_fragments, 0, `<div> <div class="yo torp-1ljxz83"> From string </div> <a> From state </a> <div> From state with scope </div> <div> Class object </div> <div> Class array </div> <div> Class nested </div> </div>`);
24
+ const t_fragment_0 = t_fragment($parent.ownerDocument!, t_fragments, 0, `<div class="torp-1ljxz83"> <div id="divid" class="torp-1ljxz83"> From id </div> <div class="divclass torp-1ljxz83"> From string </div> <a class="torp-1ljxz83"> From state </a> <div class="torp-1ljxz83"> From state with scope </div> <div class="torp-1ljxz83"> Class object </div> <div class="torp-1ljxz83"> Class array </div> <div class="torp-1ljxz83"> Class nested </div> </div>`);
25
25
  // @ts-ignore
26
26
  const t_div_1 = t_root(t_fragment_0) as HTMLDivElement;
27
- const t_a_1 = t_next(t_next(t_next(t_child(t_div_1)))) as HTMLElement;
27
+ const t_a_1 = t_next(t_next(t_next(t_next(t_next(t_child(t_div_1)))))) as HTMLElement;
28
28
  const t_div_2 = t_next(t_next(t_a_1)) as HTMLDivElement;
29
29
  const t_div_3 = t_next(t_next(t_div_2)) as HTMLDivElement;
30
30
  const t_div_4 = t_next(t_next(t_div_3)) as HTMLDivElement;
@@ -0,0 +1,17 @@
1
+ import { type ServerSlotRender } from "../../../../src/types/ServerSlotRender";
2
+ import t_class from "../../../../src/render/getClasses";
3
+
4
+ export default function Class(
5
+ $props: Record<PropertyKey, any>,
6
+ // @ts-ignore
7
+ $context?: Record<PropertyKey, any>,
8
+ // @ts-ignore
9
+ $slots?: Record<string, ServerSlotRender>
10
+ ) {
11
+
12
+ /* User interface */
13
+ let $output = "";
14
+ $output += `<div class="torp-1ljxz83"> <div id="divid" class="torp-1ljxz83"> From id </div> <div class="divclass torp-1ljxz83"> From string </div> <a class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state </a> <div class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state with scope </div> <div class="${t_class({ foo: true, bar: false, baz: 5, qux: null }, "torp-1ljxz83")}"> Class object </div> <div class="${t_class([ "foo", false, true && "baz", undefined ], "torp-1ljxz83")}"> Class array </div> <div class="${t_class([ "foo", 0, { bar: true }, "", [1 && "baz", ["qux"]] ], "torp-1ljxz83")}"> Class nested </div> </div>`;
15
+
16
+ return $output;
17
+ }
@@ -1,17 +0,0 @@
1
- import { type ServerSlotRender } from "../../../../src/types/ServerSlotRender";
2
- import t_class from "../../../../src/render/getClasses";
3
-
4
- export default function Class(
5
- $props: Record<PropertyKey, any>,
6
- // @ts-ignore
7
- $context?: Record<PropertyKey, any>,
8
- // @ts-ignore
9
- $slots?: Record<string, ServerSlotRender>
10
- ) {
11
-
12
- /* User interface */
13
- let $output = "";
14
- $output += `<div> <div class="yo torp-1ljxz83"> From string </div> <a class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state </a> <div class="${t_class({ hello: true, red: $props.red, green: $props.green, blue: $props.blue }, "torp-1ljxz83")}"> From state with scope </div> <div class="${t_class({ foo: true, bar: false, baz: 5, qux: null }, "torp-1ljxz83")}"> Class object </div> <div class="${t_class([ "foo", false, true && "baz", undefined ], "torp-1ljxz83")}"> Class array </div> <div class="${t_class([ "foo", 0, { bar: true }, "", [1 && "baz", ["qux"]] ], "torp-1ljxz83")}"> Class nested </div> </div>`;
15
-
16
- return $output;
17
- }