@barefootjs/perl 0.8.0 → 0.9.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.
- package/LICENSE +21 -0
- package/lib/BarefootJS/DevReload.pm +1 -1
- package/lib/BarefootJS.pm +93 -15
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-present BarefootJS Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/lib/BarefootJS.pm
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
package BarefootJS;
|
|
2
|
-
our $VERSION = "0.
|
|
2
|
+
our $VERSION = "0.8.0";
|
|
3
3
|
use strict;
|
|
4
4
|
use warnings;
|
|
5
5
|
use utf8;
|
|
@@ -504,6 +504,84 @@ sub includes ($self, $recv, $elem) {
|
|
|
504
504
|
return index($recv // '', $elem // '') != -1 ? 1 : 0;
|
|
505
505
|
}
|
|
506
506
|
|
|
507
|
+
# `Array.prototype.filter(fn)` / `.every(fn)` / `.some(fn)`. The Xslate adapter
|
|
508
|
+
# lowers a JS arrow predicate to a Kolon lambda (`-> $x { ... }`), which is
|
|
509
|
+
# callable from Perl as a code ref, and emits `$bf.filter($arr, <lambda>)`.
|
|
510
|
+
# `filter` returns a new arrayref; `every` / `some` return 1/0. Non-array /
|
|
511
|
+
# empty receivers follow JS (`filter` → [], `every` → true, `some` → false).
|
|
512
|
+
# (The Mojo adapter lowers these shapes inline and never reaches these methods.)
|
|
513
|
+
sub filter ($self, $recv, $pred) {
|
|
514
|
+
return [] unless ref($recv) eq 'ARRAY';
|
|
515
|
+
return [ grep { $pred->($_) } @$recv ];
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
sub every ($self, $recv, $pred) {
|
|
519
|
+
return 1 unless ref($recv) eq 'ARRAY';
|
|
520
|
+
for my $item (@$recv) { return 0 unless $pred->($item) }
|
|
521
|
+
return 1;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
sub some ($self, $recv, $pred) {
|
|
525
|
+
return 0 unless ref($recv) eq 'ARRAY';
|
|
526
|
+
for my $item (@$recv) { return 1 if $pred->($item) }
|
|
527
|
+
return 0;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
# `Array.prototype.find(fn)` / `.findIndex(fn)` / `.findLast(fn)` /
|
|
531
|
+
# `.findLastIndex(fn)` — same Kolon-lambda predicate mechanism as filter. The
|
|
532
|
+
# camelCase JS names lower to these snake_case methods (like index_of /
|
|
533
|
+
# last_index_of). `find` / `find_last` return the matching element (or undef →
|
|
534
|
+
# JS `undefined`); the index forms return the 0-based position (or -1).
|
|
535
|
+
sub find ($self, $recv, $pred) {
|
|
536
|
+
return undef unless ref($recv) eq 'ARRAY';
|
|
537
|
+
for my $item (@$recv) { return $item if $pred->($item) }
|
|
538
|
+
return undef;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
sub find_index ($self, $recv, $pred) {
|
|
542
|
+
return -1 unless ref($recv) eq 'ARRAY';
|
|
543
|
+
for my $i (0 .. $#$recv) { return $i if $pred->($recv->[$i]) }
|
|
544
|
+
return -1;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
sub find_last ($self, $recv, $pred) {
|
|
548
|
+
return undef unless ref($recv) eq 'ARRAY';
|
|
549
|
+
for my $i (reverse 0 .. $#$recv) { return $recv->[$i] if $pred->($recv->[$i]) }
|
|
550
|
+
return undef;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
sub find_last_index ($self, $recv, $pred) {
|
|
554
|
+
return -1 unless ref($recv) eq 'ARRAY';
|
|
555
|
+
for my $i (reverse 0 .. $#$recv) { return $i if $pred->($recv->[$i]) }
|
|
556
|
+
return -1;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
# `String.prototype.toLowerCase()` / `.toUpperCase()`. Kolon has a builtin
|
|
560
|
+
# `.join` array method (so the adapter uses that directly) but no builtin
|
|
561
|
+
# `lc` / `uc`, so these live on the runtime object. `CORE::` avoids recursing
|
|
562
|
+
# into these methods.
|
|
563
|
+
sub lc ($self, $s) { return defined $s ? CORE::lc($s) : '' }
|
|
564
|
+
sub uc ($self, $s) { return defined $s ? CORE::uc($s) : '' }
|
|
565
|
+
|
|
566
|
+
# `Array.prototype.join(sep)` with JS semantics: separator defaults to ",",
|
|
567
|
+
# and undefined / null elements render as empty (`[1,,2].join(",")` → "1,,2").
|
|
568
|
+
# Kolon has a builtin `.join`, but routing through the runtime keeps the
|
|
569
|
+
# JS-compat element handling in one place. `CORE::join` avoids recursing.
|
|
570
|
+
sub join ($self, $recv, $sep = undef) {
|
|
571
|
+
return '' unless ref($recv) eq 'ARRAY';
|
|
572
|
+
$sep //= ',';
|
|
573
|
+
return CORE::join($sep, map { defined $_ ? $_ : '' } @$recv);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
# `.length` — JS works on BOTH arrays (element count) and strings (character
|
|
577
|
+
# count); Kolon's builtin `.size()` is array-only and faults on a string. So
|
|
578
|
+
# dispatch on ref type here. `CORE::length` avoids recursing into this method.
|
|
579
|
+
sub length ($self, $recv) {
|
|
580
|
+
return scalar @$recv if ref($recv) eq 'ARRAY';
|
|
581
|
+
return 0 if ref($recv);
|
|
582
|
+
return CORE::length($recv // '');
|
|
583
|
+
}
|
|
584
|
+
|
|
507
585
|
# `Array.prototype.indexOf(x)` / `Array.prototype.lastIndexOf(x)`
|
|
508
586
|
# value-equality search (#1448 Tier A). Returns the 0-based position
|
|
509
587
|
# of the first / last matching element, or -1 if not found.
|
|
@@ -762,10 +840,10 @@ sub starts_with ($self, $recv, $prefix, $position = undef) {
|
|
|
762
840
|
if (defined $position) {
|
|
763
841
|
my $n = int($position);
|
|
764
842
|
$n = 0 if $n < 0;
|
|
765
|
-
$n = length($s) if $n > length($s);
|
|
843
|
+
$n = CORE::length($s) if $n > CORE::length($s);
|
|
766
844
|
$s = substr($s, $n);
|
|
767
845
|
}
|
|
768
|
-
return substr($s, 0, length $p) eq $p ? 1 : 0;
|
|
846
|
+
return substr($s, 0, CORE::length $p) eq $p ? 1 : 0;
|
|
769
847
|
}
|
|
770
848
|
|
|
771
849
|
# `String.prototype.endsWith(suffix, endPosition?)` (#1448 Tier B) —
|
|
@@ -782,12 +860,12 @@ sub ends_with ($self, $recv, $suffix, $end_position = undef) {
|
|
|
782
860
|
if (defined $end_position) {
|
|
783
861
|
my $e = int($end_position);
|
|
784
862
|
$e = 0 if $e < 0;
|
|
785
|
-
$e = length($s) if $e > length($s);
|
|
863
|
+
$e = CORE::length($s) if $e > CORE::length($s);
|
|
786
864
|
$s = substr($s, 0, $e);
|
|
787
865
|
}
|
|
788
866
|
return 1 if $x eq '';
|
|
789
|
-
return 0 if length($s) < length($x);
|
|
790
|
-
return substr($s, -length $x) eq $x ? 1 : 0;
|
|
867
|
+
return 0 if CORE::length($s) < CORE::length($x);
|
|
868
|
+
return substr($s, -CORE::length $x) eq $x ? 1 : 0;
|
|
791
869
|
}
|
|
792
870
|
|
|
793
871
|
# `String.prototype.replace(pattern, replacement)` — string-pattern
|
|
@@ -808,7 +886,7 @@ sub replace ($self, $recv, $pattern, $replacement) {
|
|
|
808
886
|
return $n . $s if $o eq '';
|
|
809
887
|
my $i = index($s, $o);
|
|
810
888
|
return $s if $i < 0;
|
|
811
|
-
return substr($s, 0, $i) . $n . substr($s, $i + length($o));
|
|
889
|
+
return substr($s, 0, $i) . $n . substr($s, $i + CORE::length($o));
|
|
812
890
|
}
|
|
813
891
|
|
|
814
892
|
# `String.prototype.repeat(n)` — the receiver concatenated n times
|
|
@@ -837,12 +915,12 @@ sub _pad ($s, $target, $pad, $at_start) {
|
|
|
837
915
|
$pad = ' ' unless defined $pad;
|
|
838
916
|
$pad = "$pad";
|
|
839
917
|
return $s if $pad eq '';
|
|
840
|
-
my $len = length $s;
|
|
918
|
+
my $len = CORE::length $s;
|
|
841
919
|
my $t = int($target // 0);
|
|
842
920
|
return $s if $len >= $t;
|
|
843
921
|
my $need = $t - $len;
|
|
844
922
|
# Repeat enough copies to cover $need, then trim to exactly $need.
|
|
845
|
-
my $fill = substr($pad x (int($need / length($pad)) + 1), 0, $need);
|
|
923
|
+
my $fill = substr($pad x (int($need / CORE::length($pad)) + 1), 0, $need);
|
|
846
924
|
return $at_start ? $fill . $s : $s . $fill;
|
|
847
925
|
}
|
|
848
926
|
|
|
@@ -1097,7 +1175,7 @@ sub _style_to_css ($value) {
|
|
|
1097
1175
|
# `typeof value !== 'object'` branch in `styleToCss`.
|
|
1098
1176
|
if (ref($value) ne 'HASH') {
|
|
1099
1177
|
my $s = "$value";
|
|
1100
|
-
return length $s ? $s : undef;
|
|
1178
|
+
return CORE::length $s ? $s : undef;
|
|
1101
1179
|
}
|
|
1102
1180
|
my @parts;
|
|
1103
1181
|
for my $key (sort keys %$value) {
|
|
@@ -1107,7 +1185,7 @@ sub _style_to_css ($value) {
|
|
|
1107
1185
|
$prop =~ s/([A-Z])/-\L$1/g;
|
|
1108
1186
|
push @parts, "$prop:$v";
|
|
1109
1187
|
}
|
|
1110
|
-
return @parts ? join(';', @parts) : undef;
|
|
1188
|
+
return @parts ? CORE::join(';', @parts) : undef;
|
|
1111
1189
|
}
|
|
1112
1190
|
|
|
1113
1191
|
sub spread_attrs ($self, $bag) {
|
|
@@ -1117,9 +1195,9 @@ sub spread_attrs ($self, $bag) {
|
|
|
1117
1195
|
# Event handlers: skip when key starts `on` and the third
|
|
1118
1196
|
# character is its own uppercase form (uppercase letter,
|
|
1119
1197
|
# digit, underscore, …). Mirrors the JS predicate.
|
|
1120
|
-
if (length($key) > 2 && substr($key, 0, 2) eq 'on') {
|
|
1198
|
+
if (CORE::length($key) > 2 && substr($key, 0, 2) eq 'on') {
|
|
1121
1199
|
my $c = substr($key, 2, 1);
|
|
1122
|
-
next if uc($c) eq $c;
|
|
1200
|
+
next if CORE::uc($c) eq $c;
|
|
1123
1201
|
}
|
|
1124
1202
|
next if $key eq 'children';
|
|
1125
1203
|
my $val = $bag->{$key};
|
|
@@ -1143,7 +1221,7 @@ sub spread_attrs ($self, $bag) {
|
|
|
1143
1221
|
# serialise to a real CSS string.
|
|
1144
1222
|
if ($key eq 'style') {
|
|
1145
1223
|
my $css = _style_to_css($val);
|
|
1146
|
-
next unless defined $css && length $css;
|
|
1224
|
+
next unless defined $css && CORE::length $css;
|
|
1147
1225
|
push @parts, qq{style="} . _html_escape($css) . qq{"};
|
|
1148
1226
|
next;
|
|
1149
1227
|
}
|
|
@@ -1154,7 +1232,7 @@ sub spread_attrs ($self, $bag) {
|
|
|
1154
1232
|
# Mark the result raw so the calling template's `<%==` raw-emit
|
|
1155
1233
|
# doesn't re-escape the already-escaped values (the Mojo backend
|
|
1156
1234
|
# returns a Mojo::ByteStream).
|
|
1157
|
-
return $self->backend->mark_raw(join(' ', @parts));
|
|
1235
|
+
return $self->backend->mark_raw(CORE::join(' ', @parts));
|
|
1158
1236
|
}
|
|
1159
1237
|
|
|
1160
1238
|
1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/perl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "BarefootJS engine-agnostic Perl runtime (BarefootJS.pm) — pluggable rendering backend; the shared basis for Mojolicious and other Perl framework integrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|