Skip to content

Commit

Permalink
Merge pull request #986 from svenluijten/attributes-without-values
Browse files Browse the repository at this point in the history
Allow adding attributes without value
  • Loading branch information
colinodell authored Jul 31, 2023
2 parents 4aec9f5 + a8076d8 commit 2138460
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi

## [Unreleased][unreleased]

### Added

- The `AttributesExtension` now supports attributes without values (#985, #986)

## [2.4.0] - 2023-03-24

### Added
Expand Down
10 changes: 8 additions & 2 deletions src/Extension/Attributes/Util/AttributesHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
final class AttributesHelper
{
private const SINGLE_ATTRIBUTE = '\s*([.#][_a-z0-9-]+|' . RegexHelper::PARTIAL_ATTRIBUTENAME . RegexHelper::PARTIAL_ATTRIBUTEVALUESPEC . ')\s*';
private const SINGLE_ATTRIBUTE = '\s*([.#][_a-z0-9-]+|' . RegexHelper::PARTIAL_ATTRIBUTENAME . RegexHelper::PARTIAL_ATTRIBUTEVALUESPEC . '?)\s*';
private const ATTRIBUTE_LIST = '/^{:?(' . self::SINGLE_ATTRIBUTE . ')+}/i';

/**
Expand Down Expand Up @@ -72,8 +72,14 @@ public static function parseAttributes(Cursor $cursor): array
continue;
}

$parts = \explode('=', $attribute, 2);
if (\count($parts) === 1) {
$attributes[$attribute] = true;
continue;
}

/** @psalm-suppress PossiblyUndefinedArrayOffset */
[$name, $value] = \explode('=', $attribute, 2);
[$name, $value] = $parts;

$first = $value[0];
$last = \substr($value, -1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ <h2 class="main shine" id="the-site">The Site</h2>
<p>Attributes without quote and non-whitespace char <a target="_blank" href="http://url.com" rel="noopener noreferrer">link</a></p>
<p>Attributes without quote and non-whitespace char and a dot <a target="_blank" href="http://url.com" rel="noopener noreferrer">link</a>.</p>
<p>Multiple attributes without quote and non-whitespace char and a dot <a class="class" id="id" target="_blank" href="http://url.com" rel="noopener noreferrer">link</a>.</p>
<p><img valueless-attribute src="/assets/image.jpg" alt="image" /></p>
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ Attributes without quote and non-whitespace char [link](http://url.com){target=_
Attributes without quote and non-whitespace char and a dot [link](http://url.com){target=_blank}.

Multiple attributes without quote and non-whitespace char and a dot [link](http://url.com){#id .class target=_blank}.

![image](/assets/image.jpg){valueless-attribute}
6 changes: 4 additions & 2 deletions tests/unit/Extension/Attributes/Util/AttributesHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ public function dataForTestParseAttributes(): iterable
yield [new Cursor('{: #custom-id }'), ['id' => 'custom-id']];
yield [new Cursor('{: #custom-id #another-id }'), ['id' => 'another-id']];
yield [new Cursor('{: .class1 .class2 }'), ['class' => 'class1 class2']];
yield [new Cursor('{: #custom-id .class1 .class2 title="My Title" }'), ['id' => 'custom-id', 'class' => 'class1 class2', 'title' => 'My Title']];
yield [new Cursor('{: #custom-id .class1 .class2 title="My Title" disabled }'), ['id' => 'custom-id', 'class' => 'class1 class2', 'title' => 'My Title', 'disabled' => true]];
yield [new Cursor('{:target=_blank}'), ['target' => '_blank']];
yield [new Cursor('{: target=_blank}'), ['target' => '_blank']];
yield [new Cursor('{: target=_blank }'), ['target' => '_blank']];
yield [new Cursor('{: target=_blank }'), ['target' => '_blank']];
yield [new Cursor('{: disabled}'), ['disabled' => true]];

// Examples without colons
yield [new Cursor('{title="My Title"}'), ['title' => 'My Title']];
Expand All @@ -68,11 +69,12 @@ public function dataForTestParseAttributes(): iterable
yield [new Cursor('{ #custom-id }'), ['id' => 'custom-id']];
yield [new Cursor('{ #custom-id #another-id }'), ['id' => 'another-id']];
yield [new Cursor('{ .class1 .class2 }'), ['class' => 'class1 class2']];
yield [new Cursor('{ #custom-id .class1 .class2 title="My Title" }'), ['id' => 'custom-id', 'class' => 'class1 class2', 'title' => 'My Title']];
yield [new Cursor('{ #custom-id .class1 .class2 title="My Title" disabled }'), ['id' => 'custom-id', 'class' => 'class1 class2', 'title' => 'My Title', 'disabled' => true]];
yield [new Cursor('{target=_blank}'), ['target' => '_blank']];
yield [new Cursor('{ target=_blank}'), ['target' => '_blank']];
yield [new Cursor('{target=_blank }'), ['target' => '_blank']];
yield [new Cursor('{ target=_blank }'), ['target' => '_blank']];
yield [new Cursor('{disabled}'), ['disabled' => true]];

// Stuff at the beginning
yield [new Cursor(' {: #custom-id }'), ['id' => 'custom-id']];
Expand Down

0 comments on commit 2138460

Please sign in to comment.