ripple 0.2.34 → 0.2.35

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
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is a TypeScript UI framework for the web",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.2.34",
6
+ "version": "0.2.35",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index.js",
9
9
  "main": "src/runtime/index.js",
@@ -8,6 +8,7 @@ import {
8
8
  is_ripple_import,
9
9
  is_tracked_computed_property,
10
10
  is_tracked_name,
11
+ is_void_element,
11
12
  } from '../../utils.js';
12
13
  import { extract_paths } from '../../../utils/ast.js';
13
14
  import is_reference from 'is-reference';
@@ -432,6 +433,8 @@ const visitors = {
432
433
  const attribute_names = new Set();
433
434
 
434
435
  if (is_dom_element) {
436
+ const is_void = is_void_element(node.id.name);
437
+
435
438
  if (state.elements) {
436
439
  state.elements.push(node);
437
440
  }
@@ -468,6 +471,14 @@ const visitors = {
468
471
  );
469
472
  }
470
473
  }
474
+
475
+ if (is_void && node.children.length > 0) {
476
+ error(
477
+ `The <${node.id.name}> element is a void element and cannot have children`,
478
+ state.analysis.module.filename,
479
+ node,
480
+ );
481
+ }
471
482
  } else {
472
483
  for (const attr of node.attributes) {
473
484
  if (attr.type === 'Attribute') {
@@ -21,6 +21,7 @@ import {
21
21
  is_inside_call_expression,
22
22
  is_tracked_computed_property,
23
23
  is_value_static,
24
+ is_void_element,
24
25
  } from '../../utils.js';
25
26
  import is_reference from 'is-reference';
26
27
  import { extract_paths, object } from '../../../utils/ast.js';
@@ -438,6 +439,7 @@ const visitors = {
438
439
  if (is_dom_element) {
439
440
  let class_attribute = null;
440
441
  const local_updates = [];
442
+ const is_void = is_void_element(node.id.name);
441
443
 
442
444
  state.template.push(`<${node.id.name}`);
443
445
 
@@ -629,7 +631,14 @@ const visitors = {
629
631
  const init = [];
630
632
  const update = [];
631
633
 
632
- transform_children(node.children, { visit, state: { ...state, init, update }, root: false });
634
+ if (!is_void) {
635
+ transform_children(node.children, {
636
+ visit,
637
+ state: { ...state, init, update },
638
+ root: false,
639
+ });
640
+ state.template.push(`</${node.id.name}>`);
641
+ }
633
642
 
634
643
  update.push(...local_updates);
635
644
 
@@ -640,8 +649,6 @@ const visitors = {
640
649
  if (update.length > 0) {
641
650
  state.init.push(b.stmt(b.call('$.render', b.thunk(b.block(update)))));
642
651
  }
643
-
644
- state.template.push(`</${node.id.name}>`);
645
652
  } else {
646
653
  const id = state.flush_node();
647
654
 
@@ -3,6 +3,33 @@ import * as b from '../utils/builders.js';
3
3
 
4
4
  const regex_return_characters = /\r/g;
5
5
 
6
+ const VOID_ELEMENT_NAMES = [
7
+ 'area',
8
+ 'base',
9
+ 'br',
10
+ 'col',
11
+ 'command',
12
+ 'embed',
13
+ 'hr',
14
+ 'img',
15
+ 'input',
16
+ 'keygen',
17
+ 'link',
18
+ 'meta',
19
+ 'param',
20
+ 'source',
21
+ 'track',
22
+ 'wbr'
23
+ ];
24
+
25
+ /**
26
+ * Returns `true` if `name` is of a void element
27
+ * @param {string} name
28
+ */
29
+ export function is_void_element(name) {
30
+ return VOID_ELEMENT_NAMES.includes(name) || name.toLowerCase() === '!doctype';
31
+ }
32
+
6
33
  const RESERVED_WORDS = [
7
34
  'arguments',
8
35
  'await',