Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions src/Parser/Tokenizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Livewire\Blaze\Parser\Tokens\TagOpenToken;
use Livewire\Blaze\Parser\Tokens\TextToken;
use Livewire\Blaze\Parser\Tokens\Token;
use Livewire\Blaze\Support\LaravelRegex;

/**
* Finite state machine that lexes Blade templates into component/slot/text tokens.
Expand Down Expand Up @@ -127,6 +128,10 @@ protected function handleTextState(): TokenizerState

$this->advance(strlen('</' . $slotInfo['prefix']));

if ($this->current() === ':') {
$this->advance();
}

return TokenizerState::SLOT_CLOSE;
}

Expand Down Expand Up @@ -279,14 +284,10 @@ protected function handleSlotOpenState(): TokenizerState
*/
protected function handleSlotCloseState(): TokenizerState
{
if ($this->match('/^:[a-zA-Z0-9-]+/')) {
$matches = [];

preg_match('/^:[a-zA-Z0-9-]+/', $this->remaining(), $matches);

$this->currentToken->name = substr($matches[0], 1);
if ($name = $this->matchSlotName()) {
$this->currentToken->name = $name;

$this->advance(strlen($matches[0]));
$this->advance(strlen($name));
}

if ($this->current() === '>') {
Expand Down Expand Up @@ -520,11 +521,11 @@ protected function matchComponentClose(): ?array
}

/**
* Match a tag name (alphanumeric, hyphens, dots, colons) at the current position.
* Match a tag name at the current position.
*/
protected function matchTagName(): ?string
{
if (preg_match('/^[a-zA-Z0-9-\.:]+/', $this->remaining(), $matches)) {
if (preg_match(LaravelRegex::TAG_NAME, $this->remaining(), $matches)) {
return $matches[0];
}

Expand All @@ -536,7 +537,7 @@ protected function matchTagName(): ?string
*/
protected function matchSlotName(): ?string
{
if (preg_match('/^[a-zA-Z0-9-]+/', $this->remaining(), $matches)) {
if (preg_match(LaravelRegex::SLOT_INLINE_NAME, $this->remaining(), $matches)) {
return $matches[0];
}

Expand Down
32 changes: 32 additions & 0 deletions src/Support/LaravelRegex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Livewire\Blaze\Support;

/**
* Regex patterns sourced from Laravel's ComponentTagCompiler.
*
* Every constant in this class MUST match the corresponding regex
* in Laravel's source exactly. Do not modify these without first
* verifying the change against the Laravel source cited in each
* constant's docblock.
*
* @see vendor/laravel/framework/src/Illuminate/View/Compilers/ComponentTagCompiler.php
*/
class LaravelRegex
{
/**
* Pattern for matching a component tag name at the current position.
*
* @see ComponentTagCompiler::compileOpeningTags() — x[-\:]([\w\-\:\.]*)
* @see ComponentTagCompiler::compileSelfClosingTags() — x[-\:]([\w\-\:\.]*)
* @see ComponentTagCompiler::compileClosingTags() — x[-\:][\w\-\:\.]*
*/
const TAG_NAME = '/^[\w\-\:\.]*/';

/**
* Pattern for matching a slot inline name (e.g., <x-slot:header>).
*
* @see ComponentTagCompiler::compileSlots() — (\w+(?:-\w+)*)
*/
const SLOT_INLINE_NAME = '/^\w+(?:-\w+)*/';
}