diff --git a/src/Illuminate/Support/Facades/Request.php b/src/Illuminate/Support/Facades/Request.php index 045a07fd1f42..82fecbe7d306 100755 --- a/src/Illuminate/Support/Facades/Request.php +++ b/src/Illuminate/Support/Facades/Request.php @@ -65,6 +65,8 @@ * @method static string normalizeQueryString(string|null $qs) * @method static void enableHttpMethodParameterOverride() * @method static bool getHttpMethodParameterOverride() + * @method static void setAllowedHttpMethodOverride(array|null $methods) + * @method static array|null getAllowedHttpMethodOverride() * @method static bool hasPreviousSession() * @method static void setSession(\Symfony\Component\HttpFoundation\Session\SessionInterface $session) * @method static array getClientIps() diff --git a/src/Illuminate/View/ComponentAttributeBag.php b/src/Illuminate/View/ComponentAttributeBag.php index 607f4d134301..94288c441fc9 100644 --- a/src/Illuminate/View/ComponentAttributeBag.php +++ b/src/Illuminate/View/ComponentAttributeBag.php @@ -491,11 +491,26 @@ public function __toString() continue; } + // Empty "alt" explicitly marks an image as decorative; empty "value" and "data-*" + // are valid. For everything else we don't want to render the attribute at all. + if (!in_array($key, ['alt', 'value']) && !str_starts_with($key, 'data') && (is_string($value) && trim($value) === '')) { + continue; + } + if ($value === true) { $value = $key === 'x-data' || str_starts_with($key, 'wire:') ? '' : $key; } - $string .= ' '.$key.'="'.str_replace('"', '\\"', trim($value)).'"'; + // Same as above. We want everything but data and value to be trimmed + $value = !str_starts_with($key, 'data') && $key !== 'value' + ? trim($value) + : $value; + + if($key === $value) { + $string .= ' '.$key; + } else { + $string .= ' '.$key.'="'.str_replace('"', '\\"', $value).'"'; + } } return trim($string); diff --git a/tests/View/ViewComponentAttributeBagTest.php b/tests/View/ViewComponentAttributeBagTest.php index a2293e6e5f19..225ac0cf671c 100644 --- a/tests/View/ViewComponentAttributeBagTest.php +++ b/tests/View/ViewComponentAttributeBagTest.php @@ -51,10 +51,15 @@ public function testAttributeRetrieval() 'test-0' => 0, 'test-0-string' => '0', 'test-empty-string' => '', + 'test-whitespace-string' => ' ', + 'data-test-empty-string' => '', + 'data-test-whitespace-string' => ' ', + 'value' => ' ', + 'alt' => '', ]); - $this->assertSame('test-string="ok" test-true="test-true" test-0="0" test-0-string="0" test-empty-string=""', (string) $bag); - $this->assertSame('test-string="ok" test-true="test-true" test-0="0" test-0-string="0" test-empty-string=""', (string) $bag->merge()); + $this->assertSame('test-string="ok" test-true test-0="0" test-0-string="0" data-test-empty-string="" data-test-whitespace-string=" " value=" " alt=""', (string) $bag); + $this->assertSame('test-string="ok" test-true test-0="0" test-0-string="0" data-test-empty-string="" data-test-whitespace-string=" " value=" " alt=""', (string) $bag->merge()); $bag = (new ComponentAttributeBag) ->merge([ @@ -72,10 +77,14 @@ public function testAttributeRetrieval() 'test-0' => 0, 'test-0-string' => '0', 'test-empty-string' => '', + 'test-whitespace-string' => ' ', + 'data-test-empty-string' => '', + 'data-test-whitespace-string' => ' ', + 'value' => ' ', + 'alt' => '', ]); - $this->assertSame('test-string="ok" test-true="test-true" test-0="0" test-0-string="0" test-empty-string=""', (string) $bag); - + $this->assertSame('test-string="ok" test-true test-0="0" test-0-string="0" data-test-empty-string="" data-test-whitespace-string=" " value=" " alt=""', (string) $bag); $bag = (new ComponentAttributeBag) ->merge([ 'test-extract-1' => 'extracted-1', @@ -151,7 +160,7 @@ public function testItMakesAnExceptionForAlpineXdata() 'x-data' => true, ]); - $this->assertSame('required="required" x-data=""', (string) $bag); + $this->assertSame('required x-data=""', (string) $bag); } public function testItMakesAnExceptionForLivewireWireAttributes()