%PDF- %PDF-
Direktori : /www/varak.net/nextcloud.varak.net/apps_old/apps/bookmarks/vendor/rowbot/url/src/ |
Current File : //www/varak.net/nextcloud.varak.net/apps_old/apps/bookmarks/vendor/rowbot/url/src/URL.php |
<?php declare(strict_types=1); namespace Rowbot\URL; use InvalidArgumentException; use JsonSerializable; use Rowbot\URL\Component\PathList; use Rowbot\URL\Component\QueryList; use Rowbot\URL\Exception\JsonException; use Rowbot\URL\Exception\TypeError; use Rowbot\URL\State\FragmentState; use Rowbot\URL\State\HostnameState; use Rowbot\URL\State\HostState; use Rowbot\URL\State\PathStartState; use Rowbot\URL\State\PortState; use Rowbot\URL\State\QueryState; use Rowbot\URL\State\SchemeStartState; use Rowbot\URL\String\CodePoint; use Rowbot\URL\String\IDLString; use Rowbot\URL\String\USVStringInterface; use function json_encode; use function json_last_error; use function json_last_error_msg; use const JSON_ERROR_NONE; use const JSON_UNESCAPED_SLASHES; /** * Represents a URL that can be manipulated. * * @see https://url.spec.whatwg.org/#api * @see https://developer.mozilla.org/en-US/docs/Web/API/URL * * @property string $href * @property string $origin * @property string $protocol * @property string $username * @property string $password * @property string $host * @property string $hostname * @property string $port * @property string $pathname * @property string $search * @property \Rowbot\URL\URLSearchParams $searchParams * @property string $hash */ class URL implements JsonSerializable { /** * @var \Rowbot\URL\URLSearchParams */ private $queryObject; /** * @var \Rowbot\URL\URLRecord */ private $url; /** * @throws \Rowbot\URL\Exception\TypeError */ public function __construct(string $url, string $base = null) { $parsedBase = null; $parser = new BasicURLParser(); if ($base !== null) { $parsedBase = $parser->parse(new IDLString($base)); if ($parsedBase === false) { throw new TypeError($base . ' is not a valid URL.'); } } $parsedURL = $parser->parse(new IDLString($url), $parsedBase); if ($parsedURL === false) { throw new TypeError($url . ' is not a valid URL.'); } $this->url = $parsedURL; $this->queryObject = new URLSearchParams(); $this->queryObject->setUrl($parsedURL); if ($this->url->query === null) { return; } $this->queryObject->setList(QueryList::fromString($this->url->query)); } public function __clone() { $this->url = clone $this->url; $this->queryObject = clone $this->queryObject; $this->queryObject->setUrl($this->url); } /** * @return string|\Rowbot\URL\URLSearchParams * * @throws \InvalidArgumentException When an invalid $name value is passed. */ public function __get(string $name) { if ($name === 'hash') { if ($this->url->fragment === null || $this->url->fragment === '') { return ''; } return '#' . $this->url->fragment; } if ($name === 'host') { if ($this->url->host->isNull()) { return ''; } $serializer = $this->url->host->getSerializer(); if ($this->url->port === null) { return $serializer->toFormattedString(); } return $serializer->toFormattedString() . ':' . $this->url->port; } if ($name === 'hostname') { if ($this->url->host->isNull()) { return ''; } return $this->url->host->getSerializer()->toFormattedString(); } if ($name === 'href') { return $this->url->serializeURL(); } if ($name === 'origin') { return (string) $this->url->getOrigin(); } if ($name === 'password') { return $this->url->password; } if ($name === 'pathname') { if ($this->url->cannotBeABaseUrl) { return (string) $this->url->path->first(); } if ($this->url->path->isEmpty()) { return ''; } return '/' . $this->url->path; } if ($name === 'port') { if ($this->url->port === null) { return ''; } return (string) $this->url->port; } if ($name === 'protocol') { return $this->url->scheme . ':'; } if ($name === 'search') { if ($this->url->query === null || $this->url->query === '') { return ''; } return '?' . $this->url->query; } if ($name === 'searchParams') { return $this->queryObject; } if ($name === 'username') { return $this->url->username; } throw new InvalidArgumentException($name . ' is not a valid property.'); } /** * @throws \InvalidArgumentException When an invalid $name or $value value is passed. * @throws \Rowbot\URL\Exception\TypeError Only when trying to set URL::$searchParams */ public function __set(string $name, string $value): void { if ($name === 'searchParams') { throw new TypeError(); } $input = new IDLString($value); $parser = new BasicURLParser(); if ($name === 'hash') { if ($input->isEmpty()) { $this->url->fragment = null; // Terminate these steps return; } if ($input->startsWith('#')) { $input = $input->substr(1); } $this->url->fragment = ''; $parser->parse($input, null, null, $this->url, new FragmentState()); } elseif ($name === 'host') { if ($this->url->cannotBeABaseUrl) { // Terminate these steps return; } $parser->parse($input, null, null, $this->url, new HostState()); } elseif ($name === 'hostname') { if ($this->url->cannotBeABaseUrl) { // Terminate these steps return; } $parser->parse($input, null, null, $this->url, new HostnameState()); } elseif ($name === 'href') { $parsedURL = $parser->parse($input); if ($parsedURL === false) { throw new TypeError($value . ' is not a valid URL.'); } $this->url = $parsedURL; $this->queryObject->setUrl($this->url); if ($this->url->query === null) { return; } $this->queryObject->setList(QueryList::fromString($this->url->query)); } elseif ($name === 'password') { if ($this->url->cannotHaveUsernamePasswordPort()) { return; } $this->setUrlPassword($input); } elseif ($name === 'pathname') { if ($this->url->cannotBeABaseUrl) { // Terminate these steps return; } $this->url->path = new PathList(); $parser->parse($input, null, null, $this->url, new PathStartState()); } elseif ($name === 'port') { if ($this->url->cannotHaveUsernamePasswordPort()) { return; } if ($value === '') { $this->url->port = null; return; } $parser->parse($input, null, null, $this->url, new PortState()); } elseif ($name === 'protocol') { $parser->parse($input->append(':'), null, null, $this->url, new SchemeStartState()); } elseif ($name === 'search') { if ($value === '') { $this->url->query = null; $this->queryObject->setList(new QueryList()); return; } if ($input->startsWith('?')) { $input = $input->substr(1); } $this->url->query = ''; $parser->parse($input, null, null, $this->url, new QueryState()); $this->queryObject->setList(QueryList::fromString((string) $input)); } elseif ($name === 'username') { if ($this->url->cannotHaveUsernamePasswordPort()) { return; } $this->setUrlUsername($input); } else { throw new InvalidArgumentException($name . ' is not a valid property.'); } } /** * @see https://url.spec.whatwg.org/#set-the-password */ private function setUrlPassword(USVStringInterface $input): void { $this->url->password = ''; foreach ($input as $codePoint) { $this->url->password .= CodePoint::utf8PercentEncode( $codePoint, CodePoint::USERINFO_PERCENT_ENCODE_SET ); } } /** * @see https://url.spec.whatwg.org/#set-the-username */ private function setUrlUsername(USVStringInterface $input): void { $this->url->username = ''; foreach ($input as $codePoint) { $this->url->username .= CodePoint::utf8PercentEncode( $codePoint, CodePoint::USERINFO_PERCENT_ENCODE_SET ); } } public function __toString(): string { return $this->url->serializeURL(); } public function toString(): string { return $this->url->serializeURL(); } /** * Returns a JSON encoded string without escaping forward slashes. If you * need forward slashes to be escaped, pass the URL object to json_encode() * instead of calling this method. * * @see https://url.spec.whatwg.org/#dom-url-tojson */ public function toJSON(): string { // Use JSON_UNESCAPED_SLASHES here since JavaScript's JSON.stringify() // method does not escape forward slashes by default. $result = json_encode($this->url->serializeURL(), JSON_UNESCAPED_SLASHES); if ($result === false || json_last_error() !== JSON_ERROR_NONE) { throw new JsonException(json_last_error_msg(), json_last_error()); } return $result; } /** * Returns the serialized URL for consumption by json_encode(). To match * JavaScript's behavior, you should pass the JSON_UNESCAPED_SLASHES option * to json_encode(). */ public function jsonSerialize(): string { return $this->url->serializeURL(); } }