Fix positional multi-select list compatibility

ⓘ Preserve selected labels, value order and pre-escaped text when callers omit the options hash.
This commit is contained in:
Ilia Ross
2026-09-09 13:29:32 +02:00
parent 29aa16e6d4
commit bbd9a56e42
2 changed files with 18 additions and 6 deletions

View File

@@ -509,6 +509,17 @@ like(main::ui_form_columns_table('x.cgi', [ [ 'go', 'Go' ] ], 0, undef, undef,
is_deeply(\@disabled, [ 1, 0 ], 'themes receive the normalized disabled state');
}
# Three-argument callers retain legacy selected labels and order.
{
my $values = [ [ 'b', 'Selected & saved' ], [ 'a', 'A' ] ];
my $options = [ [ 'a', 'R&D' ], [ 'b', 'Available' ] ];
my $html = main::ui_multi_select_list('short', $values, $options);
like($html, qr/name="short"[^>]*value="b\na"/,
'omitting size preserves the supplied selection order');
like($html, qr/>Selected &amp; saved</,
'omitting size preserves the selected description and escaped text');
}
# Positional calls preserve the old selected pane's labels and value order.
{
my @values = ( [ 'b', 'B (selected)', q{disabled title="Selected"} ],
@@ -561,7 +572,7 @@ like(main::ui_form_columns_table('x.cgi', [ [ 'go', 'Go' ] ], 0, undef, undef,
my ($filter) = $html =~ /data-ui-multi-text="([^"]*)"/;
is($filter, $label, 'filter label retains original UTF-8 bytes and case');
my $literal = 'R&amp;D';
$html = main::ui_multi_select_list('g', [ ], [ [ 'team', $literal ] ]);
$html = main::ui_multi_select_list('g', [ ], [ [ 'team', $literal ] ], {});
($filter) = $html =~ /data-ui-multi-text="([^"]*)"/;
is(decode_attr($filter), $literal,
'filter text preserves literal HTML entity names in plain labels');

View File

@@ -5727,10 +5727,11 @@ Shift-click applies the clicked state from the last clicked entry to the
current one, skipping filtered, folded and disabled entries. Labels and row
backgrounds work too.
Accepts an options hash or ui_multi_select's trailing positional arguments.
Positional calls preserve selected labels, attributes, value order and
pre-escaped label text. Newly selected entries are prepended as in the old
widget. Size, add-if-missing, titles and width are ignored.
Accepts an options hash or the legacy trailing positional arguments.
Calls without an options hash preserve selected labels, attributes, value
order and pre-escaped label text. Newly selected entries are prepended as in the old
widget. Pass an options hash (even empty) for plain labels and option ordering.
Size, add-if-missing, titles and width are ignored.
=item name - HTML name for the input.
@@ -5764,7 +5765,7 @@ sub ui_multi_select_list
return &theme_ui_multi_select_list(@_)
if (defined(&theme_ui_multi_select_list));
my ($name, $values, $options, $opts) = @_;
my $legacy = @_ > 3 && ref($opts) ne 'HASH';
my $legacy = ref($opts) ne 'HASH';
if (ref($opts) ne 'HASH') {
# Accept ui_multi_select's positional disabled argument.
$opts = { 'disabled' => $_[5] };