\*)' . '|(:(?P[\w-]*))' . '|\((?P[^)]*)\)' . '|(?P[\w-]*)' . '|(?P\s*>\s*)' . '|(#(?P[\w-]*))' . '|(\.(?P[\w-]*))' . '|(?P\s*\+\s*)' . '|(?P\s*~\s*)' . "|(\[(?P[\w-]*)((?P[=~$|^*]+)" . "(?P(.+\[\]'?)|[^\]]+))*\])+" . '|(?P\s+)' . '/'; public const EQUALS_EXACT = "="; public const EQUALS_CONTAINS_WORD = "~="; public const EQUALS_ENDS_WITH = "$="; public const EQUALS_CONTAINS = "*="; public const EQUALS_OR_STARTS_WITH_HYPHENATED = "|="; public const EQUALS_STARTS_WITH = "^="; private SingleSelectorConverter $singleSelectorConverter; private SelectorListSplitter $selectorListSplitter; public function __construct( protected string $cssSelector, protected string $prefix = ".//", protected bool $htmlMode = true, ?SingleSelectorConverter $singleSelectorConverter = null, ?SelectorListSplitter $selectorListSplitter = null, ) { $this->singleSelectorConverter = $singleSelectorConverter ?? new SingleSelectorConverter(); $this->selectorListSplitter = $selectorListSplitter ?? new SelectorListSplitter(); } public function __toString():string { return $this->convert($this->cssSelector); } // phpcs:disable Generic.NamingConventions.CamelCapsFunctionName public function asXPath():string { return $this->convert($this->cssSelector); } // phpcs:enable protected function convert(string $css):string { $cssArray = $this->selectorListSplitter->split($css); $xPathArray = []; foreach($cssArray as $input) { $xPathArray[] = $this->convertSingleSelector(trim($input)); } return implode(" | ", $xPathArray); } protected function convertSingleSelector(string $css):string { return $this->singleSelectorConverter->convert( $css, $this->prefix, $this->htmlMode ); } }