Skip to content

feat: void element tags in helpers are selectable between > and /> #6789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 1, 2022
10 changes: 10 additions & 0 deletions app/Config/DocTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,14 @@ class DocTypes
'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">',
];

/**
* Whether to remove the solidus (`/`) character for void HTML elements (e.g. `<input>`)
* for HTML5 compatibility.
*
* Set to:
* `true` - to be HTML5 compatible
* `false` - to be XHTML compatible
*/
public bool $html5 = true;
}
20 changes: 18 additions & 2 deletions system/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ function csrf_hash(): string
*/
function csrf_field(?string $id = null): string
{
return '<input type="hidden"' . (! empty($id) ? ' id="' . esc($id, 'attr') . '"' : '') . ' name="' . csrf_token() . '" value="' . csrf_hash() . '" />';
return '<input type="hidden"' . (! empty($id) ? ' id="' . esc($id, 'attr') . '"' : '') . ' name="' . csrf_token() . '" value="' . csrf_hash() . '"' . _solidus() . '>';
}
}

Expand All @@ -291,7 +291,7 @@ function csrf_field(?string $id = null): string
*/
function csrf_meta(?string $id = null): string
{
return '<meta' . (! empty($id) ? ' id="' . esc($id, 'attr') . '"' : '') . ' name="' . csrf_header() . '" content="' . csrf_hash() . '" />';
return '<meta' . (! empty($id) ? ' id="' . esc($id, 'attr') . '"' : '') . ' name="' . csrf_header() . '" content="' . csrf_hash() . '"' . _solidus() . '>';
}
}

Expand Down Expand Up @@ -852,6 +852,22 @@ function redirect(?string $route = null): RedirectResponse
}
}

if (! function_exists('_solidus')) {
/**
* Generates the solidus character (`/`) depending on the HTML5 compatibility flag in `Config\DocTypes`
*
* @internal
*/
function _solidus(): string
{
if (config('DocTypes')->html5 ?? false) {
return '';
}

return ' /';
}
}

if (! function_exists('remove_invisible_characters')) {
/**
* Remove Invisible Characters
Expand Down
6 changes: 3 additions & 3 deletions system/Helpers/form_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ function form_input($data = '', string $value = '', $extra = '', string $type =
'value' => $value,
];

return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . _solidus() . ">\n";
}
}

Expand Down Expand Up @@ -194,7 +194,7 @@ function form_upload($data = '', string $value = '', $extra = ''): string

$data['type'] = 'file';

return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . _solidus() . ">\n";
}
}

Expand Down Expand Up @@ -365,7 +365,7 @@ function form_checkbox($data = '', string $value = '', bool $checked = false, $e
$defaults['checked'] = 'checked';
}

return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . _solidus() . ">\n";
}
}

Expand Down
32 changes: 13 additions & 19 deletions system/Helpers/html_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function img($src = '', bool $indexPage = false, $attributes = ''): string
unset($attributes['alt'], $attributes['src']);
}

return $img . stringify_attributes($attributes) . ' />';
return $img . stringify_attributes($attributes) . _solidus() . '>';
}
}

Expand Down Expand Up @@ -229,8 +229,6 @@ function script_tag($src = '', bool $indexPage = false): string
*/
function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/css', string $title = '', string $media = '', bool $indexPage = false, string $hreflang = ''): string
{
$link = '<link ';

// extract fields if needed
if (is_array($href)) {
$rel = $href['rel'] ?? $rel;
Expand All @@ -243,34 +241,30 @@ function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/c
}

if (! preg_match('#^([a-z]+:)?//#i', $href)) {
if ($indexPage === true) {
$link .= 'href="' . site_url($href) . '" ';
} else {
$link .= 'href="' . slash_item('baseURL') . $href . '" ';
}
$attributes['href'] = $indexPage ? site_url($href) : slash_item('baseURL') . $href;
} else {
$link .= 'href="' . $href . '" ';
$attributes['href'] = $href;
}

if ($hreflang !== '') {
$link .= 'hreflang="' . $hreflang . '" ';
$attributes['hreflang'] = $hreflang;
}

$link .= 'rel="' . $rel . '" ';
$attributes['rel'] = $rel;

if (! in_array($rel, ['alternate', 'canonical'], true)) {
$link .= 'type="' . $type . '" ';
$attributes['type'] = $type;
}

if ($media !== '') {
$link .= 'media="' . $media . '" ';
$attributes['media'] = $media;
}

if ($title !== '') {
$link .= 'title="' . $title . '" ';
$attributes['title'] = $title;
}

return $link . '/>';
return '<link' . stringify_attributes($attributes) . _solidus() . '>';
}
}

Expand Down Expand Up @@ -423,7 +417,7 @@ function source(string $src, string $type = 'unknown', string $attributes = '',
$source .= ' ' . $attributes;
}

return $source . ' />';
return $source . _solidus() . '>';
}
}

Expand All @@ -442,7 +436,7 @@ function track(string $src, string $kind, string $srcLanguage, string $label): s
. '" kind="' . $kind
. '" srclang="' . $srcLanguage
. '" label="' . $label
. '" />';
. '"' . _solidus() . '>';
}
}

Expand Down Expand Up @@ -496,7 +490,7 @@ function param(string $name, string $value, string $type = 'ref', string $attrib
return '<param name="' . $name
. '" type="' . $type
. '" value="' . $value
. '" ' . $attributes . ' />';
. '" ' . $attributes . _solidus() . '>';
}
}

Expand All @@ -518,7 +512,7 @@ function embed(string $src, string $type = 'unknown', string $attributes = '', b

return '<embed src="' . $src
. '" type="' . $type . '" '
. $attributes . " />\n";
. $attributes . _solidus() . ">\n";
}
}

Expand Down
17 changes: 17 additions & 0 deletions tests/system/CommonFunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,23 @@ public function testResponse()
$this->assertInstanceOf(Response::class, $response);
}

public function testSolidusElement()
{
$this->assertSame('', _solidus());
}

public function testSolidusElementXHTML()
{
$doctypes = config('DocTypes');
$default = $doctypes->html5;
$doctypes->html5 = false;

$this->assertSame(' /', _solidus());

// Reset
$doctypes->html5 = $default;
}

public function testView()
{
$data = [
Expand Down
Loading