Skip to content

Commit a7de35a

Browse files
authored
Merge pull request #6789 from ddevsr/solidus-html
feat: void element tags in helpers are selectable between `>` and `/>`
2 parents 0e3d5cc + 6540df0 commit a7de35a

35 files changed

+402
-85
lines changed

app/Config/DocTypes.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,14 @@ class DocTypes
3030
'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
3131
'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">',
3232
];
33+
34+
/**
35+
* Whether to remove the solidus (`/`) character for void HTML elements (e.g. `<input>`)
36+
* for HTML5 compatibility.
37+
*
38+
* Set to:
39+
* `true` - to be HTML5 compatible
40+
* `false` - to be XHTML compatible
41+
*/
42+
public bool $html5 = true;
3343
}

system/Common.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ function csrf_hash(): string
281281
*/
282282
function csrf_field(?string $id = null): string
283283
{
284-
return '<input type="hidden"' . (! empty($id) ? ' id="' . esc($id, 'attr') . '"' : '') . ' name="' . csrf_token() . '" value="' . csrf_hash() . '" />';
284+
return '<input type="hidden"' . (! empty($id) ? ' id="' . esc($id, 'attr') . '"' : '') . ' name="' . csrf_token() . '" value="' . csrf_hash() . '"' . _solidus() . '>';
285285
}
286286
}
287287

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

@@ -852,6 +852,22 @@ function redirect(?string $route = null): RedirectResponse
852852
}
853853
}
854854

855+
if (! function_exists('_solidus')) {
856+
/**
857+
* Generates the solidus character (`/`) depending on the HTML5 compatibility flag in `Config\DocTypes`
858+
*
859+
* @internal
860+
*/
861+
function _solidus(): string
862+
{
863+
if (config('DocTypes')->html5 ?? false) {
864+
return '';
865+
}
866+
867+
return ' /';
868+
}
869+
}
870+
855871
if (! function_exists('remove_invisible_characters')) {
856872
/**
857873
* Remove Invisible Characters

system/Helpers/form_helper.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ function form_input($data = '', string $value = '', $extra = '', string $type =
148148
'value' => $value,
149149
];
150150

151-
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
151+
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . _solidus() . ">\n";
152152
}
153153
}
154154

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

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

197-
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
197+
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . _solidus() . ">\n";
198198
}
199199
}
200200

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

368-
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . " />\n";
368+
return '<input ' . parse_form_attributes($data, $defaults) . stringify_attributes($extra) . _solidus() . ">\n";
369369
}
370370
}
371371

system/Helpers/html_helper.php

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function img($src = '', bool $indexPage = false, $attributes = ''): string
128128
unset($attributes['alt'], $attributes['src']);
129129
}
130130

131-
return $img . stringify_attributes($attributes) . ' />';
131+
return $img . stringify_attributes($attributes) . _solidus() . '>';
132132
}
133133
}
134134

@@ -229,8 +229,6 @@ function script_tag($src = '', bool $indexPage = false): string
229229
*/
230230
function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/css', string $title = '', string $media = '', bool $indexPage = false, string $hreflang = ''): string
231231
{
232-
$link = '<link ';
233-
234232
// extract fields if needed
235233
if (is_array($href)) {
236234
$rel = $href['rel'] ?? $rel;
@@ -243,34 +241,30 @@ function link_tag($href = '', string $rel = 'stylesheet', string $type = 'text/c
243241
}
244242

245243
if (! preg_match('#^([a-z]+:)?//#i', $href)) {
246-
if ($indexPage === true) {
247-
$link .= 'href="' . site_url($href) . '" ';
248-
} else {
249-
$link .= 'href="' . slash_item('baseURL') . $href . '" ';
250-
}
244+
$attributes['href'] = $indexPage ? site_url($href) : slash_item('baseURL') . $href;
251245
} else {
252-
$link .= 'href="' . $href . '" ';
246+
$attributes['href'] = $href;
253247
}
254248

255249
if ($hreflang !== '') {
256-
$link .= 'hreflang="' . $hreflang . '" ';
250+
$attributes['hreflang'] = $hreflang;
257251
}
258252

259-
$link .= 'rel="' . $rel . '" ';
253+
$attributes['rel'] = $rel;
260254

261255
if (! in_array($rel, ['alternate', 'canonical'], true)) {
262-
$link .= 'type="' . $type . '" ';
256+
$attributes['type'] = $type;
263257
}
264258

265259
if ($media !== '') {
266-
$link .= 'media="' . $media . '" ';
260+
$attributes['media'] = $media;
267261
}
268262

269263
if ($title !== '') {
270-
$link .= 'title="' . $title . '" ';
264+
$attributes['title'] = $title;
271265
}
272266

273-
return $link . '/>';
267+
return '<link' . stringify_attributes($attributes) . _solidus() . '>';
274268
}
275269
}
276270

@@ -423,7 +417,7 @@ function source(string $src, string $type = 'unknown', string $attributes = '',
423417
$source .= ' ' . $attributes;
424418
}
425419

426-
return $source . ' />';
420+
return $source . _solidus() . '>';
427421
}
428422
}
429423

@@ -442,7 +436,7 @@ function track(string $src, string $kind, string $srcLanguage, string $label): s
442436
. '" kind="' . $kind
443437
. '" srclang="' . $srcLanguage
444438
. '" label="' . $label
445-
. '" />';
439+
. '"' . _solidus() . '>';
446440
}
447441
}
448442

@@ -496,7 +490,7 @@ function param(string $name, string $value, string $type = 'ref', string $attrib
496490
return '<param name="' . $name
497491
. '" type="' . $type
498492
. '" value="' . $value
499-
. '" ' . $attributes . ' />';
493+
. '" ' . $attributes . _solidus() . '>';
500494
}
501495
}
502496

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

519513
return '<embed src="' . $src
520514
. '" type="' . $type . '" '
521-
. $attributes . " />\n";
515+
. $attributes . _solidus() . ">\n";
522516
}
523517
}
524518

tests/system/CommonFunctionsTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,23 @@ public function testResponse()
163163
$this->assertInstanceOf(Response::class, $response);
164164
}
165165

166+
public function testSolidusElement()
167+
{
168+
$this->assertSame('', _solidus());
169+
}
170+
171+
public function testSolidusElementXHTML()
172+
{
173+
$doctypes = config('DocTypes');
174+
$default = $doctypes->html5;
175+
$doctypes->html5 = false;
176+
177+
$this->assertSame(' /', _solidus());
178+
179+
// Reset
180+
$doctypes->html5 = $default;
181+
}
182+
166183
public function testView()
167184
{
168185
$data = [

0 commit comments

Comments
 (0)