| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- <?php
- namespace Gt\CssXPath;
- class CssAttributeTokenBuilder {
- /**
- * @return array<string, mixed>
- */
- public function build(string $content, ?callable $transform):array {
- $operatorData = $this->extractOperator($content);
- $token = $this->buildMatchPayload(
- "attribute",
- $operatorData["name"],
- $transform
- );
- if($operatorData["operator"] === null) {
- return $token;
- }
- $token["detail"] = [
- $this->buildMatchPayload(
- "attribute_equals",
- $operatorData["operator"],
- $transform
- ),
- $this->buildMatchPayload(
- "attribute_value",
- $operatorData["value"],
- $transform
- ),
- ];
- return $token;
- }
- /**
- * @return array{name: string, operator: string|null, value: string}
- */
- private function extractOperator(string $content):array {
- $operators = ["~=", "$=", "|=", "^=", "*=", "="];
- $quote = null;
- $length = strlen($content);
- for($index = 0; $index < $length; $index++) {
- $char = $content[$index];
- if($quote !== null) {
- if($char === $quote) {
- $quote = null;
- }
- continue;
- }
- if($char === "'" || $char === '"') {
- $quote = $char;
- continue;
- }
- $matchedOperator = $this->matchOperator(
- $content,
- $index,
- $operators
- );
- if($matchedOperator === null) {
- continue;
- }
- return [
- "name" => trim(substr($content, 0, $index)),
- "operator" => $matchedOperator,
- "value" => trim(
- substr($content, $index + strlen($matchedOperator))
- ),
- ];
- }
- return [
- "name" => trim($content),
- "operator" => null,
- "value" => "",
- ];
- }
- /**
- * @param array<int, string> $operators
- */
- private function matchOperator(
- string $content,
- int $index,
- array $operators
- ):?string {
- foreach($operators as $operator) {
- if(substr($content, $index, strlen($operator)) === $operator) {
- return $operator;
- }
- }
- return null;
- }
- /** @return array<string, string> */
- private function buildMatchPayload(
- string $groupKey,
- string $match,
- ?callable $transform
- ):array {
- if($transform) {
- return $transform($groupKey, $match);
- }
- return ["type" => $groupKey, "content" => $match];
- }
- }
|