From c0a06671fed8db601bb680dc4d5accf3cd9deb81 Mon Sep 17 00:00:00 2001 From: Chris How Date: Wed, 3 Jan 2024 19:33:56 +0100 Subject: [PATCH] Implement 'equals starts with' ('^=') and 'equals or starts with hyphenated' ('|=') selectors (#221) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve detection of element in query * style: reformat * style: reformat * test: multiple named selects * Implement 'equals starts with' ('^=') and 'equals or starts with hyphenated' ('|=') selectors --------- Co-authored-by: Tomáš Fedor Co-authored-by: Greg Bowler --- src/Translator.php | 23 ++++++++++++++++++----- test/phpunit/TranslatorTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Translator.php b/src/Translator.php index 2bcbee8..c785594 100644 --- a/src/Translator.php +++ b/src/Translator.php @@ -12,7 +12,7 @@ class Translator { . '|(#(?P[\w-]*))' . '|(\.(?P[\w-]*))' . '|(?P\s*\+\s*)' - . "|(\[(?P[\w-]*)((?P[=~$*]+)(?P(.+\[\]'?)|[^\]]+))*\])+" + . "|(\[(?P[\w-]*)((?P[=~$|^*]+)(?P(.+\[\]'?)|[^\]]+))*\])+" . '|(?P\s+)' . '/'; @@ -20,7 +20,7 @@ class Translator { const EQUALS_CONTAINS_WORD = "~="; const EQUALS_ENDS_WITH = "$="; const EQUALS_CONTAINS = "*="; - const EQUALS_STARTS_WITH_OR_STARTS_WITH_HYPHENATED = "|="; + const EQUALS_OR_STARTS_WITH_HYPHENATED = "|="; const EQUALS_STARTS_WITH = "^="; public function __construct( @@ -245,11 +245,24 @@ protected function convertSingleSelector(string $css):string { ); break; - case self::EQUALS_STARTS_WITH_OR_STARTS_WITH_HYPHENATED: - throw new NotYetImplementedException(); + case self::EQUALS_OR_STARTS_WITH_HYPHENATED: + array_push( + $xpath, + "[" + . "@{$currentThreadItem['content']}=\"{$valueString}\" or " + . "starts-with(@{$currentThreadItem['content']}, \"{$valueString}-\")" + . "]" + ); + break; case self::EQUALS_STARTS_WITH: - throw new NotYetImplementedException(); + array_push( + $xpath, + "[starts-with(" + . "@{$currentThreadItem['content']}, \"{$valueString}\"" + . ")]" + ); + break; case self::EQUALS_ENDS_WITH: array_push( diff --git a/test/phpunit/TranslatorTest.php b/test/phpunit/TranslatorTest.php index edbeebc..cc4a6ec 100644 --- a/test/phpunit/TranslatorTest.php +++ b/test/phpunit/TranslatorTest.php @@ -320,6 +320,30 @@ public function testAttributeDollarSelector() { ); } + public function testAttributeEqualsOrStartsWithHypehnatedSelector() { + $document = new DOMDocument("1.0", "UTF-8"); + $document->loadHTML("
"); + $xpath = new DOMXPath($document); + + $selector = new Translator("[class|=en]"); + self::assertEquals( + 3, + $xpath->query($selector)->length + ); + } + + public function testAttributeStartsWithSelector() { + $document = new DOMDocument("1.0", "UTF-8"); + $document->loadHTML("
"); + $xpath = new DOMXPath($document); + + $selector = new Translator("[class^=class1]"); + self::assertEquals( + 2, + $xpath->query($selector)->length + ); + } + public function testClassSelector() { $document = new DOMDocument("1.0", "UTF-8"); $document->loadHTML(Helper::HTML_COMPLEX);