xote 6.1.2 → 6.2.0

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.
@@ -1,32 +1,19 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
- import * as Signal$Xote from "./Signal.res.mjs";
3
+ import * as Prop$Xote from "./Prop.res.mjs";
4
4
 
5
- function get(value) {
6
- if (value.TAG === "Reactive") {
7
- return Signal$Xote.get(value._0);
8
- } else {
9
- return value._0;
10
- }
11
- }
5
+ let get = Prop$Xote.get;
12
6
 
13
- function $$static(value) {
14
- return {
15
- TAG: "Static",
16
- _0: value
17
- };
18
- }
7
+ let $$static = Prop$Xote.$$static;
19
8
 
20
- function reactive(signal) {
21
- return {
22
- TAG: "Reactive",
23
- _0: signal
24
- };
25
- }
9
+ let reactive = Prop$Xote.reactive;
10
+
11
+ let signal = Prop$Xote.signal;
26
12
 
27
13
  export {
28
14
  get,
29
15
  $$static,
30
16
  reactive,
17
+ signal,
31
18
  }
32
19
  /* No side effect */
package/src/Route.res CHANGED
@@ -60,3 +60,7 @@ let matchPath = (pattern: array<segment>, pathname: string): matchResult => {
60
60
  let match = (pattern: string, pathname: string): matchResult => {
61
61
  matchPath(parsePattern(pattern), pathname)
62
62
  }
63
+
64
+ let compile = parsePattern
65
+ let matchCompiled = matchPath
66
+ let matchPathname = match
package/src/Route.res.mjs CHANGED
@@ -48,9 +48,18 @@ function match(pattern, pathname) {
48
48
  return matchPath(parsePattern(pattern), pathname);
49
49
  }
50
50
 
51
+ let compile = parsePattern;
52
+
53
+ let matchCompiled = matchPath;
54
+
55
+ let matchPathname = match;
56
+
51
57
  export {
52
58
  parsePattern,
53
59
  matchPath,
54
60
  match,
61
+ compile,
62
+ matchCompiled,
63
+ matchPathname,
55
64
  }
56
65
  /* No side effect */
package/src/Router.res CHANGED
@@ -309,11 +309,11 @@ let replace = (pathname: string, ~search: string="", ~hash: string="", ()): unit
309
309
  // Route definition for routes() component
310
310
  type routeConfig = {
311
311
  pattern: string,
312
- render: Route.params => Node.node,
312
+ render: Route.params => View.node,
313
313
  }
314
314
 
315
315
  // Single route component - renders if pattern matches
316
- let route = (pattern: string, render: Route.params => Node.node): Node.node => {
316
+ let route = (pattern: string, render: Route.params => View.node): View.node => {
317
317
  warnIfNotInitialized("Router.route()")
318
318
 
319
319
  let signal = Computed.make(() => {
@@ -323,11 +323,11 @@ let route = (pattern: string, render: Route.params => Node.node): Node.node => {
323
323
  | NoMatch => []
324
324
  }
325
325
  })
326
- Node.signalFragment(signal)
326
+ View.signalFragment(signal)
327
327
  }
328
328
 
329
329
  // Routes component - renders first matching route
330
- let routes = (configs: array<routeConfig>): Node.node => {
330
+ let routes = (configs: array<routeConfig>): View.node => {
331
331
  warnIfNotInitialized("Router.routes()")
332
332
 
333
333
  let signal = Computed.make(() => {
@@ -344,16 +344,16 @@ let routes = (configs: array<routeConfig>): Node.node => {
344
344
  | None => [] // No matching route - render nothing
345
345
  }
346
346
  })
347
- Node.signalFragment(signal)
347
+ View.signalFragment(signal)
348
348
  }
349
349
 
350
350
  // Link component - handles navigation without page reload
351
351
  let link = (
352
352
  ~to: string,
353
- ~attrs: array<(string, Node.attrValue)>=[],
354
- ~children: array<Node.node>=[],
353
+ ~attrs: array<(string, View.attrValue)>=[],
354
+ ~children: array<View.node>=[],
355
355
  (),
356
- ): Node.node => {
356
+ ): View.node => {
357
357
  warnIfNotInitialized("Router.link()")
358
358
 
359
359
  let handleClick = (_evt: Dom.event) => {
@@ -362,7 +362,7 @@ let link = (
362
362
  }
363
363
 
364
364
  Html.a(
365
- ~attrs=Array.concat(attrs, [Node.attr("href", addBasePath(to))]),
365
+ ~attrs=Array.concat(attrs, [View.attr("href", addBasePath(to))]),
366
366
  ~events=[("click", handleClick)],
367
367
  ~children,
368
368
  (),
@@ -371,7 +371,7 @@ let link = (
371
371
 
372
372
  // JSX Link component
373
373
  module Link = {
374
- module ReactiveProp = ReactiveProp
374
+ module Prop = Prop
375
375
 
376
376
  type props<'class, 'id, 'style, 'target, 'ariaLabel> = {
377
377
  /* Required navigation prop */
@@ -385,61 +385,35 @@ module Link = {
385
385
  /* Event handlers */
386
386
  onClick?: Dom.event => unit,
387
387
  /* Children */
388
- children?: Node.node,
389
- }
390
-
391
- /* Helper to detect if a value is a ReactiveProp variant */
392
- let isReactiveProp = (value: 'a): bool => {
393
- ignore(value)
394
- %raw(`value && typeof value === 'object' && ('TAG' in value) && (value.TAG === 'Static' || value.TAG === 'Reactive')`)
395
- }
396
-
397
- /* Helper to convert string attribute value */
398
- let convertAttrValue = (key: string, value: 'a): (string, Node.attrValue) => {
399
- if isReactiveProp(value) {
400
- let rp: ReactiveProp.t<string> = Obj.magic(value)
401
- switch rp {
402
- | Static(s) => Node.attr(key, s)
403
- | Reactive(signal) => Node.signalAttr(key, signal)
404
- }
405
- } else if typeof(value) == #function {
406
- let f: unit => string = Obj.magic(value)
407
- Node.computedAttr(key, f)
408
- } else if typeof(value) == #object {
409
- let sig: Signal.t<string> = Obj.magic(value)
410
- Node.signalAttr(key, sig)
411
- } else {
412
- let s: string = Obj.magic(value)
413
- Node.attr(key, s)
414
- }
388
+ children?: View.node,
415
389
  }
416
390
 
417
391
  /* Convert props to attrs array */
418
- let propsToAttrs = (props): array<(string, Node.attrValue)> => {
392
+ let propsToAttrs = (props): array<(string, View.attrValue)> => {
419
393
  let attrs = []
420
394
 
421
395
  switch props.class {
422
- | Some(v) => attrs->Array.push(convertAttrValue("class", v))
396
+ | Some(v) => attrs->Array.push(RuntimeJsxProp.toStringAttr("class", v))
423
397
  | None => ()
424
398
  }
425
399
 
426
400
  switch props.id {
427
- | Some(v) => attrs->Array.push(convertAttrValue("id", v))
401
+ | Some(v) => attrs->Array.push(RuntimeJsxProp.toStringAttr("id", v))
428
402
  | None => ()
429
403
  }
430
404
 
431
405
  switch props.style {
432
- | Some(v) => attrs->Array.push(convertAttrValue("style", v))
406
+ | Some(v) => attrs->Array.push(RuntimeJsxProp.toStringAttr("style", v))
433
407
  | None => ()
434
408
  }
435
409
 
436
410
  switch props.target {
437
- | Some(v) => attrs->Array.push(convertAttrValue("target", v))
411
+ | Some(v) => attrs->Array.push(RuntimeJsxProp.toStringAttr("target", v))
438
412
  | None => ()
439
413
  }
440
414
 
441
415
  switch props.ariaLabel {
442
- | Some(v) => attrs->Array.push(convertAttrValue("aria-label", v))
416
+ | Some(v) => attrs->Array.push(RuntimeJsxProp.toStringAttr("aria-label", v))
443
417
  | None => ()
444
418
  }
445
419
 
@@ -447,16 +421,16 @@ module Link = {
447
421
  }
448
422
 
449
423
  /* Extract children from props */
450
- let getChildren = (props): array<Node.node> => {
424
+ let getChildren = (props): array<View.node> => {
451
425
  switch props.children {
452
- | Some(Node.Fragment(children)) => children
426
+ | Some(View.Fragment(children)) => children
453
427
  | Some(child) => [child]
454
428
  | None => []
455
429
  }
456
430
  }
457
431
 
458
432
  /* JSX component function */
459
- let make = (props): Node.node => {
433
+ let make = (props): View.node => {
460
434
  warnIfNotInitialized("Router.Link")
461
435
 
462
436
  let handleClick = (evt: Dom.event) => {
@@ -471,7 +445,7 @@ module Link = {
471
445
  }
472
446
 
473
447
  Html.a(
474
- ~attrs=Array.concat(propsToAttrs(props), [Node.attr("href", addBasePath(props.to))]),
448
+ ~attrs=Array.concat(propsToAttrs(props), [View.attr("href", addBasePath(props.to))]),
475
449
  ~events=[("click", handleClick)],
476
450
  ~children=getChildren(props),
477
451
  (),
@@ -482,8 +456,10 @@ module Link = {
482
456
  let jsx = make
483
457
  let jsxs = make
484
458
  let jsxKeyed = (props, ~key: option<string>=?, _: unit) => {
485
- let _ = key
486
- make(props)
459
+ switch key {
460
+ | Some(key) => View.Keyed({key, identity: Obj.magic(props), child: make(props)})
461
+ | None => make(props)
462
+ }
487
463
  }
488
464
  let jsxsKeyed = jsxKeyed
489
465
  }
@@ -1,12 +1,13 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Html$Xote from "./Html.res.mjs";
4
- import * as Node$Xote from "./Node.res.mjs";
4
+ import * as View$Xote from "./View.res.mjs";
5
5
  import * as Route$Xote from "./Route.res.mjs";
6
6
  import * as Signal$Xote from "./Signal.res.mjs";
7
7
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
8
8
  import * as Computed$Xote from "./Computed.res.mjs";
9
9
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
10
+ import * as RuntimeJsxProp$Xote from "./RuntimeJsxProp.res.mjs";
10
11
 
11
12
  function getSymbolKey() {
12
13
  return Symbol.for("xote.router.state");
@@ -213,7 +214,7 @@ function replace(pathname, searchOpt, hashOpt, param) {
213
214
 
214
215
  function route(pattern, render) {
215
216
  warnIfNotInitialized("Router.route()");
216
- return Node$Xote.signalFragment(Computed$Xote.make(() => {
217
+ return View$Xote.signalFragment(Computed$Xote.make(() => {
217
218
  let loc = Signal$Xote.get(getGlobalState().location);
218
219
  let params = Route$Xote.match(pattern, loc.pathname);
219
220
  if (typeof params !== "object") {
@@ -226,7 +227,7 @@ function route(pattern, render) {
226
227
 
227
228
  function routes(configs) {
228
229
  warnIfNotInitialized("Router.routes()");
229
- return Node$Xote.signalFragment(Computed$Xote.make(() => {
230
+ return View$Xote.signalFragment(Computed$Xote.make(() => {
230
231
  let loc = Signal$Xote.get(getGlobalState().location);
231
232
  let matched = Stdlib_Array.findMap(configs, config => {
232
233
  let params = Route$Xote.match(config.pattern, loc.pathname);
@@ -252,53 +253,33 @@ function link(to, attrsOpt, childrenOpt, param) {
252
253
  ((_evt.preventDefault()));
253
254
  push(to, undefined, undefined, undefined);
254
255
  };
255
- return Html$Xote.a(attrs.concat([Node$Xote.attr("href", addBasePath(to))]), [[
256
+ return Html$Xote.a(attrs.concat([View$Xote.attr("href", addBasePath(to))]), [[
256
257
  "click",
257
258
  handleClick
258
259
  ]], children, undefined);
259
260
  }
260
261
 
261
- function isReactiveProp(value) {
262
- return (value && typeof value === 'object' && ('TAG' in value) && (value.TAG === 'Static' || value.TAG === 'Reactive'));
263
- }
264
-
265
- function convertAttrValue(key, value) {
266
- if (isReactiveProp(value)) {
267
- if (value.TAG === "Reactive") {
268
- return Node$Xote.signalAttr(key, value._0);
269
- } else {
270
- return Node$Xote.attr(key, value._0);
271
- }
272
- } else if (typeof value === "function") {
273
- return Node$Xote.computedAttr(key, value);
274
- } else if (typeof value === "object") {
275
- return Node$Xote.signalAttr(key, value);
276
- } else {
277
- return Node$Xote.attr(key, value);
278
- }
279
- }
280
-
281
262
  function propsToAttrs(props) {
282
263
  let attrs = [];
283
264
  let v = props.class;
284
265
  if (v !== undefined) {
285
- attrs.push(convertAttrValue("class", Primitive_option.valFromOption(v)));
266
+ attrs.push(RuntimeJsxProp$Xote.toStringAttr("class", Primitive_option.valFromOption(v)));
286
267
  }
287
268
  let v$1 = props.id;
288
269
  if (v$1 !== undefined) {
289
- attrs.push(convertAttrValue("id", Primitive_option.valFromOption(v$1)));
270
+ attrs.push(RuntimeJsxProp$Xote.toStringAttr("id", Primitive_option.valFromOption(v$1)));
290
271
  }
291
272
  let v$2 = props.style;
292
273
  if (v$2 !== undefined) {
293
- attrs.push(convertAttrValue("style", Primitive_option.valFromOption(v$2)));
274
+ attrs.push(RuntimeJsxProp$Xote.toStringAttr("style", Primitive_option.valFromOption(v$2)));
294
275
  }
295
276
  let v$3 = props.target;
296
277
  if (v$3 !== undefined) {
297
- attrs.push(convertAttrValue("target", Primitive_option.valFromOption(v$3)));
278
+ attrs.push(RuntimeJsxProp$Xote.toStringAttr("target", Primitive_option.valFromOption(v$3)));
298
279
  }
299
280
  let v$4 = props["aria-label"];
300
281
  if (v$4 !== undefined) {
301
- attrs.push(convertAttrValue("aria-label", Primitive_option.valFromOption(v$4)));
282
+ attrs.push(RuntimeJsxProp$Xote.toStringAttr("aria-label", Primitive_option.valFromOption(v$4)));
302
283
  }
303
284
  return attrs;
304
285
  }
@@ -326,20 +307,27 @@ function make(props) {
326
307
  return handler(evt);
327
308
  }
328
309
  };
329
- return Html$Xote.a(propsToAttrs(props).concat([Node$Xote.attr("href", addBasePath(props.to))]), [[
310
+ return Html$Xote.a(propsToAttrs(props).concat([View$Xote.attr("href", addBasePath(props.to))]), [[
330
311
  "click",
331
312
  handleClick
332
313
  ]], getChildren(props), undefined);
333
314
  }
334
315
 
335
316
  function jsxKeyed(props, key, param) {
336
- return make(props);
317
+ if (key !== undefined) {
318
+ return {
319
+ TAG: "Keyed",
320
+ key: key,
321
+ identity: props,
322
+ child: make(props)
323
+ };
324
+ } else {
325
+ return make(props);
326
+ }
337
327
  }
338
328
 
339
329
  let Link = {
340
- ReactiveProp: undefined,
341
- isReactiveProp: isReactiveProp,
342
- convertAttrValue: convertAttrValue,
330
+ Prop: undefined,
343
331
  propsToAttrs: propsToAttrs,
344
332
  getChildren: getChildren,
345
333
  make: make,
@@ -0,0 +1,21 @@
1
+ let booleanAttributes = [
2
+ "checked",
3
+ "disabled",
4
+ "required",
5
+ "readonly",
6
+ "multiple",
7
+ "aria-hidden",
8
+ "aria-expanded",
9
+ "aria-selected",
10
+ "draggable",
11
+ "hidden",
12
+ "contenteditable",
13
+ "spellcheck",
14
+ "autofocus",
15
+ ]
16
+
17
+ let isBoolean = (key: string): bool => booleanAttributes->Array.includes(key)
18
+
19
+ let boolToString = (value: bool): string => value ? "true" : "false"
20
+
21
+ let shouldRenderBoolean = (value: string): bool => value == "true"
@@ -0,0 +1,42 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ let booleanAttributes = [
5
+ "checked",
6
+ "disabled",
7
+ "required",
8
+ "readonly",
9
+ "multiple",
10
+ "aria-hidden",
11
+ "aria-expanded",
12
+ "aria-selected",
13
+ "draggable",
14
+ "hidden",
15
+ "contenteditable",
16
+ "spellcheck",
17
+ "autofocus"
18
+ ];
19
+
20
+ function isBoolean(key) {
21
+ return booleanAttributes.includes(key);
22
+ }
23
+
24
+ function boolToString(value) {
25
+ if (value) {
26
+ return "true";
27
+ } else {
28
+ return "false";
29
+ }
30
+ }
31
+
32
+ function shouldRenderBoolean(value) {
33
+ return value === "true";
34
+ }
35
+
36
+ export {
37
+ booleanAttributes,
38
+ isBoolean,
39
+ boolToString,
40
+ shouldRenderBoolean,
41
+ }
42
+ /* No side effect */
@@ -0,0 +1,95 @@
1
+ let svgNamespace = "http://www.w3.org/2000/svg"
2
+
3
+ let svgTags = [
4
+ "svg",
5
+ "path",
6
+ "circle",
7
+ "ellipse",
8
+ "line",
9
+ "polygon",
10
+ "polyline",
11
+ "rect",
12
+ "g",
13
+ "defs",
14
+ "clipPath",
15
+ "mask",
16
+ "pattern",
17
+ "marker",
18
+ "symbol",
19
+ "use",
20
+ "text",
21
+ "tspan",
22
+ "image",
23
+ "foreignObject",
24
+ "linearGradient",
25
+ "radialGradient",
26
+ "stop",
27
+ "filter",
28
+ "feBlend",
29
+ "feColorMatrix",
30
+ "feComposite",
31
+ "feFlood",
32
+ "feGaussianBlur",
33
+ "feMerge",
34
+ "feMergeNode",
35
+ "feOffset",
36
+ "animate",
37
+ "animateTransform",
38
+ "desc",
39
+ "title",
40
+ "metadata",
41
+ ]
42
+
43
+ let svgTagSet: Dict.t<bool> = {
44
+ let d = Dict.make()
45
+ svgTags->Array.forEach(tag => d->Dict.set(tag, true))
46
+ d
47
+ }
48
+
49
+ let isSvgTag = (tag: string): bool => svgTagSet->Dict.get(tag)->Option.isSome
50
+
51
+ @val @scope("document") external createElement: string => Dom.element = "createElement"
52
+ @val @scope("document")
53
+ external createElementNS: (string, string) => Dom.element = "createElementNS"
54
+ @val @scope("document") external createTextNode: string => Dom.element = "createTextNode"
55
+ @val @scope("document")
56
+ external createDocumentFragment: unit => Dom.element = "createDocumentFragment"
57
+ @val @scope("document") external createComment: string => Dom.element = "createComment"
58
+ @val @scope("document")
59
+ external getElementById: string => Nullable.t<Dom.element> = "getElementById"
60
+
61
+ @get external getNextSibling: Dom.element => Nullable.t<Dom.element> = "nextSibling"
62
+ @get external getFirstChild: Dom.element => Nullable.t<Dom.element> = "firstChild"
63
+ @get external getParentNode: Dom.element => Nullable.t<Dom.element> = "parentNode"
64
+
65
+ @send
66
+ external addEventListener: (Dom.element, string, Dom.event => unit) => unit = "addEventListener"
67
+ @send external appendChild: (Dom.element, Dom.element) => unit = "appendChild"
68
+ @send external remove: Dom.element => unit = "remove"
69
+ @send external setAttribute: (Dom.element, string, string) => unit = "setAttribute"
70
+ @send external removeAttribute: (Dom.element, string) => unit = "removeAttribute"
71
+ @send external replaceChild: (Dom.element, Dom.element, Dom.element) => unit = "replaceChild"
72
+ @send external insertBefore: (Dom.element, Dom.element, Dom.element) => unit = "insertBefore"
73
+ @set external setTextContent: (Dom.element, string) => unit = "textContent"
74
+ @set external setInnerHTML: (Dom.element, string) => unit = "innerHTML"
75
+ @set external setValue: (Dom.element, string) => unit = "value"
76
+ @set external setChecked: (Dom.element, bool) => unit = "checked"
77
+ @set external setDisabled: (Dom.element, bool) => unit = "disabled"
78
+
79
+ let createElementForTag = (tag: string): Dom.element =>
80
+ isSvgTag(tag) ? createElementNS(svgNamespace, tag) : createElement(tag)
81
+
82
+ let setAttrOrProp = (el: Dom.element, key: string, value: string): unit => {
83
+ switch key {
84
+ | "value" => setValue(el, value)
85
+ | "checked" => setChecked(el, value == "true")
86
+ | "disabled" => setDisabled(el, value == "true")
87
+ | _ if RuntimeAttr.isBoolean(key) =>
88
+ if RuntimeAttr.shouldRenderBoolean(value) {
89
+ setAttribute(el, key, "")
90
+ } else {
91
+ removeAttribute(el, key)
92
+ }
93
+ | _ => setAttribute(el, key, value)
94
+ }
95
+ }
@@ -0,0 +1,101 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
4
+ import * as RuntimeAttr$Xote from "./RuntimeAttr.res.mjs";
5
+
6
+ let svgNamespace = "http://www.w3.org/2000/svg";
7
+
8
+ let svgTags = [
9
+ "svg",
10
+ "path",
11
+ "circle",
12
+ "ellipse",
13
+ "line",
14
+ "polygon",
15
+ "polyline",
16
+ "rect",
17
+ "g",
18
+ "defs",
19
+ "clipPath",
20
+ "mask",
21
+ "pattern",
22
+ "marker",
23
+ "symbol",
24
+ "use",
25
+ "text",
26
+ "tspan",
27
+ "image",
28
+ "foreignObject",
29
+ "linearGradient",
30
+ "radialGradient",
31
+ "stop",
32
+ "filter",
33
+ "feBlend",
34
+ "feColorMatrix",
35
+ "feComposite",
36
+ "feFlood",
37
+ "feGaussianBlur",
38
+ "feMerge",
39
+ "feMergeNode",
40
+ "feOffset",
41
+ "animate",
42
+ "animateTransform",
43
+ "desc",
44
+ "title",
45
+ "metadata"
46
+ ];
47
+
48
+ let d = {};
49
+
50
+ svgTags.forEach(tag => {
51
+ d[tag] = true;
52
+ });
53
+
54
+ function isSvgTag(tag) {
55
+ return Stdlib_Option.isSome(d[tag]);
56
+ }
57
+
58
+ function createElementForTag(tag) {
59
+ if (Stdlib_Option.isSome(d[tag])) {
60
+ return document.createElementNS(svgNamespace, tag);
61
+ } else {
62
+ return document.createElement(tag);
63
+ }
64
+ }
65
+
66
+ function setAttrOrProp(el, key, value) {
67
+ switch (key) {
68
+ case "checked" :
69
+ el.checked = value === "true";
70
+ return;
71
+ case "disabled" :
72
+ el.disabled = value === "true";
73
+ return;
74
+ case "value" :
75
+ el.value = value;
76
+ return;
77
+ default:
78
+ if (RuntimeAttr$Xote.isBoolean(key)) {
79
+ if (RuntimeAttr$Xote.shouldRenderBoolean(value)) {
80
+ el.setAttribute(key, "");
81
+ } else {
82
+ el.removeAttribute(key);
83
+ }
84
+ } else {
85
+ el.setAttribute(key, value);
86
+ }
87
+ return;
88
+ }
89
+ }
90
+
91
+ let svgTagSet = d;
92
+
93
+ export {
94
+ svgNamespace,
95
+ svgTags,
96
+ svgTagSet,
97
+ isSvgTag,
98
+ createElementForTag,
99
+ setAttrOrProp,
100
+ }
101
+ /* Not a pure module */
@@ -0,0 +1,27 @@
1
+ let escape = (str: string): string => {
2
+ str
3
+ ->String.replaceAll("&", "&amp;")
4
+ ->String.replaceAll("<", "&lt;")
5
+ ->String.replaceAll(">", "&gt;")
6
+ ->String.replaceAll("\"", "&quot;")
7
+ ->String.replaceAll("'", "&#x27;")
8
+ }
9
+
10
+ let voidElements = [
11
+ "area",
12
+ "base",
13
+ "br",
14
+ "col",
15
+ "embed",
16
+ "hr",
17
+ "img",
18
+ "input",
19
+ "link",
20
+ "meta",
21
+ "param",
22
+ "source",
23
+ "track",
24
+ "wbr",
25
+ ]
26
+
27
+ let isVoidElement = (tag: string): bool => voidElements->Array.includes(tag)
@@ -0,0 +1,34 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ function escape(str) {
5
+ return str.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#x27;");
6
+ }
7
+
8
+ let voidElements = [
9
+ "area",
10
+ "base",
11
+ "br",
12
+ "col",
13
+ "embed",
14
+ "hr",
15
+ "img",
16
+ "input",
17
+ "link",
18
+ "meta",
19
+ "param",
20
+ "source",
21
+ "track",
22
+ "wbr"
23
+ ];
24
+
25
+ function isVoidElement(tag) {
26
+ return voidElements.includes(tag);
27
+ }
28
+
29
+ export {
30
+ escape,
31
+ voidElements,
32
+ isVoidElement,
33
+ }
34
+ /* No side effect */