Translator.php 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. namespace Gt\CssXPath;
  3. class Translator {
  4. public const CSS_REGEX =
  5. '/'
  6. . '(?P<star>\*)'
  7. . '|(:(?P<pseudo>[\w-]*))'
  8. . '|\((?P<pseudospecifier>[^)]*)\)'
  9. . '|(?P<element>[\w-]*)'
  10. . '|(?P<child>\s*>\s*)'
  11. . '|(#(?P<id>[\w-]*))'
  12. . '|(\.(?P<class>[\w-]*))'
  13. . '|(?P<sibling>\s*\+\s*)'
  14. . '|(?P<subsequentsibling>\s*~\s*)'
  15. . "|(\[(?P<attribute>[\w-]*)((?P<attribute_equals>[=~$|^*]+)"
  16. . "(?P<attribute_value>(.+\[\]'?)|[^\]]+))*\])+"
  17. . '|(?P<descendant>\s+)'
  18. . '/';
  19. public const EQUALS_EXACT = "=";
  20. public const EQUALS_CONTAINS_WORD = "~=";
  21. public const EQUALS_ENDS_WITH = "$=";
  22. public const EQUALS_CONTAINS = "*=";
  23. public const EQUALS_OR_STARTS_WITH_HYPHENATED = "|=";
  24. public const EQUALS_STARTS_WITH = "^=";
  25. private SingleSelectorConverter $singleSelectorConverter;
  26. private SelectorListSplitter $selectorListSplitter;
  27. public function __construct(
  28. protected string $cssSelector,
  29. protected string $prefix = ".//",
  30. protected bool $htmlMode = true,
  31. ?SingleSelectorConverter $singleSelectorConverter = null,
  32. ?SelectorListSplitter $selectorListSplitter = null,
  33. ) {
  34. $this->singleSelectorConverter = $singleSelectorConverter
  35. ?? new SingleSelectorConverter();
  36. $this->selectorListSplitter = $selectorListSplitter
  37. ?? new SelectorListSplitter();
  38. }
  39. public function __toString():string {
  40. return $this->convert($this->cssSelector);
  41. }
  42. // phpcs:disable Generic.NamingConventions.CamelCapsFunctionName
  43. public function asXPath():string {
  44. return $this->convert($this->cssSelector);
  45. }
  46. // phpcs:enable
  47. protected function convert(string $css):string {
  48. $cssArray = $this->selectorListSplitter->split($css);
  49. $xPathArray = [];
  50. foreach($cssArray as $input) {
  51. $xPathArray[] = $this->convertSingleSelector(trim($input));
  52. }
  53. return implode(" | ", $xPathArray);
  54. }
  55. protected function convertSingleSelector(string $css):string {
  56. return $this->singleSelectorConverter->convert(
  57. $css,
  58. $this->prefix,
  59. $this->htmlMode
  60. );
  61. }
  62. }