multimedia tags are mostly finished

This commit is contained in:
Joby 2023-09-10 21:02:51 +00:00
parent 76a5eae11e
commit d093dce41a
78 changed files with 3593 additions and 635 deletions

View file

@ -5,7 +5,7 @@ namespace ByJoby\HTML;
use ByJoby\HTML\Containers\Fragment;
use ByJoby\HTML\Containers\FragmentInterface;
use ByJoby\HTML\Containers\HtmlDocumentInterface;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Nodes\CData;
use ByJoby\HTML\Nodes\CDataInterface;
use ByJoby\HTML\Nodes\Comment;

View file

@ -17,21 +17,21 @@ interface ContainerInterface extends Stringable
NodeInterface|Stringable|string $child,
bool $prepend = false,
bool $skip_sanitize = false
): static;
): self;
public function removeChild(
NodeInterface|Stringable|string $child
): static;
): self;
public function addChildBefore(
NodeInterface|Stringable|string $new_child,
NodeInterface|Stringable|string $before_child,
bool $skip_sanitize = false
): static;
): self;
public function addChildAfter(
NodeInterface|Stringable|string $new_child,
NodeInterface|Stringable|string $after_child,
bool $skip_sanitize = false
): static;
): self;
}

View file

@ -5,7 +5,7 @@ namespace ByJoby\HTML\Helpers;
use ArrayAccess;
use ArrayIterator;
use BackedEnum;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use ByJoby\HTML\Helpers\BooleanAttribute;
use Exception;
use IteratorAggregate;
use Stringable;
@ -81,7 +81,7 @@ class Attributes implements IteratorAggregate, ArrayAccess
* @param string $separator
* @return static
*/
public function setEnumArray(string $offset, null|BackedEnum|array $value, string $enum_class, string $separator): static
public function setEnumArray(string $offset, null|BackedEnum|array $value, string $enum_class, string $separator): self
{
if (is_null($value)) {
$value = [];

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Helpers;
/**
* This special enum is used to specify that an attribute is an HTML5 boolean

View file

@ -59,7 +59,7 @@ class Classes implements Countable
return $this->classes;
}
public function add(string|Stringable $class, bool $no_exception = false): static
public function add(string|Stringable $class, bool $no_exception = false): self
{
try {
$class = static::sanitizeClassName($class, true);
@ -77,7 +77,7 @@ class Classes implements Countable
return $this;
}
public function remove(string|Stringable $class): static
public function remove(string|Stringable $class): self
{
$class = static::sanitizeClassName($class);
$this->classes = array_values(array_filter(

View file

@ -20,7 +20,7 @@ class TitleTag extends AbstractContentTag implements TitleTagInterface
protected $content = 'Untitled';
protected $inline = true;
public function setContent(string|Stringable $content): static
public function setContent(string|Stringable $content): self
{
parent::setContent(trim(strip_tags($content)));
return $this;

View file

@ -2,7 +2,7 @@
namespace ByJoby\HTML\Html5\Enums;
enum Type_list: string {
enum ListTypeValue: string {
case letterLower = 'a';
case letterUpper = 'A';
case romanLower = 'i';

View file

@ -2,7 +2,7 @@
namespace ByJoby\HTML\Html5\Enums;
enum Spellcheck: string
enum SpellcheckValue: string
{
case true = "true";
case false = "false";

View file

@ -11,7 +11,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/translate
*/
enum Translate: string
enum TranslateValue: string
{
case true = "yes";
case false = "no";

View file

@ -12,11 +12,12 @@ class Html5Parser extends AbstractParser
{
/** @var array<int,string> */
protected $tag_namespaces = [
'\\ByJoby\\HTML\\Html5\\Tags\\',
'\\ByJoby\\HTML\\Html5\\InlineTextSemantics\\',
'\\ByJoby\\HTML\\Html5\\TextContentTags\\',
'\\ByJoby\\HTML\\Html5\\ContentSectioningTags\\',
'\\ByJoby\\HTML\\Html5\\DocumentTags\\',
'\\ByJoby\\HTML\\Html5\\InlineTextSemantics\\',
'\\ByJoby\\HTML\\Html5\\Multimedia\\',
'\\ByJoby\\HTML\\Html5\\Tags\\',
'\\ByJoby\\HTML\\Html5\\TextContentTags\\',
];
/** @var class-string<HtmlDocumentInterface> */

View file

@ -2,10 +2,11 @@
namespace ByJoby\HTML\Html5\InlineTextSemantics;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Enums\BrowsingContext;
use ByJoby\HTML\Html5\Enums\ReferrerPolicy_a;
use ByJoby\HTML\Html5\Enums\Rel_a;
use ByJoby\HTML\Html5\InlineTextSemantics\ATag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\InlineTextSemantics\ATag\RelValue;
use ByJoby\HTML\Html5\Traits\HyperlinkTrait;
use ByJoby\HTML\Tags\AbstractContainerTag;
use Stringable;
@ -19,308 +20,6 @@ use Stringable;
*/
class ATag extends AbstractContainerTag
{
use HyperlinkTrait;
const TAG = 'a';
/**
* Causes the browser to treat the linked URL as a download. Can be used
* with or without a filename value.
*
* @return null|string|Stringable|BooleanAttribute::true
*/
public function download(): null|string|Stringable|BooleanAttribute
{
if ($this->attributes()['download'] === BooleanAttribute::true) return BooleanAttribute::true;
else return $this->attributes()->asString('download');
}
/**
* Causes the browser to treat the linked URL as a download. Can be used
* with or without a filename value.
*
* @param null|string|Stringable|BooleanAttribute $download
* @return static
*/
public function setDownload(null|string|Stringable|BooleanAttribute $download): static
{
if ($download === BooleanAttribute::true) $this->attributes()['download'] = BooleanAttribute::true;
elseif ($download === BooleanAttribute::false) $this->unsetDownload();
elseif ($download) $this->attributes()['download'] = $download;
else $this->unsetDownload();
return $this;
}
/**
* Causes the browser to treat the linked URL as a download. Can be used
* with or without a filename value.
*
* @return static
*/
public function unsetDownload(): static
{
unset($this->attributes()['download']);
return $this;
}
/**
* The URL that the hyperlink points to. Links are not restricted to
* HTTP-based URLs they can use any URL scheme supported by browsers
*
* @return null|string|Stringable
*/
public function href(): null|string|Stringable
{
return $this->attributes()->asString('href');
}
/**
* The URL that the hyperlink points to. Links are not restricted to
* HTTP-based URLs they can use any URL scheme supported by browsers
*
* @param null|string|Stringable $href
* @return static
*/
public function setHref(null|string|Stringable $href): static
{
if ($href) $this->attributes()['href'] = $href;
else $this->unsetHref();
return $this;
}
/**
* The URL that the hyperlink points to. Links are not restricted to
* HTTP-based URLs they can use any URL scheme supported by browsers
*
* @return static
*/
public function unsetHref(): static
{
$this->unsetHreflang();
unset($this->attributes()['href']);
return $this;
}
/**
* Hints at the human language of the linked URL. No built-in functionality.
* Allowed values are the same as the global lang attribute.
*
* @return null|string|Stringable
*/
public function hreflang(): null|string|Stringable
{
return $this->attributes()->asString('hreflang');
}
/**
* Hints at the human language of the linked URL. No built-in functionality.
* Allowed values are the same as the global lang attribute.
*
* @param null|string|Stringable $hreflang
* @return static
*/
public function setHreflang(null|string|Stringable $hreflang): static
{
if ($hreflang) $this->attributes()['hreflang'] = $hreflang;
else $this->unsetHreflang();
return $this;
}
/**
* Hints at the human language of the linked URL. No built-in functionality.
* Allowed values are the same as the global lang attribute.
*
* @return static
*/
public function unsetHreflang(): static
{
unset($this->attributes()['hreflang']);
return $this;
}
/**
* A space-separated list of URLs. When the link is followed, the browser
* will send POST requests with the body PING to the URLs. Typically for
* tracking.
*
* @return null|string|Stringable
*/
public function ping(): null|string|Stringable
{
return $this->attributes()->asString('ping');
}
/**
* A space-separated list of URLs. When the link is followed, the browser
* will send POST requests with the body PING to the URLs. Typically for
* tracking.
*
* @param null|string|Stringable $ping
* @return static
*/
public function setPing(null|string|Stringable $ping): static
{
if ($ping) $this->attributes()['ping'] = $ping;
else $this->unsetPing();
return $this;
}
/**
* A space-separated list of URLs. When the link is followed, the browser
* will send POST requests with the body PING to the URLs. Typically for
* tracking.
*
* @return static
*/
public function unsetPing(): static
{
unset($this->attributes()['ping']);
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return null|ReferrerPolicy_a
*/
public function referrerpolicy(): null|ReferrerPolicy_a
{
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicy_a::class);
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @param null|ReferrerPolicy_a $referrerpolicy
* @return static
*/
public function setReferrerpolicy(null|ReferrerPolicy_a $referrerpolicy): static
{
if ($referrerpolicy) $this->attributes()['referrerpolicy'] = $referrerpolicy->value;
else $this->unsetReferrerpolicy();
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return static
*/
public function unsetReferrerpolicy(): static
{
unset($this->attributes()['referrerpolicy']);
return $this;
}
/**
* The relationship of the linked URL as space-separated link types.
*
* @return Rel_a[]
*/
public function rel(): array
{
return $this->attributes()->asEnumArray('rel', Rel_a::class, ' ');
}
/**
* The relationship of the linked URL as space-separated link types.
*
* @param null|Rel_a|array<int|string,Rel_a> $rel
* @return static
*/
public function setRel(null|Rel_a|array $rel): static
{
if ($rel) $this->attributes()->setEnumArray('rel', $rel, Rel_a::class, ' ');
else $this->unsetRel();
return $this;
}
/**
* The relationship of the linked URL as space-separated link types.
*
* @return static
*/
public function unsetRel(): static
{
unset($this->attributes()['rel']);
return $this;
}
/**
* Where to display the linked URL, as the name for a browsing context (a
* tab, window, or <iframe>).
*
* @return null|string|Stringable|BrowsingContext
*/
public function target(): null|string|Stringable|BrowsingContext
{
return $this->attributes()->asEnum('target', BrowsingContext::class)
?? $this->attributes()->asString('target');
}
/**
* Where to display the linked URL, as the name for a browsing context (a
* tab, window, or <iframe>).
*
* @param null|string|Stringable|BrowsingContext $target
* @return static
*/
public function setTarget(null|string|Stringable|BrowsingContext $target): static
{
if (!$target) {
$this->unsetTarget();
} elseif ($target instanceof BrowsingContext) {
$this->attributes()['target'] = $target->value;
} else {
$this->attributes()['target'] = $target;
}
return $this;
}
/**
* Where to display the linked URL, as the name for a browsing context (a
* tab, window, or <iframe>).
*
* @return static
*/
public function unsetTarget(): static
{
unset($this->attributes()['target']);
return $this;
}
/**
* Hints at the linked URL's format with a MIME type. No built-in
* functionality.
*
* @return null|string|Stringable
*/
public function type(): null|string|Stringable
{
return $this->attributes()->asString('type');
}
/**
* Hints at the linked URL's format with a MIME type. No built-in
* functionality.
*
* @param null|string|Stringable $type
* @return static
*/
public function setType(null|string|Stringable $type): static
{
if ($type) $this->attributes()['type'] = $type;
else $this->unsetType();
return $this;
}
/**
* Hints at the linked URL's format with a MIME type. No built-in
* functionality.
*
* @return static
*/
public function unsetType(): static
{
unset($this->attributes()['type']);
return $this;
}
}

View file

@ -47,7 +47,7 @@ class AbbrTag extends AbstractContainerTag
* @param null|string|Stringable $title
* @return static
*/
public function setTitle(null|string|Stringable $title): static
public function setTitle(null|string|Stringable $title): self
{
if ($title) $this->attributes()['title'] = $title;
else $this->unsetTitle();
@ -62,7 +62,7 @@ class AbbrTag extends AbstractContainerTag
*
* @return static
*/
public function unsetTitle(): static
public function unsetTitle(): self
{
unset($this->attributes()['title']);
return $this;

View file

@ -35,7 +35,7 @@ class DataTag extends AbstractContainerTag
* @param null|string|Stringable $value
* @return static
*/
public function setValue(null|string|Stringable $value): static
public function setValue(null|string|Stringable $value): self
{
if ($value) $this->attributes()['value'] = $value;
else $this->unsetValue();
@ -48,7 +48,7 @@ class DataTag extends AbstractContainerTag
*
* @return static
*/
public function unsetValue(): static
public function unsetValue(): self
{
unset($this->attributes()['value']);
return $this;

View file

@ -53,7 +53,7 @@ class DataTag extends AbstractContainerTag
* @param null|string|Stringable $title
* @return static
*/
public function setTitle(null|string|Stringable $title): static
public function setTitle(null|string|Stringable $title): self
{
if ($title) $this->attributes()['title'] = $title;
else $this->unsetTitle();
@ -68,7 +68,7 @@ class DataTag extends AbstractContainerTag
*
* @return static
*/
public function unsetTitle(): static
public function unsetTitle(): self
{
unset($this->attributes()['title']);
return $this;

View file

@ -38,7 +38,7 @@ class QTag extends AbstractContainerTag
* @param null|string|Stringable $cite
* @return static
*/
public function setCite(null|string|Stringable $cite): static
public function setCite(null|string|Stringable $cite): self
{
if ($cite) $this->attributes()['cite'] = $cite;
else $this->unsetCite();
@ -52,7 +52,7 @@ class QTag extends AbstractContainerTag
*
* @return static
*/
public function unsetCite(): static
public function unsetCite(): self
{
unset($this->attributes()['cite']);
return $this;

View file

@ -31,14 +31,14 @@ class TimeTag extends AbstractContainerTag
);
}
public function setDatetime(null|DatetimeValue $datetime): static
public function setDatetime(null|DatetimeValue $datetime): self
{
if ($datetime) $this->attributes()['datetime'] = $datetime;
else $this->unsetDatetime();
return $this;
}
public function unsetDatetime(): static
public function unsetDatetime(): self
{
unset($this->attributes()['datetime']);
return $this;

View file

@ -0,0 +1,264 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Containers\ContainerGroup;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Multimedia\AbstractPlaybackTag\PreloadValue;
use ByJoby\HTML\Html5\Traits\CrossOriginTrait;
use ByJoby\HTML\NodeInterface;
use ByJoby\HTML\Tags\AbstractGroupedTag;
use ByJoby\HTML\Tags\TagInterface;
use Stringable;
/**
* The <audio> HTML element is used to embed sound or video content in
* documents. It may contain one or more audio sources, represented using the
* src attribute or the <source> element: the browser will choose the most
* suitable one. It can also be the destination for streamed media, using a
* MediaStream.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
*/
abstract class AbstractPlaybackTag extends AbstractGroupedTag
{
use CrossOriginTrait;
/** @var ContainerGroup<TagInterface> */
protected $sources;
/** @var ContainerGroup<TagInterface> */
protected $tracks;
/** @var ContainerGroup<NodeInterface> */
protected $fallback;
public function __construct()
{
$this->addGroup($this->sources = ContainerGroup::ofTag('source'));
$this->addGroup($this->tracks = ContainerGroup::ofTag('track'));
$this->addGroup($this->fallback = ContainerGroup::catchAll());
}
/**
* Get all the <source> tags
*
* @return ContainerGroup<TagInterface>
*/
public function sources(): ContainerGroup
{
return $this->sources;
}
/**
* Get all the <track> tags
*
* @return ContainerGroup<TagInterface>
*/
public function tracks(): ContainerGroup
{
return $this->tracks;
}
/**
* Get all the fallback content (children that are not <source> or <track>
* tags) that will display for a browser that does not support in-place
* playback.
*
* @return ContainerGroup<NodeInterface>
*/
public function fallback(): ContainerGroup
{
return $this->fallback;
}
/**
* A Boolean attribute: if specified, the content will automatically begin
* playback as soon as it can do so, without waiting for the entire content
* file to finish downloading.
*
* @return boolean
*/
public function autoplay(): bool
{
return $this->attributes()['autoplay'] === BooleanAttribute::true;
}
/**
* A Boolean attribute: if specified, the content will automatically begin
* playback as soon as it can do so, without waiting for the entire content
* file to finish downloading.
*
* @param boolean $autoplay
* @return self
*/
public function setAutoplay(bool $autoplay): self
{
if ($autoplay) $this->attributes()['autoplay'] = BooleanAttribute::true;
else unset($this->attributes()['autoplay']);
return $this;
}
/**
* If this attribute is present, the browser will offer controls to allow
* the user to control content playback, including volume, seeking, and
* pause/resume playback.
*
* @return boolean
*/
public function controls(): bool
{
return $this->attributes()['controls'] === BooleanAttribute::true;
}
/**
* If this attribute is present, the browser will offer controls to allow
* the user to control content playback, including volume, seeking, and
* pause/resume playback.
*
* @param boolean $controls
* @return self
*/
public function setControls(bool $controls): self
{
if ($controls) $this->attributes()['controls'] = BooleanAttribute::true;
else unset($this->attributes()['controls']);
return $this;
}
/**
* A Boolean attribute: if specified, the player will automatically seek
* back to the start upon reaching the end of the content.
*
* @return boolean
*/
public function loop(): bool
{
return $this->attributes()['loop'] === BooleanAttribute::true;
}
/**
* A Boolean attribute: if specified, the player will automatically seek
* back to the start upon reaching the end of the content.
*
* @param boolean $loop
* @return self
*/
public function setLoop(bool $loop): self
{
if ($loop) $this->attributes()['loop'] = BooleanAttribute::true;
else unset($this->attributes()['loop']);
return $this;
}
/**
* A Boolean attribute that indicates whether the player will be initially
* silenced. Its default value is false.
*
* @return boolean
*/
public function muted(): bool
{
return $this->attributes()['muted'] === BooleanAttribute::true;
}
/**
* A Boolean attribute that indicates whether the player will be initially
* silenced. Its default value is false.
*
* @param boolean $muted
* @return self
*/
public function setMuted(bool $muted): self
{
if ($muted) $this->attributes()['muted'] = BooleanAttribute::true;
else unset($this->attributes()['muted']);
return $this;
}
/**
* The URL of the content to embed. This is subject to HTTP access controls.
* This is optional; you may instead use the <source> element within the tag
* to specify the file to embed.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* The URL of the content to embed. This is subject to HTTP access controls.
* This is optional; you may instead use the <source> element within the tag
* to specify the file to embed.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* The URL of the content to embed. This is subject to HTTP access controls.
* This is optional; you may instead use the <source> element within the tag
* to specify the file to embed.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* This enumerated attribute is intended to provide a hint to the browser
* about what the author thinks will lead to the best user experience.
*
* The default value is different for each browser. The spec advises it to
* be set to metadata.
*
* @return null|PreloadValue
*/
public function preload(): null|PreloadValue
{
return $this->attributes()->asEnum('preload', PreloadValue::class);
}
/**
* This enumerated attribute is intended to provide a hint to the browser
* about what the author thinks will lead to the best user experience.
*
* The default value is different for each browser. The spec advises it to
* be set to metadata.
*
* @param null|PreloadValue $preload
* @return self
*/
public function setPreload(null|PreloadValue $preload): self
{
if ($preload) $this->attributes()['preload'] = $preload->value;
else $this->unsetPreload();
return $this;
}
/**
* This enumerated attribute is intended to provide a hint to the browser
* about what the author thinks will lead to the best user experience.
*
* The default value is different for each browser. The spec advises it to
* be set to metadata.
*
* @return self
*/
public function unsetPreload(): self
{
unset($this->attributes()['preload']);
return $this;
}
}

View file

@ -0,0 +1,21 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\AbstractPlaybackTag;
enum PreloadValue: string
{
/**
* Indicates that the content should not be preloaded.
*/
case none = "none";
/**
* Advised option for most cases. Indicates that only content metadata (e.g.
* length) is fetched.
*/
case metadata = "metadata";
/**
* Indicates that the whole content file can be downloaded, even if the user
* is not expected to use it.
*/
case auto = "auto";
}

View file

@ -0,0 +1,247 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Html5\Exceptions\InvalidArgumentsException;
use ByJoby\HTML\Html5\Multimedia\AreaTag\ShapeValue;
use ByJoby\HTML\Html5\Traits\HyperlinkTrait;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <area> HTML element defines an area inside an image map that has
* predefined clickable areas. An image map allows geometric areas on an image
* to be associated with hypertext links.
*
* This element is used only within a <map> element.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area
*/
class AreaTag extends AbstractTag
{
use HyperlinkTrait;
const TAG = 'area';
/**
* @inheritDoc
*
* @param null|string|Stringable $href
* @param null|string|Stringable|null $alt required to set for <area> tags
* @return self
*/
public function setHref(null|string|Stringable $href, null|string|Stringable $alt = null): self
{
if ($href) {
$this->attributes()['href'] = $href;
if (!$alt) throw new InvalidArgumentsException('alt text is required to set href on an <area> tag');
} else $this->unsetHref();
if ($alt) $this->setAlt($alt);
return $this;
}
/**
* A text string alternative to display on browsers that do not display
* images. The text should be phrased so that it presents the user with the
* same kind of choice as the image would offer when displayed without the
* alternative text. This attribute is required only if the href attribute
* is used.
*
* @return null|string|Stringable
*/
public function alt(): null|string|Stringable
{
return $this->attributes()->asString('alt');
}
/**
* A text string alternative to display on browsers that do not display
* images. The text should be phrased so that it presents the user with the
* same kind of choice as the image would offer when displayed without the
* alternative text. This attribute is required only if the href attribute
* is used.
*
* @param null|string|Stringable $alt
* @return self
*/
public function setAlt(null|string|Stringable $alt): self
{
if (!$alt) $this->unsetAlt();
else $this->attributes()['alt'] = $alt;
return $this;
}
/**
* A text string alternative to display on browsers that do not display
* images. The text should be phrased so that it presents the user with the
* same kind of choice as the image would offer when displayed without the
* alternative text. This attribute is required only if the href attribute
* is used.
*
* @return self
*/
public function unsetAlt(): self
{
unset($this->attributes()['alt']);
return $this;
}
/**
* The coords attribute details the coordinates of the shape attribute in
* size, shape, and placement of an <area>. This attribute must not be used
* if shape is set to default.
*
* @return null|array<int,int>
*/
public function coords(): null|array
{
// TODO write tests for this
$coords = $this->attributes()->asString('coords');
if (!$coords) return null;
$coords = explode(',', $coords);
$coords = array_map(trim(...), $coords);
$coords = array_filter($coords, fn($e) => $e !== '');
$coords = array_map(intval(...), $coords);
return $coords;
}
/**
* The coords attribute details the coordinates of the shape attribute in
* size, shape, and placement of an <area>. This attribute must not be used
* if shape is set to default.
*
* @param null|string|Stringable|array<int|string,int> $coords
* @return self
*/
public function setCoords(null|string|Stringable|array $coords): self
{
if (is_array($coords)) $coords = implode(',', $coords);
if (!$coords) $this->unsetCoords();
else $this->attributes()['coords'] = $coords;
return $this;
}
public function unsetCoords(): self
{
unset($this->attributes()['coords']);
return $this;
}
/**
* The shape of the associated hot spot. The specifications for HTML defines
* the values rect, which defines a rectangular region; circle, which
* defines a circular region; poly, which defines a polygon; and default,
* which indicates the entire region beyond any defined shapes.
*
* @return null|ShapeValue
*/
public function shape(): null|ShapeValue
{
return $this->attributes()->asEnum('shape', ShapeValue::class);
}
/**
* The shape of the associated hot spot. The specifications for HTML defines
* the values rect, which defines a rectangular region; circle, which
* defines a circular region; poly, which defines a polygon; and default,
* which indicates the entire region beyond any defined shapes.
*
* @param ShapeValue|null $shape
* @param int $coords
* @return self
*/
public function setShape(ShapeValue|null $shape, ...$coords): self
{
// TODO write tests for the various shape setters
if (!$shape) return $this->unsetShape();
switch ($shape) {
case ShapeValue::default:
return $this->setShapeDefault();
case ShapeValue::rectangle:
return $this->setRectangle(...$coords);
case ShapeValue::circle:
return $this->setCircle(...$coords);
case ShapeValue::polygon:
return $this->setPolygon(...$coords);
}
return $this;
}
/**
* The shape of the associated hot spot. The specifications for HTML defines
* the values rect, which defines a rectangular region; circle, which
* defines a circular region; poly, which defines a polygon; and default,
* which indicates the entire region beyond any defined shapes.
*
* @return self
*/
public function unsetShape(): self
{
unset($this->attributes()['shape']);
$this->unsetCoords();
return $this;
}
/**
* indicates the entire region beyond any defined shapes.
*
* @return self
*/
public function setShapeDefault(): self
{
$this->attributes()['shape'] = ShapeValue::default ->value;
$this->unsetCoords();
return $this;
}
/**
* the value is x1,y1,x2,y2. The value specifies the coordinates of the
* top-left and bottom-right corner of the rectangle. For example, in <area
* shape="rect" coords="0,0,253,27" href="#" target="_blank" alt="Mozilla">
* the coordinates are 0,0 and 253,27, indicating the top-left and
* bottom-right corners of the rectangle, respectively.
*
* @param integer $x1
* @param integer $y1
* @param integer $x2
* @param integer $y2
* @return self
*/
public function setRectangle(int $x1, int $y1, int $x2, int $y2): self
{
$this->attributes()['shape'] = ShapeValue::rectangle->value;
$this->setCoords([$x1, $y1, $x2, $y2]);
return $this;
}
/**
* the value is x,y,radius. Value specifies the coordinates of the circle
* center and the radius.
*
* @param integer $x
* @param integer $y
* @param integer $radius
* @return self
*/
public function setCircle(int $x, int $y, int $radius): self
{
$this->attributes()['shape'] = ShapeValue::circle->value;
$this->setCoords([$x, $y, $radius]);
return $this;
}
/**
* the value is x1,y1,x2,y2,..,xn,yn. Value specifies the coordinates of the
* edges of the polygon. If the first and last coordinate pairs are not the
* same, the browser will add the last coordinate pair to close the polygon
*
* @param int ...$coords
* @return self
*/
public function setPolygon(...$coords): self
{
$this->attributes()['shape'] = ShapeValue::polygon->value;
$this->setCoords($coords);
return $this;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\AreaTag;
enum ShapeValue: string
{
/**
* indicates the entire region beyond any defined shapes
*/
case default = "default";
case rectangle = "rect";
case circle = "circle";
case polygon = "poly";
}

View file

@ -0,0 +1,17 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
/**
* The <audio> HTML element is used to embed sound content in documents. It may
* contain one or more audio sources, represented using the src attribute or the
* <source> element: the browser will choose the most suitable one. It can also
* be the destination for streamed media, using a MediaStream.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio
*/
class AudioTag extends AbstractPlaybackTag
{
const TAG = 'audio';
}

View file

@ -0,0 +1,165 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <embed> HTML element embeds external content at the specified point in
* the document. This content is provided by an external application or other
* source of interactive content such as a browser plug-in.
*
* @deprecated Keep in mind that most modern browsers have deprecated and
* removed support for browser plug-ins, so relying upon <embed> is generally
* not wise if you want your site to be operable on the average user's browser.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed
*/
class EmbedTag extends AbstractTag
{
const TAG = "embed";
/**
* The displayed height of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return null|integer
*/
public function height(): null|int
{
return $this->attributes()->asInt('height');
}
/**
* The displayed height of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @param null|integer $height
* @return self
*/
public function setHeight(null|int $height): self
{
if (is_int($height)) $this->attributes()['height'] = $height;
else $this->unsetHeight();
return $this;
}
/**
* The displayed height of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return self
*/
public function unsetHeight(): self
{
unset($this->attributes()['height']);
return $this;
}
/**
* The URL of the resource being embedded.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* The URL of the resource being embedded.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* The URL of the resource being embedded.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* The MIME type to use to select the plug-in to instantiate.
*
* @return null|string|Stringable
*/
public function type(): null|string|Stringable
{
return $this->attributes()->asString('type');
}
/**
* The MIME type to use to select the plug-in to instantiate.
*
* @param null|string|Stringable $type
* @return static
*/
public function setType(null|string|Stringable $type): self
{
if ($type) $this->attributes()['type'] = $type;
else $this->unsetType();
return $this;
}
/**
* The MIME type to use to select the plug-in to instantiate.
*
* @return static
*/
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;
}
/**
* The displayed width of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return null|integer
*/
public function width(): null|int
{
return $this->attributes()->asInt('width');
}
/**
* The displayed width of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @param null|integer $width
* @return self
*/
public function setWidth(null|int $width): self
{
if (is_int($width)) $this->attributes()['width'] = $width;
else $this->unsetWidth();
return $this;
}
/**
* The displayed width of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return self
*/
public function unsetWidth(): self
{
unset($this->attributes()['width']);
return $this;
}
}

View file

@ -0,0 +1,377 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Helpers\StringableEnumArray;
use ByJoby\HTML\Html5\Multimedia\IframeTag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Multimedia\IframeTag\SandboxValue;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <embed> HTML element embeds external content at the specified point in
* the document. This content is provided by an external application or other
* source of interactive content such as a browser plug-in.
*
* Keep in mind that most modern browsers have deprecated and removed support
* for browser plug-ins, so relying upon <embed> is generally not wise if you
* want your site to be operable on the average user's browser.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
*/
class IframeTag extends AbstractTag
{
const TAG = "embed";
/**
* Specifies a Permissions Policy for the <iframe>. The policy defines what
* features are available to the <iframe> (for example, access to the
* microphone, camera, battery, web-share, etc.) based on the origin of the
* request.
*
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy
*
* @return null|string|Stringable
*/
public function allow(): null|string|Stringable
{
return $this->attributes()->asString('allow');
}
/**
* Specifies a Permissions Policy for the <iframe>. The policy defines what
* features are available to the <iframe> (for example, access to the
* microphone, camera, battery, web-share, etc.) based on the origin of the
* request.
*
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy
*
* @param null|string|Stringable $allow
* @return static
*/
public function setAllow(null|string|Stringable $allow): self
{
if ($allow) $this->attributes()['allow'] = $allow;
else $this->unsetAllow();
return $this;
}
/**
* Specifies a Permissions Policy for the <iframe>. The policy defines what
* features are available to the <iframe> (for example, access to the
* microphone, camera, battery, web-share, etc.) based on the origin of the
* request.
*
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy
*
* @return static
*/
public function unsetAllow(): self
{
unset($this->attributes()['allow']);
return $this;
}
/**
* Defer loading of the iframe until it reaches a calculated distance from
* the viewport, as defined by the browser.
*
* @return boolean
*/
public function lazy(): bool
{
return $this->attributes()['loading'] == 'lazy';
}
/**
* Defer loading of the iframe until it reaches a calculated distance from
* the viewport, as defined by the browser.
*
* @param boolean $lazy
* @return self
*/
public function setLazy(bool $lazy): self
{
if ($lazy) $this->attributes()['loading'] = 'lazy';
else unset($this->attributes()['lazy']);
return $this;
}
/**
* A targetable name for the embedded browsing context. This can be used in
* the target attribute of the <a>, <form>, or <base> elements; the
* formtarget attribute of the <input> or <button> elements; or the
* windowName parameter in the window.open() method.
*
* @return null|string|Stringable
*/
public function name(): null|string|Stringable
{
return $this->attributes()->asString('name');
}
/**
* A targetable name for the embedded browsing context. This can be used in
* the target attribute of the <a>, <form>, or <base> elements; the
* formtarget attribute of the <input> or <button> elements; or the
* windowName parameter in the window.open() method.
*
* @param null|string|Stringable $name
* @return static
*/
public function setName(null|string|Stringable $name): self
{
if ($name) $this->attributes()['name'] = $name;
else $this->unsetName();
return $this;
}
/**
* A targetable name for the embedded browsing context. This can be used in
* the target attribute of the <a>, <form>, or <base> elements; the
* formtarget attribute of the <input> or <button> elements; or the
* windowName parameter in the window.open() method.
*
* @return static
*/
public function unsetName(): self
{
unset($this->attributes()['name']);
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return null|ReferrerPolicyValue
*/
public function referrerpolicy(): null|ReferrerPolicyValue
{
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicyValue::class);
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @param null|ReferrerPolicyValue $referrerpolicy
* @return static
*/
public function setReferrerpolicy(null|ReferrerPolicyValue $referrerpolicy): self
{
if ($referrerpolicy) $this->attributes()['referrerpolicy'] = $referrerpolicy->value;
else $this->unsetReferrerpolicy();
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return static
*/
public function unsetReferrerpolicy(): self
{
unset($this->attributes()['referrerpolicy']);
return $this;
}
/**
* Controls the restrictions applied to the content embedded in the
* <iframe>. The value of the attribute can either be empty to apply all
* restrictions, or space-separated tokens to lift particular restrictions:
*
* @return null|array<int|string,SandboxValue>
*/
public function sandbox(): null|array {
// TODO test retrieving various possible values
if (!$this->attributes()->asString('sandbox')) return null;
else return $this->attributes()->asEnumArray('sandbox',SandboxValue::class,' ');
}
/**
* Controls the restrictions applied to the content embedded in the
* <iframe>. The value of the attribute can either be empty to apply all
* restrictions, or space-separated tokens to lift particular restrictions:
*
* @param null|SandboxValue|array<int|string,SandboxValue> $sandbox
* @return static
*/
public function setSandbox(null|SandboxValue|array $sandbox): self
{
// TODO test the ways this can be set
if (is_null($sandbox)) $this->unsetSandbox();
else {
if ($sandbox instanceof SandboxValue) $sandbox = [$sandbox];
if (count($sandbox) === 0) $sandbox = [SandboxValue::denyAll];
$this->attributes()['sandbox'] = new StringableEnumArray($sandbox, ' ');
}
return $this;
}
/**
* Controls the restrictions applied to the content embedded in the
* <iframe>. The value of the attribute can either be empty to apply all
* restrictions, or space-separated tokens to lift particular restrictions:
*
* @return self
*/
public function unsetSandbox(): self
{
unset($this->attributes()['sandbox']);
return $this;
}
/**
* The height of the frame in CSS pixels. Default is 150.
*
* @return null|integer
*/
public function height(): null|int
{
return $this->attributes()->asInt('height');
}
/**
* The height of the frame in CSS pixels. Default is 150.
*
* @param null|integer $height
* @return self
*/
public function setHeight(null|int $height): self
{
if (is_int($height)) $this->attributes()['height'] = $height;
else $this->unsetHeight();
return $this;
}
/**
* The height of the frame in CSS pixels. Default is 150.
*
* @return self
*/
public function unsetHeight(): self
{
unset($this->attributes()['height']);
return $this;
}
/**
* The URL of the page to embed. Use a value of about:blank to embed an
* empty page that conforms to the same-origin policy. Also note that
* programmatically removing an <iframe>'s src attribute (e.g. via
* Element.removeAttribute()) causes about:blank to be loaded in the frame
* in Firefox (from version 65), Chromium-based browsers, and Safari/iOS.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* The URL of the page to embed. Use a value of about:blank to embed an
* empty page that conforms to the same-origin policy. Also note that
* programmatically removing an <iframe>'s src attribute (e.g. via
* Element.removeAttribute()) causes about:blank to be loaded in the frame
* in Firefox (from version 65), Chromium-based browsers, and Safari/iOS.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* The URL of the page to embed. Use a value of about:blank to embed an
* empty page that conforms to the same-origin policy. Also note that
* programmatically removing an <iframe>'s src attribute (e.g. via
* Element.removeAttribute()) causes about:blank to be loaded in the frame
* in Firefox (from version 65), Chromium-based browsers, and Safari/iOS.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* Inline HTML to embed, overriding the src attribute. If a browser does not
* support the srcdoc attribute, it will fall back to the URL in the src
* attribute.
*
* @return null|string|Stringable
*/
public function srcdoc(): null|string|Stringable
{
return $this->attributes()->asString('srcdoc');
}
/**
* Inline HTML to embed, overriding the src attribute. If a browser does not
* support the srcdoc attribute, it will fall back to the URL in the src
* attribute.
*
* @param null|string|Stringable $srcdoc
* @return static
*/
public function setSrcdoc(null|string|Stringable $srcdoc): self
{
if ($srcdoc) $this->attributes()['srcdoc'] = $srcdoc;
else $this->unsetSrcdoc();
return $this;
}
/**
* Inline HTML to embed, overriding the src attribute. If a browser does not
* support the srcdoc attribute, it will fall back to the URL in the src
* attribute.
*
* @return static
*/
public function unsetSrcdoc(): self
{
unset($this->attributes()['srcdoc']);
return $this;
}
/**
* The width of the frame in CSS pixels. Default is 300.
*
* @return null|integer
*/
public function width(): null|int
{
return $this->attributes()->asInt('width');
}
/**
* The width of the frame in CSS pixels. Default is 300.
*
* @param null|integer $width
* @return self
*/
public function setWidth(null|int $width): self
{
if (is_int($width)) $this->attributes()['width'] = $width;
else $this->unsetWidth();
return $this;
}
/**
* The width of the frame in CSS pixels. Default is 300.
*
* @return self
*/
public function unsetWidth(): self
{
unset($this->attributes()['width']);
return $this;
}
}

View file

@ -0,0 +1,55 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\IframeTag;
/**
* A string indicating which referrer to use when fetching the resource.
*
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
*/
enum ReferrerPolicyValue: string
{
/**
* DEFAULT: Send a full URL when performing a same-origin request, only send
* the origin when the protocol security level stays the same (HTTPS→HTTPS),
* and send no header to a less secure destination (HTTPS→HTTP).
*/
case strictOriginWhenCrossOrigin = "strict-origin-when-cross-origin";
/**
* means that the Referer header will not be sent.
*/
case noReferrer = "no-referrer";
/**
* The Referer header will not be sent to origins without TLS (HTTPS).
*/
case noReferrerWhenDowngrade = "no-referrer-when-downgrade";
/**
* The sent referrer will be limited to the origin of the referring page:
* its scheme, host, and port.
*/
case origin = "origin";
/**
* The referrer sent to other origins will be limited to the scheme, the
* host, and the port. Navigations on the same origin will still include the
* path.
*/
case originWhenCrossOrigin = "origin-when-cross-origin";
/**
* A referrer will be sent for same origin, but cross-origin requests will
* contain no referrer information.
*/
case sameOrigin = "same-origin";
/**
* Only send the origin of the document as the referrer when the protocol
* security level stays the same (HTTPS→HTTPS), but don't send it to a less
* secure destination (HTTPS→HTTP).
*/
case strictOrigin = "strict-origin";
/**
* The referrer will include the origin and the path (but not the fragment,
* password, or username). THIS VALUE IS UNSAFE, because it leaks origins
* and paths from TLS-protected resources to insecure origins.
*/
case unsafeUrl = "unsafe-url";
}

View file

@ -0,0 +1,96 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\IframeTag;
/**
* Controls the restrictions applied to the content embedded in the <iframe>.
* The value of the attribute can either be empty to apply all restrictions, or
* space-separated tokens to lift particular restrictions:
*
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
*/
enum SandboxValue: string
{
case denyAll = "";
/**
* Allows downloading files through an <a> or <area> element with the
* download attribute, as well as through the navigation that leads to a
* download of a file. This works regardless of whether the user clicked on
* the link, or JS code initiated it without user interaction.
*/
case allowDownloads = "allow-downloads";
/**
* Allows for downloads to occur without a gesture from the user.
*
* @experimental
*/
case allowDownloadsWithoutInteraction = "allow-downloads-without-user-activation";
/**
* Allows the page to submit forms. If this keyword is not used, form will
* be displayed as normal, but submitting it will not trigger input
* validation, sending data to a web server or closing a dialog.
*/
case allowForms = "allow-forms";
/**
* Allows the page to open modal windows by Window.alert(),
* Window.confirm(), Window.print() and Window.prompt(), while opening a
* <dialog> is allowed regardless of this keyword. It also allows the page
* to receive BeforeUnloadEvent event.
*/
case allowModals = "allow-modals";
/**
* Lets the resource lock the screen orientation.
*/
case allowOrientationLock = "allow-orientation-lock";
/**
* Allows the page to use the Pointer Lock API.
*/
case allowPointerLock = "allow-pointer-lock";
/**
* Allows popups (like from Window.open(), target="_blank",
* Window.showModalDialog()). If this keyword is not used, that
* functionality will silently fail.
*/
case allowPopups = "allow-popups";
/**
* Allows a sandboxed document to open new windows without forcing the
* sandboxing flags upon them. This will allow, for example, a third-party
* advertisement to be safely sandboxed without forcing the same
* restrictions upon the page the ad links to.
*/
case allowPopupsToEscapeSandbox = "allow-popups-to-escape-sandbox";
/**
* Allows embedders to have control over whether an iframe can start a
* presentation session.
*/
case allowPresentation = "allow-presentation";
/**
* If this token is not used, the resource is treated as being from a
* special origin that always fails the same-origin policy (potentially
* preventing access to data storage/cookies and some JavaScript APIs).
*/
case allowSameOrigin = "allow-same-origin";
/**
* Allows the page to run scripts (but not create pop-up windows). If this
* keyword is not used, this operation is not allowed.
*/
case allowScripts = "allow-scripts";
/**
* Lets the resource navigate the top-level browsing context (the one named
* _top).
*/
case allowTopNavigation = "allow-top-navigation";
/**
* Lets the resource navigate the top-level browsing context, but only if
* initiated by a user gesture.
*/
case allowTopNavigationByUser = "allow-top-navigation-by-user-activation";
/**
* Allows navigations to non-http protocols built into browser or registered
* by a website. This feature is also activated by allow-popups or
* allow-top-navigation keyword.
*/
case allowTopNavigationToCustomProtocols = "allow-top-navigation-to-custom-protocols";
}

View file

@ -0,0 +1,569 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Multimedia\ImgTag\DecodingValue;
use ByJoby\HTML\Html5\Multimedia\ImgTag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Traits\CrossOriginTrait;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <img> HTML element embeds an image into the document.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
*/
class ImgTag extends AbstractTag
{
use CrossOriginTrait;
const TAG = "img";
/**
* Defines an alternative text description of the image.
*
* Setting this attribute to an empty string (alt="") indicates that this
* image is not a key part of the content (it's decoration or a tracking
* pixel), and that non-visual browsers may omit it from rendering. Visual
* browsers will also hide the broken image icon if the alt is empty and the
* image failed to display.
*
* @return null|string|Stringable
*/
public function alt(): null|string|Stringable
{
return $this->attributes()->asString('alt');
}
/**
* Defines an alternative text description of the image.
*
* Setting this attribute to an empty string (alt="") indicates that this
* image is not a key part of the content (it's decoration or a tracking
* pixel), and that non-visual browsers may omit it from rendering. Visual
* browsers will also hide the broken image icon if the alt is empty and the
* image failed to display.
*
* @param null|string|Stringable $alt
* @return self
*/
public function setAlt(null|string|Stringable $alt): self
{
if (is_null($alt)) $this->unsetAlt();
else $this->attributes()['alt'] = $alt;
return $this;
}
/**
* Defines an alternative text description of the image.
*
* Setting this attribute to an empty string (alt="") indicates that this
* image is not a key part of the content (it's decoration or a tracking
* pixel), and that non-visual browsers may omit it from rendering. Visual
* browsers will also hide the broken image icon if the alt is empty and the
* image failed to display.
*
* @return self
*/
public function unsetAlt(): self
{
unset($this->attributes()['alt']);
return $this;
}
/**
* This attribute provides a hint to the browser as to whether it should
* perform image decoding along with rendering the other DOM content in a
* single presentation step that looks more "correct" (sync), or render and
* present the other DOM content first and then decode the image and present
* it later (async). In practice, async means that the next paint does not
* wait for the image to decode.
*
* It is often difficult to perceive any noticeable effect when using
* decoding on static <img> elements. They'll likely be initially rendered
* as empty images while the image files are fetched (either from the
* network or from the cache) and then handled independently anyway, so the
* "syncing" of content updates is less apparent. However, the blocking of
* rendering while decoding happens, while often quite small, can be
* measured even if it is difficult to observe with the human eye. See
* What does the image decoding attribute actually do? for a more detailed
* analysis (tunetheweb.com, 2023).
*
* https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/
*
* @return null|DecodingValue
*/
public function decoding(): null|DecodingValue
{
return $this->attributes()->asEnum('decoding', DecodingValue::class);
}
/**
* This attribute provides a hint to the browser as to whether it should
* perform image decoding along with rendering the other DOM content in a
* single presentation step that looks more "correct" (sync), or render and
* present the other DOM content first and then decode the image and present
* it later (async). In practice, async means that the next paint does not
* wait for the image to decode.
*
* It is often difficult to perceive any noticeable effect when using
* decoding on static <img> elements. They'll likely be initially rendered
* as empty images while the image files are fetched (either from the
* network or from the cache) and then handled independently anyway, so the
* "syncing" of content updates is less apparent. However, the blocking of
* rendering while decoding happens, while often quite small, can be
* measured even if it is difficult to observe with the human eye. See
* What does the image decoding attribute actually do? for a more detailed
* analysis (tunetheweb.com, 2023).
*
* https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/
*
* @param null|DecodingValue $decoding
* @return self
*/
public function setDecoding(null|DecodingValue $decoding): self
{
if (!$decoding) $this->unsetDecoding();
else $this->attributes()['decoding'] = $decoding->value;
return $this;
}
/**
* This attribute provides a hint to the browser as to whether it should
* perform image decoding along with rendering the other DOM content in a
* single presentation step that looks more "correct" (sync), or render and
* present the other DOM content first and then decode the image and present
* it later (async). In practice, async means that the next paint does not
* wait for the image to decode.
*
* It is often difficult to perceive any noticeable effect when using
* decoding on static <img> elements. They'll likely be initially rendered
* as empty images while the image files are fetched (either from the
* network or from the cache) and then handled independently anyway, so the
* "syncing" of content updates is less apparent. However, the blocking of
* rendering while decoding happens, while often quite small, can be
* measured even if it is difficult to observe with the human eye. See
* What does the image decoding attribute actually do? for a more detailed
* analysis (tunetheweb.com, 2023).
*
* https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/
*
* @return self
*/
public function unsetDecoding(): self
{
unset($this->attributes()['decoding']);
return $this;
}
/**
* The intrinsic height of the image, in pixels. Must be an integer without
* a unit.
*
* @return null|integer
*/
public function height(): null|int
{
return $this->attributes()->asInt('height');
}
/**
* The intrinsic height of the image, in pixels. Must be an integer without
* a unit.
*
* @param null|integer $height
* @return self
*/
public function setHeight(null|int $height): self
{
if (is_int($height)) $this->attributes()['height'] = $height;
else $this->unsetHeight();
return $this;
}
/**
* The intrinsic height of the image, in pixels. Must be an integer without
* a unit.
*
* @return self
*/
public function unsetHeight(): self
{
unset($this->attributes()['height']);
return $this;
}
/**
* This Boolean attribute indicates that the image is part of a server-side
* map. If so, the coordinates where the user clicked on the image are sent
* to the server.
*
* https://en.wikipedia.org/wiki/Image_map#Server-side
*
* @return boolean
*/
public function ismap(): bool
{
return $this->attributes()['ismap'] === BooleanAttribute::true;
}
/**
* This Boolean attribute indicates that the image is part of a server-side
* map. If so, the coordinates where the user clicked on the image are sent
* to the server.
*
* https://en.wikipedia.org/wiki/Image_map#Server-side
*
* @param boolean $ismap
* @return self
*/
public function setIsmap(bool $ismap): self
{
if ($ismap) $this->attributes()['ismap'] = BooleanAttribute::true;
else unset($this->attributes()['ismap']);
return $this;
}
/**
* Defers loading the image until it reaches a calculated distance from the
* viewport, as defined by the browser. The intent is to avoid the network
* and storage bandwidth needed to handle the image until it's reasonably
* certain that it will be needed. This generally improves the performance
* of the content in most typical use cases.
*
* @return boolean
*/
public function lazy(): bool
{
return $this->attributes()['loading'] == 'lazy';
}
/**
* Defers loading the image until it reaches a calculated distance from the
* viewport, as defined by the browser. The intent is to avoid the network
* and storage bandwidth needed to handle the image until it's reasonably
* certain that it will be needed. This generally improves the performance
* of the content in most typical use cases.
*
* @param boolean $lazy
* @return self
*/
public function setLazy(bool $lazy): self
{
if ($lazy) $this->attributes()['loading'] = 'lazy';
else unset($this->attributes()['lazy']);
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return null|ReferrerPolicyValue
*/
public function referrerpolicy(): null|ReferrerPolicyValue
{
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicyValue::class);
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @param null|ReferrerPolicyValue $referrerpolicy
* @return static
*/
public function setReferrerpolicy(null|ReferrerPolicyValue $referrerpolicy): self
{
if ($referrerpolicy) $this->attributes()['referrerpolicy'] = $referrerpolicy->value;
else $this->unsetReferrerpolicy();
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return static
*/
public function unsetReferrerpolicy(): self
{
unset($this->attributes()['referrerpolicy']);
return $this;
}
/**
* One or more strings separated by commas, indicating a set of source
* sizes. Each source size consists of:
* * A media condition. This must be omitted for the last item in the list.
* * A source size value.
*
* Media Conditions describe properties of the viewport, not of the image.
* For example, (max-height: 500px) 1000px proposes to use a source of
* 1000px width, if the viewport is not higher than 500px.
*
* @return null|string|Stringable
*/
public function sizes(): null|string|Stringable
{
return $this->attributes()->asString('sizes');
}
/**
* One or more strings separated by commas, indicating a set of source
* sizes. Each source size consists of:
* * A media condition. This must be omitted for the last item in the list.
* * A source size value.
*
* Media Conditions describe properties of the viewport, not of the image.
* For example, (max-height: 500px) 1000px proposes to use a source of
* 1000px width, if the viewport is not higher than 500px.
*
* @param null|string|Stringable $sizes
* @return self
*/
public function setSizes(null|string|Stringable $sizes): self
{
if (is_null($sizes)) $this->unsetSizes();
else $this->attributes()['sizes'] = $sizes;
return $this;
}
/**
* One or more strings separated by commas, indicating a set of source
* sizes. Each source size consists of:
* * A media condition. This must be omitted for the last item in the list.
* * A source size value.
*
* Media Conditions describe properties of the viewport, not of the image.
* For example, (max-height: 500px) 1000px proposes to use a source of
* 1000px width, if the viewport is not higher than 500px.
*
* @return self
*/
public function unsetSizes(): self
{
unset($this->attributes()['sizes']);
return $this;
}
/**
* The image URL. Mandatory for the <img> element. On browsers supporting
* srcset, src is treated like a candidate image with a pixel density
* descriptor 1x, unless an image with this pixel density descriptor is
* already defined in srcset, or unless srcset contains w descriptors.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* The image URL. Mandatory for the <img> element. On browsers supporting
* srcset, src is treated like a candidate image with a pixel density
* descriptor 1x, unless an image with this pixel density descriptor is
* already defined in srcset, or unless srcset contains w descriptors.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* The image URL. Mandatory for the <img> element. On browsers supporting
* srcset, src is treated like a candidate image with a pixel density
* descriptor 1x, unless an image with this pixel density descriptor is
* already defined in srcset, or unless srcset contains w descriptors.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* One or more strings separated by commas, indicating possible image
* sources for the user agent to use. Each string is composed of:
* * A URL to an image
* * Optionally, whitespace followed by one of:
* * A width descriptor (a positive integer directly followed by w). The
* width descriptor is divided by the source size given in the sizes
* attribute to calculate the effective pixel density.
* * A pixel density descriptor (a positive floating point number
* directly followed by x).
*
* If no descriptor is specified, the source is assigned the default
* descriptor of 1x.
*
* If the srcset attribute uses width descriptors, the sizes attribute must
* also be present, or the srcset itself will be ignored.
*
* The user agent selects any of the available sources at its discretion.
* This provides them with significant leeway to tailor their selection
* based on things like user preferences or bandwidth conditions.
*
* https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
*
* @return null|string|Stringable
*/
public function srcset(): null|string|Stringable
{
return $this->attributes()->asString('srcset');
}
/**
* One or more strings separated by commas, indicating possible image
* sources for the user agent to use. Each string is composed of:
* * A URL to an image
* * Optionally, whitespace followed by one of:
* * A width descriptor (a positive integer directly followed by w). The
* width descriptor is divided by the source size given in the sizes
* attribute to calculate the effective pixel density.
* * A pixel density descriptor (a positive floating point number
* directly followed by x).
*
* If no descriptor is specified, the source is assigned the default
* descriptor of 1x.
*
* If the srcset attribute uses width descriptors, the sizes attribute must
* also be present, or the srcset itself will be ignored.
*
* The user agent selects any of the available sources at its discretion.
* This provides them with significant leeway to tailor their selection
* based on things like user preferences or bandwidth conditions.
*
* https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
*
* @param null|string|Stringable $srcset
* @return static
*/
public function setSrcset(null|string|Stringable $srcset): self
{
if ($srcset) $this->attributes()['srcset'] = $srcset;
else $this->unsetSrcset();
return $this;
}
/**
* One or more strings separated by commas, indicating possible image
* sources for the user agent to use. Each string is composed of:
* * A URL to an image
* * Optionally, whitespace followed by one of:
* * A width descriptor (a positive integer directly followed by w). The
* width descriptor is divided by the source size given in the sizes
* attribute to calculate the effective pixel density.
* * A pixel density descriptor (a positive floating point number
* directly followed by x).
*
* If no descriptor is specified, the source is assigned the default
* descriptor of 1x.
*
* If the srcset attribute uses width descriptors, the sizes attribute must
* also be present, or the srcset itself will be ignored.
*
* The user agent selects any of the available sources at its discretion.
* This provides them with significant leeway to tailor their selection
* based on things like user preferences or bandwidth conditions.
*
* https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
*
* @return static
*/
public function unsetSrcset(): self
{
unset($this->attributes()['srcset']);
return $this;
}
/**
* The intrinsic width of the image in pixels. Must be an integer without a
* unit.
*
* @return null|integer
*/
public function width(): null|int
{
return $this->attributes()->asInt('width');
}
/**
* The intrinsic width of the image in pixels. Must be an integer without a
* unit.
*
* @param null|integer $width
* @return self
*/
public function setWidth(null|int $width): self
{
if (is_int($width)) $this->attributes()['width'] = $width;
else $this->unsetWidth();
return $this;
}
/**
* The intrinsic width of the image in pixels. Must be an integer without a
* unit.
*
* @return self
*/
public function unsetWidth(): self
{
unset($this->attributes()['width']);
return $this;
}
/**
* The partial URL (starting with #) of an image map associated with the
* element.
*
* You can also pass in a MapTag object and its name will be automatically
* extracted and used.
*
* @return null|string|Stringable
*/
public function usemap(): null|string|Stringable
{
return $this->attributes()->asString('usemap');
}
/**
* The partial URL (starting with #) of an image map associated with the
* element.
*
* You can also pass in a MapTag object and its name will be automatically
* extracted and used.
*
* @param null|string|Stringable $usemap
* @return static
*/
public function setUsemap(null|string|Stringable|MapTag $usemap): self
{
if (empty($usemap)) return $this->unsetUsemap();
if ($usemap instanceof MapTag) $usemap = $usemap->name();
if (!str_starts_with($usemap, '#')) $usemap = '#' . $usemap;
$this->attributes()['usemap'] = $usemap;
return $this;
}
/**
* The partial URL (starting with #) of an image map associated with the
* element.
*
* You can also pass in a MapTag object and its name will be automatically
* extracted and used.
*
* @return static
*/
public function unsetUsemap(): self
{
unset($this->attributes()['usemap']);
return $this;
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\ImgTag;
enum DecodingValue: string {
/**
* No preference for the decoding mode; the browser decides what is best for the user. This is the default value.
*/
case auto = "auto";
/**
* Decode the image synchronously along with rendering the other DOM content, and present everything together.
*/
case sync = "sync";
/**
* Decode the image asynchronously, after rendering and presenting the other DOM content.
*/
case async = "async";
}

View file

@ -0,0 +1,55 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\ImgTag;
/**
* A string indicating which referrer to use when fetching the resource.
*
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
*/
enum ReferrerPolicyValue: string
{
/**
* DEFAULT: Send a full URL when performing a same-origin request, only send
* the origin when the protocol security level stays the same (HTTPS→HTTPS),
* and send no header to a less secure destination (HTTPS→HTTP).
*/
case strictOriginWhenCrossOrigin = "strict-origin-when-cross-origin";
/**
* means that the Referer header will not be sent.
*/
case noReferrer = "no-referrer";
/**
* The Referer header will not be sent to origins without TLS (HTTPS).
*/
case noReferrerWhenDowngrade = "no-referrer-when-downgrade";
/**
* The sent referrer will be limited to the origin of the referring page:
* its scheme, host, and port.
*/
case origin = "origin";
/**
* The referrer sent to other origins will be limited to the scheme, the
* host, and the port. Navigations on the same origin will still include the
* path.
*/
case originWhenCrossOrigin = "origin-when-cross-origin";
/**
* A referrer will be sent for same origin, but cross-origin requests will
* contain no referrer information.
*/
case sameOrigin = "same-origin";
/**
* Only send the origin of the document as the referrer when the protocol
* security level stays the same (HTTPS→HTTPS), but don't send it to a less
* secure destination (HTTPS→HTTP).
*/
case strictOrigin = "strict-origin";
/**
* The referrer will include the origin and the path (but not the fragment,
* password, or username). THIS VALUE IS UNSAFE, because it leaks origins
* and paths from TLS-protected resources to insecure origins.
*/
case unsafeUrl = "unsafe-url";
}

View file

@ -0,0 +1,86 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Containers\ContainerGroup;
use ByJoby\HTML\Tags\AbstractContainerTag;
use ByJoby\HTML\Tags\AbstractGroupedTag;
use Stringable;
/**
* The <map> HTML element is used with <area> elements to define an image map (a
* clickable link area).
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map
*/
class MapTag extends AbstractGroupedTag
{
const TAG = "map";
/** @var int */
protected static $autoname_counter = 0;
/**
* A name can be specified in the constructor. Because a name must be
* present, if one is not specified one will be automatically generated.
*
* @param string|Stringable|null $name
*/
public function __construct(string|Stringable $name = null)
{
$this->addGroup(ContainerGroup::ofTag('area'));
if (!$name) $name = static::autoname();
$this->setName($name);
}
/**
* Automatically generate a name from an incrementing counter
*
* @return string
*/
protected static function autoname(): string
{
return sprintf(
"%s-tag--%s",
static::TAG,
static::$autoname_counter++
);
}
/**
* The name attribute gives the map a name so that it can be referenced. The
* attribute must be present and must have a non-empty value with no space
* characters. The value of the name attribute must not be equal to the
* value of the name attribute of another <map> element in the same
* document. If the id attribute is also specified, both attributes must
* have the same value.
*
* @return string|Stringable
*/
public function name(): string|Stringable
{
$name = $this->attributes()->asString('name');
if (!$name) {
$name = static::autoname();
$this->setName($name);
}
return $name;
}
/**
* The name attribute gives the map a name so that it can be referenced. The
* attribute must be present and must have a non-empty value with no space
* characters. The value of the name attribute must not be equal to the
* value of the name attribute of another <map> element in the same
* document. If the id attribute is also specified, both attributes must
* have the same value.
*
* @param string|Stringable $name
* @return self
*/
public function setName(string|Stringable $name): self
{
$this->attributes()['name'] = $name;
return $this;
}
}

View file

@ -0,0 +1,163 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <object> HTML element represents an external resource, which can be treated as an image, a nested browsing context, or a resource to be handled by a plugin.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed
*/
class ObjectTag extends AbstractTag
{
const TAG = "object";
// TODO data attribute
// TODO form attribute
// TODO usemap attribute
/**
* The displayed height of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return null|integer
*/
public function height(): null|int
{
return $this->attributes()->asInt('height');
}
/**
* The displayed height of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @param null|integer $height
* @return self
*/
public function setHeight(null|int $height): self
{
if (is_int($height)) $this->attributes()['height'] = $height;
else $this->unsetHeight();
return $this;
}
/**
* The displayed height of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return self
*/
public function unsetHeight(): self
{
unset($this->attributes()['height']);
return $this;
}
/**
* The URL of the resource being embedded.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* The URL of the resource being embedded.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* The URL of the resource being embedded.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* The MIME type to use to select the plug-in to instantiate.
*
* @return null|string|Stringable
*/
public function type(): null|string|Stringable
{
return $this->attributes()->asString('type');
}
/**
* The MIME type to use to select the plug-in to instantiate.
*
* @param null|string|Stringable $type
* @return static
*/
public function setType(null|string|Stringable $type): self
{
if ($type) $this->attributes()['type'] = $type;
else $this->unsetType();
return $this;
}
/**
* The MIME type to use to select the plug-in to instantiate.
*
* @return static
*/
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;
}
/**
* The displayed width of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return null|integer
*/
public function width(): null|int
{
return $this->attributes()->asInt('width');
}
/**
* The displayed width of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @param null|integer $width
* @return self
*/
public function setWidth(null|int $width): self
{
if (is_int($width)) $this->attributes()['width'] = $width;
else $this->unsetWidth();
return $this;
}
/**
* The displayed width of the resource, in CSS pixels. This must be an
* absolute value; percentages are not allowed.
*
* @return self
*/
public function unsetWidth(): self
{
unset($this->attributes()['width']);
return $this;
}
}

View file

@ -0,0 +1,405 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <source> HTML element specifies multiple media resources for the
* <picture>, the <audio> element, or the <video> element. It is a void element,
* meaning that it has no content and does not have a closing tag. It is
* commonly used to offer the same media content in multiple file formats in
* order to provide compatibility with a broad range of browsers given their
* differing support for image file formats and media file formats.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source
*/
class SourceTag extends AbstractTag
{
/**
* The MIME media type of the image or other media type, optionally with a
* codecs parameter.
*
* Example: `audio/ogg; codecs=vorbis`
*
* @return null|string|Stringable
*/
public function type(): null|string|Stringable
{
return $this->attributes()->asString('type');
}
/**
* The MIME media type of the image or other media type, optionally with a
* codecs parameter.
*
* Example: `audio/ogg; codecs=vorbis`
*
* @param null|string|Stringable $type
* @return static
*/
public function setType(null|string|Stringable $type): self
{
if ($type) $this->attributes()['type'] = $type;
else $this->unsetType();
return $this;
}
/**
* The MIME media type of the image or other media type, optionally with a
* codecs parameter.
*
* Example: `audio/ogg; codecs=vorbis`
*
* @return static
*/
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;
}
/**
* Required if the source element's parent is an <audio> and <video>
* element, but not allowed if the source element's parent is a <picture>
* element.
*
* Address of the media resource.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* Required if the source element's parent is an <audio> and <video>
* element, but not allowed if the source element's parent is a <picture>
* element.
*
* Address of the media resource.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* Required if the source element's parent is an <audio> and <video>
* element, but not allowed if the source element's parent is a <picture>
* element.
*
* Address of the media resource.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* Required if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* A list of one or more strings, separated by commas, indicating a set of
* possible images represented by the source for the browser to use. Each
* string is composed of:
* * One URL specifying an image.
* * A width descriptor, which consists of a string containing a positive
* integer directly followed by "w", such as 300w. The default value, if
* missing, is the infinity.
* * A pixel density descriptor, that is a positive floating number
* directly followed by "x". The default value, if missing, is 1x.
*
* Each string in the list must have at least a width descriptor or a pixel
* density descriptor to be valid. The two types of descriptors should not
* be mixed together and only one should be used consistently throughout the
* list. Among the list, the value of each descriptor must be unique. The
* browser chooses the most adequate image to display at a given point of
* time. If the sizes attribute is present, then a width descriptor must be
* specified for each string. If the browser does not support srcset, then
* src will be used for the default source.
*
* https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
*
* @return null|string|Stringable
*/
public function srcset(): null|string|Stringable
{
return $this->attributes()->asString('srcset');
}
/**
* Required if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* A list of one or more strings, separated by commas, indicating a set of
* possible images represented by the source for the browser to use. Each
* string is composed of:
* * One URL specifying an image.
* * A width descriptor, which consists of a string containing a positive
* integer directly followed by "w", such as 300w. The default value, if
* missing, is the infinity.
* * A pixel density descriptor, that is a positive floating number
* directly followed by "x". The default value, if missing, is 1x.
*
* Each string in the list must have at least a width descriptor or a pixel
* density descriptor to be valid. The two types of descriptors should not
* be mixed together and only one should be used consistently throughout the
* list. Among the list, the value of each descriptor must be unique. The
* browser chooses the most adequate image to display at a given point of
* time. If the sizes attribute is present, then a width descriptor must be
* specified for each string. If the browser does not support srcset, then
* src will be used for the default source.
*
* https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
*
* @param null|string|Stringable $srcset
* @return static
*/
public function setSrcset(null|string|Stringable $srcset): self
{
if ($srcset) $this->attributes()['srcset'] = $srcset;
else $this->unsetSrcset();
return $this;
}
/**
* Required if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* A list of one or more strings, separated by commas, indicating a set of
* possible images represented by the source for the browser to use. Each
* string is composed of:
* * One URL specifying an image.
* * A width descriptor, which consists of a string containing a positive
* integer directly followed by "w", such as 300w. The default value, if
* missing, is the infinity.
* * A pixel density descriptor, that is a positive floating number
* directly followed by "x". The default value, if missing, is 1x.
*
* Each string in the list must have at least a width descriptor or a pixel
* density descriptor to be valid. The two types of descriptors should not
* be mixed together and only one should be used consistently throughout the
* list. Among the list, the value of each descriptor must be unique. The
* browser chooses the most adequate image to display at a given point of
* time. If the sizes attribute is present, then a width descriptor must be
* specified for each string. If the browser does not support srcset, then
* src will be used for the default source.
*
* https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images
*
* @return static
*/
public function unsetSrcset(): self
{
unset($this->attributes()['srcset']);
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* A list of source sizes that describes the final rendered width of the
* image represented by the source. Each source size consists of a
* comma-separated list of media condition-length pairs. Before laying the
* page out, the browser uses this information to determine which image is
* defined in srcset to use. Please note that sizes will have its effect
* only if width dimension descriptors are provided with srcset instead of
* pixel ratio values (200w instead of 2x for example).
*
* @return null|string|Stringable
*/
public function sizes(): null|string|Stringable
{
return $this->attributes()->asString('sizes');
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* A list of source sizes that describes the final rendered width of the
* image represented by the source. Each source size consists of a
* comma-separated list of media condition-length pairs. Before laying the
* page out, the browser uses this information to determine which image is
* defined in srcset to use. Please note that sizes will have its effect
* only if width dimension descriptors are provided with srcset instead of
* pixel ratio values (200w instead of 2x for example).
*
* @param null|string|Stringable $sizes
* @return self
*/
public function setSizes(null|string|Stringable $sizes): self
{
if (is_null($sizes)) $this->unsetSizes();
else $this->attributes()['sizes'] = $sizes;
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* A list of source sizes that describes the final rendered width of the
* image represented by the source. Each source size consists of a
* comma-separated list of media condition-length pairs. Before laying the
* page out, the browser uses this information to determine which image is
* defined in srcset to use. Please note that sizes will have its effect
* only if width dimension descriptors are provided with srcset instead of
* pixel ratio values (200w instead of 2x for example).
*
* @return self
*/
public function unsetSizes(): self
{
unset($this->attributes()['sizes']);
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* Media query of the resource's intended media.
*
* @return null|string|Stringable
*/
public function media(): null|string|Stringable
{
return $this->attributes()->asString('media');
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* Media query of the resource's intended media.
*
* @param null|string|Stringable $media
* @return static
*/
public function setMedia(null|string|Stringable $media): self
{
if ($media) $this->attributes()['media'] = $media;
else $this->unsetMedia();
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* Media query of the resource's intended media.
*
* @return static
*/
public function unsetMedia(): self
{
unset($this->attributes()['media']);
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* The intrinsic height of the image, in pixels. Must be an integer without
* a unit.
*
* @return null|integer
*/
public function height(): null|int
{
return $this->attributes()->asInt('height');
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* The intrinsic height of the image, in pixels. Must be an integer without
* a unit.
*
* @param null|integer $height
* @return self
*/
public function setHeight(null|int $height): self
{
if (is_int($height)) $this->attributes()['height'] = $height;
else $this->unsetHeight();
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* The intrinsic height of the image, in pixels. Must be an integer without
* a unit.
*
* @return self
*/
public function unsetHeight(): self
{
unset($this->attributes()['height']);
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* The intrinsic width of the image in pixels. Must be an integer without a
* unit.
*
* @return null|integer
*/
public function width(): null|int
{
return $this->attributes()->asInt('width');
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* The intrinsic width of the image in pixels. Must be an integer without a
* unit.
*
* @param null|integer $width
* @return self
*/
public function setWidth(null|int $width): self
{
if (is_int($width)) $this->attributes()['width'] = $width;
else $this->unsetWidth();
return $this;
}
/**
* Allowed if the source element's parent is a <picture> element, but not
* allowed if the source element's parent is an <audio> or <video> element.
*
* The intrinsic width of the image in pixels. Must be an integer without a
* unit.
*
* @return self
*/
public function unsetWidth(): self
{
unset($this->attributes()['width']);
return $this;
}
}

View file

@ -0,0 +1,209 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Multimedia\TrackTag\KindValue;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
/**
* The <track> HTML element is used as a child of the media elements, <audio>
* and <video>. It lets you specify timed text tracks (or time-based data), for
* example to automatically handle subtitles. The tracks are formatted in WebVTT
* format (.vtt files) Web Video Text Tracks.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track
*/
class TrackTag extends AbstractTag
{
const TAG = "track";
/**
* This attribute indicates that the track should be enabled unless the
* user's preferences indicate that another track is more appropriate. This
* may only be used on one track element per media element.
*
* @return boolean
*/
public function default(): bool
{
return $this->attributes()['default'] === BooleanAttribute::true;
}
/**
* This attribute indicates that the track should be enabled unless the
* user's preferences indicate that another track is more appropriate. This
* may only be used on one track element per media element.
*
* @param boolean $default
* @return self
*/
public function setDefault(bool $default): self
{
if ($default) $this->attributes()['default'] = BooleanAttribute::true;
else unset($this->attributes()['default']);
return $this;
}
/**
* How the text track is meant to be used. If omitted the default kind is
* subtitles. If the attribute contains an invalid value, it will use
* metadata (Versions of Chrome earlier than 52 treated an invalid value as
* subtitles).
*
* @return null|KindValue
*/
public function kind(): null|KindValue
{
return $this->attributes()->asEnum('kind', KindValue::class);
}
/**
* How the text track is meant to be used. If omitted the default kind is
* subtitles. If the attribute contains an invalid value, it will use
* metadata (Versions of Chrome earlier than 52 treated an invalid value as
* subtitles).
*
* @param null|KindValue $kind
* @return self
*/
public function setKind(null|KindValue $kind): self
{
if ($kind) $this->attributes()['kind'] = $kind->value;
else $this->unsetKind();
return $this;
}
/**
* How the text track is meant to be used. If omitted the default kind is
* subtitles. If the attribute contains an invalid value, it will use
* metadata (Versions of Chrome earlier than 52 treated an invalid value as
* subtitles).
*
* @return self
*/
public function unsetKind(): self
{
unset($this->attributes()['kind']);
return $this;
}
/**
* A user-readable title of the text track which is used by the browser when
* listing available text tracks.
*
* @return null|string|Stringable
*/
public function label(): null|string|Stringable
{
return $this->attributes()->asString('label');
}
/**
* A user-readable title of the text track which is used by the browser when
* listing available text tracks.
*
* @param null|string|Stringable $label
* @return static
*/
public function setLabel(null|string|Stringable $label): self
{
if ($label) $this->attributes()['label'] = $label;
else $this->unsetLabel();
return $this;
}
/**
* A user-readable title of the text track which is used by the browser when
* listing available text tracks.
*
* @return static
*/
public function unsetLabel(): self
{
unset($this->attributes()['label']);
return $this;
}
/**
* Address of the track (.vtt file). Must be a valid URL. This attribute
* must be specified and its URL value must have the same origin as the
* document unless the <audio> or <video> parent element of the track
* element has a crossorigin attribute.
*
* @return null|string|Stringable
*/
public function src(): null|string|Stringable
{
return $this->attributes()->asString('src');
}
/**
* Address of the track (.vtt file). Must be a valid URL. This attribute
* must be specified and its URL value must have the same origin as the
* document unless the <audio> or <video> parent element of the track
* element has a crossorigin attribute.
*
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
return $this;
}
/**
* Address of the track (.vtt file). Must be a valid URL. This attribute
* must be specified and its URL value must have the same origin as the
* document unless the <audio> or <video> parent element of the track
* element has a crossorigin attribute.
*
* @return static
*/
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
}
/**
* Language of the track text data. It must be a valid BCP 47 language tag.
* If the kind attribute is set to subtitles, then srclang must be defined.
*
* @return null|string|Stringable
*/
public function srclang(): null|string|Stringable
{
return $this->attributes()->asString('srclang');
}
/**
* Language of the track text data. It must be a valid BCP 47 language tag.
* If the kind attribute is set to subtitles, then srclang must be defined.
*
* @param null|string|Stringable $srclang
* @return static
*/
public function setSrclang(null|string|Stringable $srclang): self
{
if ($srclang) $this->attributes()['srclang'] = $srclang;
else $this->unsetSrclang();
return $this;
}
/**
* Language of the track text data. It must be a valid BCP 47 language tag.
* If the kind attribute is set to subtitles, then srclang must be defined.
*
* @return static
*/
public function unsetSrclang(): self
{
unset($this->attributes()['srclang']);
return $this;
}
}

View file

@ -0,0 +1,52 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia\TrackTag;
/**
* How the text track is meant to be used. If omitted the default kind is
* subtitles. If the attribute contains an invalid value, it will use metadata
* (Versions of Chrome earlier than 52 treated an invalid value as subtitles).
* The following keywords are allowed:
*
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track
*/
enum KindValue: string
{
/**
* Subtitles provide translation of content that cannot be understood by the
* viewer. For example speech or text that is not English in an English
* language film.
*
* Subtitles may contain additional content, usually extra background
* information. For example the text at the beginning of the Star Wars
* films, or the date, time, and location of a scene.
*/
case subtitles = "subtitles";
/**
* Closed captions provide a transcription and possibly a translation of
* audio.
*
* It may include important non-verbal information such as music cues or
* sound effects. It may indicate the cue's source (e.g. music, text,
* character).
*
* Suitable for users who are deaf or when the sound is muted.
*/
case captions = "captions";
/**
* Textual description of the video content.
*
* Suitable for users who are blind or where the video cannot be seen.
*/
case descriptions = "descriptions";
/**
* Chapter titles are intended to be used when the user is navigating the
* media resource.
*/
case chapters = "chapters";
/**
* Tracks used by scripts. Not visible to the user.
*/
case metadata = "metadata";
}

View file

@ -0,0 +1,156 @@
<?php
namespace ByJoby\HTML\Html5\Multimedia;
use ByJoby\HTML\Helpers\BooleanAttribute;
use Stringable;
/**
* The <video> HTML element embeds a media player which supports video playback
* into the document. You can use <video> for audio content as well, but the
* <audio> element may provide a more appropriate user experience.
*
* Tag description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
*/
class VideoTag extends AbstractPlaybackTag
{
const TAG = 'video';
/**
* The height of the video's display area, in CSS pixels
*
* @return null|integer
*/
public function height(): null|int
{
return $this->attributes()->asInt('height');
}
/**
* The height of the video's display area, in CSS pixels
*
* @param null|integer $height
* @return self
*/
public function setHeight(null|int $height): self
{
if (is_int($height)) $this->attributes()['height'] = $height;
else $this->unsetHeight();
return $this;
}
/**
* The height of the video's display area, in CSS pixels
*
* @return self
*/
public function unsetHeight(): self
{
unset($this->attributes()['height']);
return $this;
}
/**
* A Boolean attribute indicating that the video is to be played "inline",
* that is within the element's playback area. Note that the absence of this
* attribute does not imply that the video will always be played in
* fullscreen.
*
* @return boolean
*/
public function playsinline(): bool
{
return $this->attributes()['playsinline'] === BooleanAttribute::true;
}
/**
* A Boolean attribute indicating that the video is to be played "inline",
* that is within the element's playback area. Note that the absence of this
* attribute does not imply that the video will always be played in
* fullscreen.
*
* @param boolean $playsinline
* @return self
*/
public function setPlaysinline(bool $playsinline): self
{
if ($playsinline) $this->attributes()['playslinline'] = BooleanAttribute::true;
else unset($this->attributes()['playsinline']);
return $this;
}
/**
* A URL for an image to be shown while the video is downloading. If this
* attribute isn't specified, nothing is displayed until the first frame is
* available, then the first frame is shown as the poster frame.
*
* @return null|string|Stringable
*/
public function poster(): null|string|Stringable
{
return $this->attributes()->asString('poster');
}
/**
* A URL for an image to be shown while the video is downloading. If this
* attribute isn't specified, nothing is displayed until the first frame is
* available, then the first frame is shown as the poster frame.
*
* @param null|string|Stringable $poster
* @return self
*/
public function setPoster(null|string|Stringable $poster): self
{
if ($poster) $this->attributes()['poster'] = $poster;
else $this->unsetPoster();
return $this;
}
/**
* A URL for an image to be shown while the video is downloading. If this
* attribute isn't specified, nothing is displayed until the first frame is
* available, then the first frame is shown as the poster frame.
*
* @return self
*/
public function unsetPoster(): self
{
unset($this->attributes()['poster']);
return $this;
}
/**
* The width of the video's display area, in CSS pixels
*
* @return null|integer
*/
public function width(): null|int
{
return $this->attributes()->asInt('width');
}
/**
* The width of the video's display area, in CSS pixels
*
* @param null|integer $width
* @return self
*/
public function setWidth(null|int $width): self
{
if (is_int($width)) $this->attributes()['width'] = $width;
else $this->unsetWidth();
return $this;
}
/**
* The width of the video's display area, in CSS pixels
*
* @return self
*/
public function unsetWidth(): self
{
unset($this->attributes()['width']);
return $this;
}
}

View file

@ -40,7 +40,7 @@ class BaseTag extends AbstractTag
* @param null|string|Stringable $href
* @return static
*/
public function setHref(null|string|Stringable $href): static
public function setHref(null|string|Stringable $href): self
{
if ($href) $this->attributes()['href'] = $href;
else $this->unsetHref();
@ -54,7 +54,7 @@ class BaseTag extends AbstractTag
*
* @return static
*/
public function unsetHref(): static
public function unsetHref(): self
{
unset($this->attributes()['href']);
return $this;
@ -81,7 +81,7 @@ class BaseTag extends AbstractTag
* @param null|string|Stringable|BrowsingContext $target
* @return static
*/
public function setTarget(null|string|Stringable|BrowsingContext $target): static
public function setTarget(null|string|Stringable|BrowsingContext $target): self
{
if (!$target) {
$this->unsetTarget();
@ -100,7 +100,7 @@ class BaseTag extends AbstractTag
*
* @return static
*/
public function unsetTarget(): static
public function unsetTarget(): self
{
unset($this->attributes()['target']);
return $this;

View file

@ -2,11 +2,12 @@
namespace ByJoby\HTML\Html5\Tags;
use ByJoby\HTML\Html5\Enums\As_link;
use ByJoby\HTML\Html5\Enums\CrossOrigin;
use ByJoby\HTML\Html5\Enums\ReferrerPolicy_link;
use ByJoby\HTML\Html5\Enums\Rel_link;
use ByJoby\HTML\Html5\Exceptions\InvalidArgumentsException;
use ByJoby\HTML\Html5\Tags\LinkTag\AsValue;
use ByJoby\HTML\Html5\Tags\LinkTag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Tags\LinkTag\RelValue;
use ByJoby\HTML\Html5\Traits\CrossOriginTrait;
use ByJoby\HTML\Html5\Traits\CrossoriginTrait\CrossOriginValue;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
@ -22,6 +23,7 @@ use Stringable;
*/
class LinkTag extends AbstractTag
{
use CrossOriginTrait;
const TAG = 'link';
/**
@ -29,11 +31,11 @@ class LinkTag extends AbstractTag
* document. The attribute must be a space-separated list of link type
* values.
*
* @return Rel_link[]
* @return RelValue[]
*/
public function rel(): array
{
return $this->attributes()->asEnumArray('rel', Rel_link::class, ' ');
return $this->attributes()->asEnumArray('rel', RelValue::class, ' ');
}
/**
@ -45,20 +47,20 @@ class LinkTag extends AbstractTag
*
* if $as is As_link::fetch then $crossorigin must be specified
*
* @param null|Rel_link|array<int|string,Rel_link> $rel
* @param null|As_link|null $as
* @param null|CrossOrigin|null $crossorigin
* @param null|RelValue|array<int|string,RelValue> $rel
* @param null|AsValue|null $as
* @param null|CrossOriginValue|null $crossorigin
* @return static
*/
public function setRel(null|Rel_link|array $rel, null|As_link $as = null, null|CrossOrigin $crossorigin = null): static
public function setRel(null|RelValue|array $rel, null|AsValue $as = null, null|CrossOriginValue $crossorigin = null): self
{
if (!$rel) {
$this->unsetRel();
} else {
$this->attributes()->setEnumArray('rel', $rel, Rel_link::class, ' ');
$this->attributes()->setEnumArray('rel', $rel, RelValue::class, ' ');
// check if new value includes Rel_link::preload and require $as if so
$rel = $this->rel();
if (in_array(Rel_link::preload, $rel)) {
if (in_array(RelValue::preload, $rel)) {
if (!$as) {
throw new InvalidArgumentsException('$as is required when $rel includes Rel_link::preload');
}
@ -78,7 +80,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetRel(): static
public function unsetRel(): self
{
unset($this->attributes()['rel']);
return $this;
@ -91,11 +93,11 @@ class LinkTag extends AbstractTag
* <link>, which is necessary for request matching, application of correct
* content security policy, and setting of correct Accept request header.
*
* @return null|As_link
* @return null|AsValue
*/
public function as (): null|As_link
public function as (): null|AsValue
{
return $this->attributes()->asEnum('as', As_link::class);
return $this->attributes()->asEnum('as', AsValue::class);
}
/**
@ -107,18 +109,18 @@ class LinkTag extends AbstractTag
*
* if $as is As_link::fetch then $crossorigin must be specified
*
* @param null|As_link $as
* @param null|CrossOrigin|null $crossorigin
* @param null|AsValue $as
* @param null|CrossOriginValue|null $crossorigin
* @return static
*/
public function setAs(null|As_link $as, null|CrossOrigin $crossorigin = null): static
public function setAs(null|AsValue $as, null|CrossOriginValue $crossorigin = null): self
{
if (!$as) {
$this->unsetAs();
} else {
$this->attributes()['as'] = $as->value;
// check if we just set as to As_link::fetch and require $crossorigin if so
if ($as == As_link::fetch) {
if ($as == AsValue::fetch) {
if (!$crossorigin) {
throw new InvalidArgumentsException('$crossorigin is required when $as is As_link::fetch');
}
@ -140,55 +142,12 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetAs(): static
public function unsetAs(): self
{
unset($this->attributes()['as']);
return $this;
}
/**
* This enumerated attribute indicates whether CORS must be used when
* fetching the resource. CORS-enabled images can be reused in the <canvas>
* element without being tainted. The allowed values are:
*
* @return null|CrossOrigin
*/
public function crossorigin(): null|CrossOrigin
{
return $this->attributes()->asEnum('crossorigin', CrossOrigin::class);
}
/**
* This enumerated attribute indicates whether CORS must be used when
* fetching the resource. CORS-enabled images can be reused in the <canvas>
* element without being tainted. The allowed values are:
*
* @param null|CrossOrigin $crossorigin
* @return static
*/
public function setCrossorigin(null|CrossOrigin $crossorigin): static
{
if (!$crossorigin) {
$this->unsetCrossorigin();
} else {
$this->attributes()['crossorigin'] = $crossorigin->value;
}
return $this;
}
/**
* This enumerated attribute indicates whether CORS must be used when
* fetching the resource. CORS-enabled images can be reused in the <canvas>
* element without being tainted. The allowed values are:
*
* @return static
*/
public function unsetCrossorigin(): static
{
unset($this->attributes()['crossorigin']);
return $this;
}
/**
* This attribute specifies the URL of the linked resource. A URL can be
* absolute or relative.
@ -207,7 +166,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $href
* @return static
*/
public function setHref(null|string|Stringable $href): static
public function setHref(null|string|Stringable $href): self
{
if ($href) $this->attributes()['href'] = $href;
else $this->unsetHref();
@ -220,7 +179,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetHref(): static
public function unsetHref(): self
{
$this->unsetHreflang();
unset($this->attributes()['href']);
@ -251,7 +210,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $hreflang
* @return static
*/
public function setHreflang(null|string|Stringable $hreflang): static
public function setHreflang(null|string|Stringable $hreflang): self
{
if ($hreflang) $this->attributes()['hreflang'] = $hreflang;
else $this->unsetHreflang();
@ -266,7 +225,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetHreflang(): static
public function unsetHreflang(): self
{
unset($this->attributes()['hreflang']);
return $this;
@ -294,7 +253,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $imagesizes
* @return static
*/
public function setImagesizes(null|string|Stringable $imagesizes): static
public function setImagesizes(null|string|Stringable $imagesizes): self
{
if ($imagesizes) $this->attributes()['imagesizes'] = $imagesizes;
else $this->unsetImagesizes();
@ -309,7 +268,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetImagesizes(): static
public function unsetImagesizes(): self
{
unset($this->attributes()['imagesizes']);
return $this;
@ -337,7 +296,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $imagesrcset
* @return static
*/
public function setImagesrcset(null|string|Stringable $imagesrcset): static
public function setImagesrcset(null|string|Stringable $imagesrcset): self
{
if ($imagesrcset) $this->attributes()['imagesrcset'] = $imagesrcset;
else $this->unsetImagesrcset();
@ -352,7 +311,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetImagesrcset(): static
public function unsetImagesrcset(): self
{
unset($this->attributes()['imagesrcset']);
return $this;
@ -380,7 +339,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $integrity
* @return static
*/
public function setIntegrity(null|string|Stringable $integrity): static
public function setIntegrity(null|string|Stringable $integrity): self
{
if ($integrity) $this->attributes()['integrity'] = $integrity;
else $this->unsetIntegrity();
@ -395,7 +354,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetIntegrity(): static
public function unsetIntegrity(): self
{
unset($this->attributes()['integrity']);
return $this;
@ -423,7 +382,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $media
* @return static
*/
public function setMedia(null|string|Stringable $media): static
public function setMedia(null|string|Stringable $media): self
{
if ($media) $this->attributes()['media'] = $media;
else $this->unsetMedia();
@ -438,7 +397,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetMedia(): static
public function unsetMedia(): self
{
unset($this->attributes()['media']);
return $this;
@ -447,20 +406,20 @@ class LinkTag extends AbstractTag
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return null|ReferrerPolicy_link
* @return null|ReferrerPolicyValue
*/
public function referrerpolicy(): null|ReferrerPolicy_link
public function referrerpolicy(): null|ReferrerPolicyValue
{
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicy_link::class);
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicyValue::class);
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @param null|ReferrerPolicy_link $referrerpolicy
* @param null|ReferrerPolicyValue $referrerpolicy
* @return static
*/
public function setReferrerpolicy(null|ReferrerPolicy_link $referrerpolicy): static
public function setReferrerpolicy(null|ReferrerPolicyValue $referrerpolicy): self
{
if ($referrerpolicy) $this->attributes()['referrerpolicy'] = $referrerpolicy->value;
else $this->unsetReferrerpolicy();
@ -472,7 +431,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetReferrerpolicy(): static
public function unsetReferrerpolicy(): self
{
unset($this->attributes()['referrerpolicy']);
return $this;
@ -508,7 +467,7 @@ class LinkTag extends AbstractTag
* @param null|string|Stringable $type
* @return static
*/
public function setType(null|string|Stringable $type): static
public function setType(null|string|Stringable $type): self
{
if ($type) $this->attributes()['type'] = $type;
else $this->unsetType();
@ -527,7 +486,7 @@ class LinkTag extends AbstractTag
*
* @return static
*/
public function unsetType(): static
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;

View file

@ -1,16 +1,22 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\LinkTag;
/**
* This attribute is required when rel="preload" has been set on the <link> element, optional when rel="modulepreload" has been set, and otherwise should not be used. It specifies the type of content being loaded by the <link>, which is necessary for request matching, application of correct content security policy, and setting of correct Accept request header.
*
* Furthermore, rel="preload" uses this as a signal for request prioritization. The value comments list the valid values for this attribute and the elements or resources they apply to.
*
* This attribute is required when rel="preload" has been set on the <link>
* element, optional when rel="modulepreload" has been set, and otherwise should
* not be used. It specifies the type of content being loaded by the <link>,
* which is necessary for request matching, application of correct content
* security policy, and setting of correct Accept request header.
*
* Furthermore, rel="preload" uses this as a signal for request prioritization.
* The value comments list the valid values for this attribute and the elements
* or resources they apply to.
*
* Descriptions by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
*/
enum As_link: string {
enum AsValue: string {
/**
* Applies to <audio> elements
*/
@ -24,8 +30,8 @@ enum As_link: string {
*/
case embed = "embed";
/**
* Applies to fetch, XHR
* Note: This value also requires <link> to contain the crossorigin attribute.
* Applies to fetch, XHR Note: This value also requires <link> to contain
* the crossorigin attribute.
*/
case fetch = "fetch";
/**
@ -33,7 +39,8 @@ enum As_link: string {
*/
case font = "font";
/**
* Applies to <img> and <picture> elements with srcset or imageset attributes, SVG <image> elements, CSS *-image rules
* Applies to <img> and <picture> elements with srcset or imageset
* attributes, SVG <image> elements, CSS *-image rules
*/
case image = "image";
/**

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\LinkTag;
/**
* A string indicating which referrer to use when fetching the resource. These
@ -9,7 +9,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
*/
enum ReferrerPolicy_link: string
enum ReferrerPolicyValue: string
{
/**
* means that the Referer header will not be sent.

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\LinkTag;
/**
* The rel attribute defines the relationship between a linked resource and the
@ -9,7 +9,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel
*/
enum Rel_link: string
enum RelValue: string
{
/**
* Alternate representations of the current document.

View file

@ -3,9 +3,9 @@
namespace ByJoby\HTML\Html5\Tags;
use ByJoby\HTML\Helpers\StringableEnumArray;
use ByJoby\HTML\Html5\Enums\HttpEquiv_meta;
use ByJoby\HTML\Html5\Enums\Name_meta;
use ByJoby\HTML\Html5\Enums\Robots_meta;
use ByJoby\HTML\Html5\Tags\MetaTag\HttpEquivValue;
use ByJoby\HTML\Html5\Tags\MetaTag\NameValue;
use ByJoby\HTML\Html5\Tags\MetaTag\RobotsValue;
use ByJoby\HTML\Tags\AbstractTag;
use Stringable;
@ -30,13 +30,13 @@ class MetaTag extends AbstractTag
* metadata names defined in the HTML specification.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name
*
* @param string|Stringable|Name_meta $name
* @param string|Stringable|NameValue $name
* @param string|Stringable $content
* @return static
*/
public function setNameAndContent(string|Stringable|Name_meta $name, string|Stringable $content): static
public function setNameAndContent(string|Stringable|NameValue $name, string|Stringable $content): self
{
if ($name instanceof Name_meta) {
if ($name instanceof NameValue) {
$name = $name->value;
}
unset($this->attributes()['http-equiv']);
@ -50,11 +50,11 @@ class MetaTag extends AbstractTag
* Defines a pragma directive. The attribute is named http-equiv(alent)
* because all the allowed values are names of particular HTTP headers.
*
* @param HttpEquiv_meta $name
* @param HttpEquivValue $name
* @param string|Stringable $content
* @return static
*/
public function setHttpEquivAndContent(HttpEquiv_meta $name, string|Stringable $content): static
public function setHttpEquivAndContent(HttpEquivValue $name, string|Stringable $content): self
{
unset($this->attributes()['name']);
unset($this->attributes()['charset']);
@ -64,18 +64,19 @@ class MetaTag extends AbstractTag
}
/**
* he behavior that cooperative crawlers, or "robots", should use with the page
* The behavior that cooperative crawlers, or "robots", should use with the
* page
*
* @param Robots_meta|Robots_meta[] $robots
* @param RobotsValue|RobotsValue[] $robots
* @return static
*/
public function setRobots(Robots_meta|array $robots): static
public function setRobots(RobotsValue|array $robots): self
{
if (!is_array($robots)) {
$robots = [$robots];
}
$this->setNameAndContent(
Name_meta::robots,
NameValue::robots,
new StringableEnumArray($robots, ',')
);
return $this;
@ -108,11 +109,11 @@ class MetaTag extends AbstractTag
* metadata in terms of name-value pairs, with the name attribute giving the
* metadata name, and the content attribute giving the value.
*
* @return null|string|Stringable|Name_meta
* @return null|string|Stringable|NameValue
*/
public function name(): null|string|Stringable|Name_meta
public function name(): null|string|Stringable|NameValue
{
return $this->attributes()->asEnum('name', Name_meta::class)
return $this->attributes()->asEnum('name', NameValue::class)
?? $this->attributes()->asString('name');
}
@ -120,11 +121,11 @@ class MetaTag extends AbstractTag
* Defines a pragma directive. The attribute is named http-equiv(alent)
* because all the allowed values are names of particular HTTP headers.
*
* @return null|HttpEquiv_meta
* @return null|HttpEquivValue
*/
public function httpEquiv(): null|HttpEquiv_meta
public function httpEquiv(): null|HttpEquivValue
{
return $this->attributes()->asEnum('http-equiv', HttpEquiv_meta::class);
return $this->attributes()->asEnum('http-equiv', HttpEquivValue::class);
}
/**
@ -134,7 +135,7 @@ class MetaTag extends AbstractTag
* @param boolean $charset
* @return static
*/
public function setCharset(bool $charset): static
public function setCharset(bool $charset): self
{
if ($charset) {
$this->attributes()['charset'] = 'utf-8';

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\MetaTag;
/**
* Defines a pragma directive. The attribute is named http-equiv(alent) because
@ -9,7 +9,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Descriptions by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv
*/
enum HttpEquiv_meta: string {
enum HttpEquivValue: string {
/**
* Allows page authors to define a content policy for the current page.
* Content policies mostly specify allowed server origins and script

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\MetaTag;
/**
* Includes a selection of standard metadata names defined in the HTML and CSS standards as well as the WHATWG Wiki MetaExtensions page.
@ -8,7 +8,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Descriptions by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name
*/
enum Name_meta: string
enum NameValue: string
{
/**
* the name of the application running in the web page.

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\MetaTag;
/**
* the behavior that cooperative crawlers, or "robots", should use. Meant to be
@ -9,7 +9,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Descriptions by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name
*/
enum Robots_meta: string {
enum RobotsValue: string {
/**
* Allows the robot to index the page (default).
*/

View file

@ -2,10 +2,10 @@
namespace ByJoby\HTML\Html5\Tags;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use ByJoby\HTML\Html5\Enums\CrossOrigin;
use ByJoby\HTML\Html5\Enums\ReferrerPolicy_script;
use ByJoby\HTML\Html5\Enums\Type_script;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Tags\ScriptTag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Tags\ScriptTag\TypeValue;
use ByJoby\HTML\Html5\Traits\CrossOriginTrait;
use ByJoby\HTML\Tags\AbstractContentTag;
use Stringable;
@ -20,6 +20,7 @@ use Stringable;
*/
class ScriptTag extends AbstractContentTag
{
use CrossOriginTrait;
const TAG = 'script';
/**
@ -39,7 +40,7 @@ class ScriptTag extends AbstractContentTag
* @param boolean $async
* @return static
*/
public function setAsync(bool $async): static
public function setAsync(bool $async): self
{
if ($async) $this->attributes()['async'] = BooleanAttribute::true;
else unset($this->attributes()['async']);
@ -78,7 +79,7 @@ class ScriptTag extends AbstractContentTag
* @param boolean $defer
* @return static
*/
public function setDefer(bool $defer): static
public function setDefer(bool $defer): self
{
if ($defer) $this->attributes()['defer'] = BooleanAttribute::true;
else unset($this->attributes()['defer']);
@ -100,52 +101,6 @@ class ScriptTag extends AbstractContentTag
return $this->attributes()['defer'] === BooleanAttribute::true;
}
/**
* Normal script elements pass minimal information to the window.onerror for
* scripts which do not pass the standard CORS checks. To allow error
* logging for sites which use a separate domain for static media, use this
* attribute. See CORS settings attributes for a more descriptive
* explanation of its valid arguments.
*
* @return null|CrossOrigin
*/
public function crossorigin(): null|CrossOrigin
{
return $this->attributes()->asEnum('crossorigin', CrossOrigin::class);
}
/**
* Normal script elements pass minimal information to the window.onerror for
* scripts which do not pass the standard CORS checks. To allow error
* logging for sites which use a separate domain for static media, use this
* attribute. See CORS settings attributes for a more descriptive
* explanation of its valid arguments.
*
* @param null|CrossOrigin $crossorigin
* @return static
*/
public function setCrossorigin(null|CrossOrigin $crossorigin): static
{
if ($crossorigin) $this->attributes()['crossorigin'] = $crossorigin->value;
else unset($this->attributes()['crossorigin']);
return $this;
}
/**
* Normal script elements pass minimal information to the window.onerror for
* scripts which do not pass the standard CORS checks. To allow error
* logging for sites which use a separate domain for static media, use this
* attribute. See CORS settings attributes for a more descriptive
* explanation of its valid arguments.
*
* @return static
*/
public function unsetCrossorigin(): static
{
unset($this->attributes()['crossorigin']);
return $this;
}
/**
* This attribute contains inline metadata that a user agent can use to
* verify that a fetched resource has been delivered free of unexpected
@ -170,7 +125,7 @@ class ScriptTag extends AbstractContentTag
* @param null|string|Stringable $integrity
* @return static
*/
public function setIntegrity(null|string|Stringable $integrity): static
public function setIntegrity(null|string|Stringable $integrity): self
{
if ($integrity) $this->attributes()['integrity'] = $integrity;
else $this->unsetIntegrity();
@ -186,7 +141,7 @@ class ScriptTag extends AbstractContentTag
*
* @return static
*/
public function unsetIntegrity(): static
public function unsetIntegrity(): self
{
unset($this->attributes()['integrity']);
return $this;
@ -201,7 +156,7 @@ class ScriptTag extends AbstractContentTag
* @param boolean $nomodule
* @return static
*/
public function setNomodule(bool $nomodule): static
public function setNomodule(bool $nomodule): self
{
if ($nomodule) $this->attributes()['nomodule'] = BooleanAttribute::true;
else unset($this->attributes()['nomodule']);
@ -247,7 +202,7 @@ class ScriptTag extends AbstractContentTag
* @param null|string|Stringable $nonce
* @return static
*/
public function setNonce(null|string|Stringable $nonce): static
public function setNonce(null|string|Stringable $nonce): self
{
if ($nonce) $this->attributes()['nonce'] = $nonce;
else $this->unsetNonce();
@ -264,7 +219,7 @@ class ScriptTag extends AbstractContentTag
*
* @return static
*/
public function unsetNonce(): static
public function unsetNonce(): self
{
unset($this->attributes()['nonce']);
return $this;
@ -274,21 +229,21 @@ class ScriptTag extends AbstractContentTag
* Indicates which referrer to send when fetching the script, or resources
* fetched by the script.
*
* @return null|ReferrerPolicy_script
* @return null|ReferrerPolicyValue
*/
public function referrerpolicy(): null|ReferrerPolicy_script
public function referrerpolicy(): null|ReferrerPolicyValue
{
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicy_script::class);
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicyValue::class);
}
/**
* Indicates which referrer to send when fetching the script, or resources
* fetched by the script.
*
* @param null|ReferrerPolicy_script $referrerpolicy
* @param null|ReferrerPolicyValue $referrerpolicy
* @return static
*/
public function setReferrerpolicy(null|ReferrerPolicy_script $referrerpolicy): static
public function setReferrerpolicy(null|ReferrerPolicyValue $referrerpolicy): self
{
if ($referrerpolicy) $this->attributes()['referrerpolicy'] = $referrerpolicy->value;
else $this->unsetReferrerpolicy();
@ -301,7 +256,7 @@ class ScriptTag extends AbstractContentTag
*
* @return static
*/
public function unsetReferrerpolicy(): static
public function unsetReferrerpolicy(): self
{
unset($this->attributes()['referrerpolicy']);
return $this;
@ -325,7 +280,7 @@ class ScriptTag extends AbstractContentTag
* @param null|string|Stringable $src
* @return static
*/
public function setSrc(null|string|Stringable $src): static
public function setSrc(null|string|Stringable $src): self
{
if ($src) $this->attributes()['src'] = $src;
else $this->unsetSrc();
@ -338,7 +293,7 @@ class ScriptTag extends AbstractContentTag
*
* @return static
*/
public function unsetSrc(): static
public function unsetSrc(): self
{
unset($this->attributes()['src']);
return $this;
@ -347,20 +302,20 @@ class ScriptTag extends AbstractContentTag
/**
* This attribute indicates the type of script represented.
*
* @return null|Type_script
* @return null|TypeValue
*/
public function type(): null|Type_script
public function type(): null|TypeValue
{
return $this->attributes()->asEnum('type', Type_script::class);
return $this->attributes()->asEnum('type', TypeValue::class);
}
/**
* This attribute indicates the type of script represented.
*
* @param null|Type_script $type
* @param null|TypeValue $type
* @return static
*/
public function setType(null|Type_script $type): static
public function setType(null|TypeValue $type): self
{
if ($type) $this->attributes()['type'] = $type->value;
else $this->unsetType();
@ -372,7 +327,7 @@ class ScriptTag extends AbstractContentTag
*
* @return static
*/
public function unsetType(): static
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\ScriptTag;
/**
* A string indicating which referrer to use when fetching the resource. These
@ -9,7 +9,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
*/
enum ReferrerPolicy_script: string
enum ReferrerPolicyValue: string
{
/**
* (default): Send a full URL when performing a same-origin request, only

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Tags\ScriptTag;
/**
* The type attribute of the <script> element indicates the type of script
@ -10,7 +10,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Descriptions by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type
*/
enum Type_script: string
enum TypeValue: string
{
/**
* Indicates that the script is a "classic script", containing JavaScript

View file

@ -37,7 +37,7 @@ class StyleTag extends AbstractContentTag
* @param null|string|Stringable $media
* @return static
*/
public function setMedia(null|string|Stringable $media): static
public function setMedia(null|string|Stringable $media): self
{
if ($media) $this->attributes()['media'] = $media;
else $this->unsetMedia();
@ -51,7 +51,7 @@ class StyleTag extends AbstractContentTag
*
* @return static
*/
public function unsetMedia(): static
public function unsetMedia(): self
{
unset($this->attributes()['media']);
return $this;
@ -85,7 +85,7 @@ class StyleTag extends AbstractContentTag
* @param null|string|Stringable $nonce
* @return static
*/
public function setNonce(null|string|Stringable $nonce): static
public function setNonce(null|string|Stringable $nonce): self
{
if ($nonce) $this->attributes()['nonce'] = $nonce;
else $this->unsetNonce();
@ -104,7 +104,7 @@ class StyleTag extends AbstractContentTag
*
* @return static
*/
public function unsetNonce(): static
public function unsetNonce(): self
{
unset($this->attributes()['nonce']);
return $this;

View file

@ -39,7 +39,7 @@ class BlockquoteTag extends AbstractContainerTag
* @param null|string|Stringable $cite
* @return static
*/
public function setCite(null|string|Stringable $cite): static
public function setCite(null|string|Stringable $cite): self
{
if ($cite) $this->attributes()['cite'] = $cite;
else $this->unsetCite();
@ -53,7 +53,7 @@ class BlockquoteTag extends AbstractContainerTag
*
* @return static
*/
public function unsetCite(): static
public function unsetCite(): self
{
unset($this->attributes()['cite']);
return $this;

View file

@ -40,7 +40,7 @@ class FigureTag extends AbstractGroupedTag
*
* @return static
*/
public function flipCaptionOrder(): static
public function flipCaptionOrder(): self
{
$this->children = array_reverse($this->children);
return $this;

View file

@ -2,7 +2,7 @@
namespace ByJoby\HTML\Html5\TextContentTags;
use ByJoby\HTML\Html5\Enums\Type_list;
use ByJoby\HTML\Html5\Enums\ListTypeValue;
use ByJoby\HTML\Tags\AbstractContainerTag;
/**
@ -22,20 +22,20 @@ class LiTag extends AbstractContainerTag
/**
* Gets the numbering type to be used if placed in an <OL> tag.
*
* @return null|Type_list
* @return null|ListTypeValue
*/
public function type(): null|Type_list
public function type(): null|ListTypeValue
{
return $this->attributes()->asEnum('type', Type_list::class);
return $this->attributes()->asEnum('type', ListTypeValue::class);
}
/**
* Sets the numbering type to be used if placed in an <OL> tag.
*
* @param null|Type_list $type
* @param null|ListTypeValue $type
* @return static
*/
public function setType(null|Type_list $type): static
public function setType(null|ListTypeValue $type): self
{
if ($type) $this->attributes()['type'] = $type->value;
else $this->unsetType();
@ -47,7 +47,7 @@ class LiTag extends AbstractContainerTag
*
* @return static
*/
public function unsetType(): static
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;

View file

@ -2,8 +2,8 @@
namespace ByJoby\HTML\Html5\TextContentTags;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use ByJoby\HTML\Html5\Enums\Type_list;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Enums\ListTypeValue;
use ByJoby\HTML\Tags\AbstractContainerTag;
/**
@ -24,7 +24,7 @@ class OlTag extends AbstractContainerTag
* @param boolean $reversed
* @return static
*/
public function setReversed(bool $reversed): static
public function setReversed(bool $reversed): self
{
if ($reversed) $this->attributes()['reversed'] = BooleanAttribute::true;
else unset($this->attributes()['reversed']);
@ -64,7 +64,7 @@ class OlTag extends AbstractContainerTag
* @param null|integer $start
* @return static
*/
public function setStart(null|int $start): static
public function setStart(null|int $start): self
{
if (is_null($start)) $this->unsetStart();
else $this->attributes()['start'] = $start;
@ -79,7 +79,7 @@ class OlTag extends AbstractContainerTag
*
* @return static
*/
public function unsetStart(): static
public function unsetStart(): self
{
unset($this->attributes()['start']);
return $this;
@ -91,11 +91,11 @@ class OlTag extends AbstractContainerTag
* The specified type is used for the entire list unless a different type
* attribute is used on an enclosed <li> element.
*
* @return null|Type_list
* @return null|ListTypeValue
*/
public function type(): null|Type_list
public function type(): null|ListTypeValue
{
return $this->attributes()->asEnum('type', Type_list::class);
return $this->attributes()->asEnum('type', ListTypeValue::class);
}
/**
@ -104,10 +104,10 @@ class OlTag extends AbstractContainerTag
* The specified type is used for the entire list unless a different type
* attribute is used on an enclosed <li> element.
*
* @param null|Type_list $type
* @param null|ListTypeValue $type
* @return static
*/
public function setType(null|Type_list $type): static
public function setType(null|ListTypeValue $type): self
{
if ($type) $this->attributes()['type'] = $type->value;
else $this->unsetType();
@ -122,7 +122,7 @@ class OlTag extends AbstractContainerTag
*
* @return static
*/
public function unsetType(): static
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;

View file

@ -0,0 +1,50 @@
<?php
namespace ByJoby\HTML\Html5\Traits;
use ByJoby\HTML\Html5\Traits\CrossoriginTrait\CrossOriginValue;
trait CrossOriginTrait {
/**
* This enumerated attribute indicates whether CORS must be used when
* fetching the resource. CORS-enabled images can be reused in the <canvas>
* element without being tainted. The allowed values are:
*
* @return null|CrossOriginValue
*/
public function crossorigin(): null|CrossOriginValue
{
return $this->attributes()->asEnum('crossorigin', CrossOriginValue::class);
}
/**
* This enumerated attribute indicates whether CORS must be used when
* fetching the resource. CORS-enabled images can be reused in the <canvas>
* element without being tainted. The allowed values are:
*
* @param null|CrossOriginValue $crossorigin
* @return static
*/
public function setCrossorigin(null|CrossOriginValue $crossorigin): self
{
if (!$crossorigin) {
$this->unsetCrossorigin();
} else {
$this->attributes()['crossorigin'] = $crossorigin->value;
}
return $this;
}
/**
* This enumerated attribute indicates whether CORS must be used when
* fetching the resource. CORS-enabled images can be reused in the <canvas>
* element without being tainted. The allowed values are:
*
* @return static
*/
public function unsetCrossorigin(): self
{
unset($this->attributes()['crossorigin']);
return $this;
}
}

View file

@ -1,8 +1,8 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Traits\CrossoriginTrait;
enum CrossOrigin: string
enum CrossOriginValue: string
{
/**
* A cross-origin request (i.e. with an Origin HTTP header) is performed,

View file

@ -0,0 +1,317 @@
<?php
namespace ByJoby\HTML\Html5\Traits;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Html5\Traits\HyperlinkTrait\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Traits\HyperlinkTrait\RelValue;
use Stringable;
/**
* Wraps up the common attribute helpers of hyperlink-ish tags, so that their
* code can be centralized. For example, this allows less code duplication
* between <a> and <area> tags.
*/
trait HyperlinkTrait {
/**
* Causes the browser to treat the linked URL as a download. Can be used
* with or without a filename value.
*
* @return null|string|Stringable|BooleanAttribute::true
*/
public function download(): null|string|Stringable|BooleanAttribute
{
if ($this->attributes()['download'] === BooleanAttribute::true) return BooleanAttribute::true;
else return $this->attributes()->asString('download');
}
/**
* Causes the browser to treat the linked URL as a download. Can be used
* with or without a filename value.
*
* @param null|string|Stringable|BooleanAttribute $download
* @return static
*/
public function setDownload(null|string|Stringable|BooleanAttribute $download): self
{
if ($download === BooleanAttribute::true) $this->attributes()['download'] = BooleanAttribute::true;
elseif ($download === BooleanAttribute::false) $this->unsetDownload();
elseif ($download) $this->attributes()['download'] = $download;
else $this->unsetDownload();
return $this;
}
/**
* Causes the browser to treat the linked URL as a download. Can be used
* with or without a filename value.
*
* @return static
*/
public function unsetDownload(): self
{
unset($this->attributes()['download']);
return $this;
}
/**
* The URL that the hyperlink points to. Links are not restricted to
* HTTP-based URLs they can use any URL scheme supported by browsers
*
* @return null|string|Stringable
*/
public function href(): null|string|Stringable
{
return $this->attributes()->asString('href');
}
/**
* The URL that the hyperlink points to. Links are not restricted to
* HTTP-based URLs they can use any URL scheme supported by browsers
*
* @param null|string|Stringable $href
* @return static
*/
public function setHref(null|string|Stringable $href): self
{
if ($href) $this->attributes()['href'] = $href;
else $this->unsetHref();
return $this;
}
/**
* The URL that the hyperlink points to. Links are not restricted to
* HTTP-based URLs they can use any URL scheme supported by browsers
*
* @return static
*/
public function unsetHref(): self
{
$this->unsetHrefLang();
unset($this->attributes()['href']);
return $this;
}
/**
* Hints at the human language of the linked URL. No built-in functionality.
* Allowed values are the same as the global lang attribute.
*
* @return null|string|Stringable
*/
public function hreflang(): null|string|Stringable
{
return $this->attributes()->asString('hreflang');
}
/**
* Hints at the human language of the linked URL. No built-in functionality.
* Allowed values are the same as the global lang attribute.
*
* @param null|string|Stringable $hreflang
* @return static
*/
public function setHreflang(null|string|Stringable $hreflang): self
{
if ($hreflang) $this->attributes()['hreflang'] = $hreflang;
else $this->unsetHreflang();
return $this;
}
/**
* Hints at the human language of the linked URL. No built-in functionality.
* Allowed values are the same as the global lang attribute.
*
* @return static
*/
public function unsetHreflang(): self
{
unset($this->attributes()['hreflang']);
return $this;
}
/**
* A space-separated list of URLs. When the link is followed, the browser
* will send POST requests with the body PING to the URLs. Typically for
* tracking.
*
* @return null|string|Stringable
*/
public function ping(): null|string|Stringable
{
return $this->attributes()->asString('ping');
}
/**
* A space-separated list of URLs. When the link is followed, the browser
* will send POST requests with the body PING to the URLs. Typically for
* tracking.
*
* @param null|string|Stringable $ping
* @return static
*/
public function setPing(null|string|Stringable $ping): self
{
if ($ping) $this->attributes()['ping'] = $ping;
else $this->unsetPing();
return $this;
}
/**
* A space-separated list of URLs. When the link is followed, the browser
* will send POST requests with the body PING to the URLs. Typically for
* tracking.
*
* @return static
*/
public function unsetPing(): self
{
unset($this->attributes()['ping']);
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return null|ReferrerPolicyValue
*/
public function referrerpolicy(): null|ReferrerPolicyValue
{
return $this->attributes()->asEnum('referrerpolicy', ReferrerPolicyValue::class);
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @param null|ReferrerPolicyValue $referrerpolicy
* @return static
*/
public function setReferrerpolicy(null|ReferrerPolicyValue $referrerpolicy): self
{
if ($referrerpolicy) $this->attributes()['referrerpolicy'] = $referrerpolicy->value;
else $this->unsetReferrerpolicy();
return $this;
}
/**
* An enum indicating which referrer to use when fetching the resource.
*
* @return static
*/
public function unsetReferrerpolicy(): self
{
unset($this->attributes()['referrerpolicy']);
return $this;
}
/**
* The relationship of the linked URL as space-separated link types.
*
* @return RelValue[]
*/
public function rel(): array
{
return $this->attributes()->asEnumArray('rel', RelValue::class, ' ');
}
/**
* The relationship of the linked URL as space-separated link types.
*
* @param null|RelValue|array<int|string,RelValue> $rel
* @return static
*/
public function setRel(null|RelValue|array $rel): self
{
if ($rel) $this->attributes()->setEnumArray('rel', $rel, RelValue::class, ' ');
else $this->unsetRel();
return $this;
}
/**
* The relationship of the linked URL as space-separated link types.
*
* @return static
*/
public function unsetRel(): self
{
unset($this->attributes()['rel']);
return $this;
}
/**
* Where to display the linked URL, as the name for a browsing context (a
* tab, window, or <iframe>).
*
* @return null|string|Stringable|BrowsingContext
*/
public function target(): null|string|Stringable|BrowsingContext
{
return $this->attributes()->asEnum('target', BrowsingContext::class)
?? $this->attributes()->asString('target');
}
/**
* Where to display the linked URL, as the name for a browsing context (a
* tab, window, or <iframe>).
*
* @param null|string|Stringable|BrowsingContext $target
* @return static
*/
public function setTarget(null|string|Stringable|BrowsingContext $target): self
{
if (!$target) {
$this->unsetTarget();
} elseif ($target instanceof BrowsingContext) {
$this->attributes()['target'] = $target->value;
} else {
$this->attributes()['target'] = $target;
}
return $this;
}
/**
* Where to display the linked URL, as the name for a browsing context (a
* tab, window, or <iframe>).
*
* @return static
*/
public function unsetTarget(): self
{
unset($this->attributes()['target']);
return $this;
}
/**
* Hints at the linked URL's format with a MIME type. No built-in
* functionality.
*
* @return null|string|Stringable
*/
public function type(): null|string|Stringable
{
return $this->attributes()->asString('type');
}
/**
* Hints at the linked URL's format with a MIME type. No built-in
* functionality.
*
* @param null|string|Stringable $type
* @return static
*/
public function setType(null|string|Stringable $type): self
{
if ($type) $this->attributes()['type'] = $type;
else $this->unsetType();
return $this;
}
/**
* Hints at the linked URL's format with a MIME type. No built-in
* functionality.
*
* @return static
*/
public function unsetType(): self
{
unset($this->attributes()['type']);
return $this;
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Traits\HyperlinkTrait;
/**
* How much of the referrer to send when following the link.
@ -8,7 +8,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
*/
enum ReferrerPolicy_a: string
enum ReferrerPolicyValue: string
{
/**
* DEFAULT: Send a full URL when performing a same-origin request, only send

View file

@ -1,6 +1,6 @@
<?php
namespace ByJoby\HTML\Html5\Enums;
namespace ByJoby\HTML\Html5\Traits\HyperlinkTrait;
/**
* The rel attribute defines the relationship between a linked resource and the
@ -9,7 +9,7 @@ namespace ByJoby\HTML\Html5\Enums;
* Description by Mozilla Contributors licensed under CC-BY-SA 2.5
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel
*/
enum Rel_a: string
enum RelValue: string
{
/**
* Alternate representations of the current document.

View file

@ -12,7 +12,7 @@ interface NodeInterface extends Stringable
public function setParent(
null|ContainerInterface $parent
): static;
): self;
public function parentTag(): null|TagInterface;
@ -25,5 +25,5 @@ interface NodeInterface extends Stringable
*/
public function parentOfType(string $class): mixed;
public function detachCopy(): static;
public function detachCopy(): self;
}

View file

@ -18,7 +18,7 @@ class CData implements CDataInterface
return $this->value;
}
public function setValue(string|Stringable $value): static
public function setValue(string|Stringable $value): self
{
$this->value = $value;
return $this;

View file

@ -9,5 +9,5 @@ interface CDataInterface extends NodeInterface
{
public function __construct(Stringable|string $value);
public function value(): string;
public function setValue(string|Stringable $value): static;
public function setValue(string|Stringable $value): self;
}

View file

@ -18,7 +18,7 @@ class Comment implements CommentInterface
return $this->value;
}
public function setValue(string|Stringable $value): static
public function setValue(string|Stringable $value): self
{
$this->value = $value;
return $this;

View file

@ -9,5 +9,5 @@ interface CommentInterface extends NodeInterface
{
public function __construct(Stringable|string $value);
public function value(): string;
public function setValue(string|Stringable $value): static;
public function setValue(string|Stringable $value): self;
}

View file

@ -18,7 +18,7 @@ class Text implements TextInterface
return $this->value;
}
public function setValue(string|Stringable $value): static
public function setValue(string|Stringable $value): self
{
$this->value = $value;
return $this;

View file

@ -9,5 +9,5 @@ interface TextInterface extends NodeInterface
{
public function __construct(Stringable|string $value);
public function value(): string;
public function setValue(string|Stringable $value): static;
public function setValue(string|Stringable $value): self;
}

View file

@ -18,7 +18,7 @@ class UnsanitizedText implements TextInterface
return $this->value;
}
public function setValue(string|Stringable $value): static
public function setValue(string|Stringable $value): self
{
$this->value = $value;
return $this;

View file

@ -16,7 +16,7 @@ abstract class AbstractContentTag extends AbstractTag implements ContentTagInter
return trim($this->content, "\t\n\r\0x0B");
}
public function setContent(string|Stringable $content): static
public function setContent(string|Stringable $content): self
{
$this->content = $content;
return $this;

View file

@ -14,5 +14,5 @@ use Stringable;
interface ContentTagInterface extends TagInterface
{
public function content(): string|Stringable;
public function setContent(string|Stringable $content): static;
public function setContent(string|Stringable $content): self;
}

View file

@ -18,7 +18,7 @@ interface TagInterface extends NodeInterface
{
public function tag(): string;
public function id(): null|string;
public function setID(null|string|Stringable $id): static;
public function setID(null|string|Stringable $id): self;
public function classes(): Classes;
public function attributes(): Attributes;
public function styles(): Styles;

View file

@ -33,7 +33,7 @@ trait ContainerTrait
NodeInterface|Stringable|string $child,
bool $prepend = false,
bool $skip_sanitize = false
): static {
): self {
$child = $this->prepareChildToAdd($child, $skip_sanitize);
if ($prepend) {
array_unshift($this->children, $child);
@ -45,7 +45,7 @@ trait ContainerTrait
public function removeChild(
NodeInterface|Stringable|string $child
): static {
): self {
$this->children = array_filter(
$this->children,
function (NodeInterface $e) use ($child) {
@ -67,7 +67,7 @@ trait ContainerTrait
NodeInterface|Stringable|string $new_child,
NodeInterface|Stringable|string $before_child,
bool $skip_sanitize = false
): static {
): self {
$i = $this->indexOfChild($before_child);
if ($i === null) {
throw new Exception('Reference child not found in this container');
@ -81,7 +81,7 @@ trait ContainerTrait
NodeInterface|Stringable|string $new_child,
NodeInterface|Stringable|string $after_child,
bool $skip_sanitize = false
): static {
): self {
$i = $this->indexOfChild($after_child);
if ($i === null) {
throw new Exception('Reference child not found in this container');

View file

@ -58,7 +58,7 @@ trait GroupedContainerTrait
NodeInterface|Stringable|string $child,
bool $prepend = false,
bool $skip_sanitize = false
): static {
): self {
foreach ($this->groups() as $group) {
if ($group->willAccept($child)) {
$group->addChild($child, $prepend, $skip_sanitize);
@ -70,7 +70,7 @@ trait GroupedContainerTrait
public function removeChild(
NodeInterface|Stringable|string $child
): static {
): self {
foreach ($this->groups() as $group) {
$group->removeChild($child);
}
@ -81,7 +81,7 @@ trait GroupedContainerTrait
NodeInterface|Stringable|string $new_child,
NodeInterface|Stringable|string $before_child,
bool $skip_sanitize = false
): static {
): self {
foreach ($this->groups() as $group) {
if ($group->willAccept($new_child) && $group->contains($before_child)) {
$group->addChildBefore($new_child, $before_child, $skip_sanitize);
@ -95,7 +95,7 @@ trait GroupedContainerTrait
NodeInterface|Stringable|string $new_child,
NodeInterface|Stringable|string $after_child,
bool $skip_sanitize = false
): static {
): self {
foreach ($this->groups() as $group) {
if ($group->willAccept($new_child) && $group->contains($after_child)) {
$group->addChildAfter($new_child, $after_child, $skip_sanitize);

View file

@ -20,7 +20,7 @@ trait NodeTrait
return $this->parent;
}
public function setParent(null|ContainerInterface $parent): static
public function setParent(null|ContainerInterface $parent): self
{
$this->parent = $parent;
return $this;
@ -47,7 +47,7 @@ trait NodeTrait
}
}
public function detachCopy(): static
public function detachCopy(): self
{
static $copier;
$copier = $copier ?? new DeepCopy();

View file

@ -3,9 +3,9 @@
namespace ByJoby\HTML\Traits;
use ByJoby\HTML\Helpers\Attributes;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Helpers\Classes;
use ByJoby\HTML\Helpers\Styles;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use Exception;
use Stringable;
@ -34,7 +34,7 @@ trait TagTrait
return $this->id;
}
public function setID(null|string|Stringable $id): static
public function setID(null|string|Stringable $id): self
{
if ($id) {
$this->id = static::sanitizeID($id);

View file

@ -2,19 +2,19 @@
namespace ByJoby\HTML\Html5\Tags;
use ByJoby\HTML\Html5\Enums\As_link;
use ByJoby\HTML\Html5\Enums\CrossOrigin;
use ByJoby\HTML\Html5\Enums\ReferrerPolicy_link;
use ByJoby\HTML\Html5\Enums\Rel_link;
use ByJoby\HTML\Html5\Tags\LinkTag\AsValue;
use ByJoby\HTML\Html5\Tags\LinkTag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Tags\LinkTag\RelValue;
use ByJoby\HTML\Html5\Exceptions\InvalidArgumentsException;
use ByJoby\HTML\Html5\Traits\CrossoriginTrait\CrossOriginValue;
class LinkTagTest extends TagTestCase
{
public function testAttributeHelpers(): void
{
$this->assertAttributeHelperMethods('referrerpolicy', LinkTag::class, ReferrerPolicy_link::origin, 'origin');
$this->assertAttributeHelperMethods('crossorigin', LinkTag::class, CrossOrigin::anonymous, 'anonymous');
$this->assertAttributeHelperMethods('crossorigin', LinkTag::class, CrossOrigin::useCredentials, 'use-credentials');
$this->assertAttributeHelperMethods('referrerpolicy', LinkTag::class, ReferrerPolicyValue::origin, 'origin');
$this->assertAttributeHelperMethods('crossorigin', LinkTag::class, CrossOriginValue::anonymous, 'anonymous');
$this->assertAttributeHelperMethods('crossorigin', LinkTag::class, CrossOriginValue::useCredentials, 'use-credentials');
$this->assertAttributeHelperMethods('href', LinkTag::class);
$this->assertAttributeHelperMethods('hreflang', LinkTag::class);
$this->assertAttributeHelperMethods('imagesizes', LinkTag::class);
@ -28,10 +28,10 @@ class LinkTagTest extends TagTestCase
{
$tag = new LinkTag();
// set as to something that can be set alone
$tag->setAs(As_link::document);
$tag->setAs(AsValue::document);
$this->assertEquals('document', $tag->attributes()->asString('as'));
// set as to fetch so crossorigin is required
$tag->setAs(As_link::fetch, CrossOrigin::anonymous);
$tag->setAs(AsValue::fetch, CrossOriginValue::anonymous);
$this->assertEquals('fetch', $tag->attributes()->asString('as'));
$this->assertEquals('anonymous', $tag->attributes()->asString('crossorigin'));
}
@ -40,13 +40,13 @@ class LinkTagTest extends TagTestCase
{
$tag = new LinkTag();
// set rel as a single attribute
$tag->setRel(Rel_link::prefetch);
$tag->setRel(RelValue::prefetch);
$this->assertEquals('prefetch', $tag->attributes()->asString('rel'));
// set rel as an array of attributes
$tag->setRel([Rel_link::prefetch, Rel_link::next]);
$tag->setRel([RelValue::prefetch, RelValue::next]);
$this->assertEquals('prefetch next', $tag->attributes()->asString('rel'));
// set deeper values
$tag->setRel(Rel_link::preload, As_link::fetch, CrossOrigin::anonymous);
$tag->setRel(RelValue::preload, AsValue::fetch, CrossOriginValue::anonymous);
$this->assertEquals('preload', $tag->attributes()->asString('rel'));
$this->assertEquals('fetch', $tag->attributes()->asString('as'));
$this->assertEquals('anonymous', $tag->attributes()->asString('crossorigin'));
@ -56,13 +56,13 @@ class LinkTagTest extends TagTestCase
{
$this->expectException(InvalidArgumentsException::class);
$tag = new LinkTag();
$tag->setRel(Rel_link::preload);
$tag->setRel(RelValue::preload);
}
public function testRelMIssingCrossorigin(): void
{
$this->expectException(InvalidArgumentsException::class);
$tag = new LinkTag();
$tag->setRel(Rel_link::preload, As_link::fetch);
$tag->setRel(RelValue::preload, AsValue::fetch);
}
}

View file

@ -2,8 +2,8 @@
namespace ByJoby\HTML\Html5\Tags;
use ByJoby\HTML\Html5\Enums\HttpEquiv_meta;
use ByJoby\HTML\Html5\Enums\Name_meta;
use ByJoby\HTML\Html5\Tags\MetaTag\HttpEquivValue;
use ByJoby\HTML\Html5\Tags\MetaTag\NameValue;
class MetaTagTest extends TagTestCase
{
@ -19,16 +19,16 @@ class MetaTagTest extends TagTestCase
public function testName(): void
{
$tag = new MetaTag();
$tag->setNameAndContent(Name_meta::application, 'test');
$this->assertEquals(Name_meta::application->value, $tag->attributes()['name']);
$tag->setNameAndContent(NameValue::application, 'test');
$this->assertEquals(NameValue::application->value, $tag->attributes()['name']);
$this->assertEquals('test', $tag->attributes()['content']);
}
public function testHttpEquiv(): void
{
$tag = new MetaTag();
$tag->setHttpEquivAndContent(HttpEquiv_meta::mime, 'text/plain');
$this->assertEquals(HttpEquiv_meta::mime->value, $tag->attributes()['http-equiv']);
$tag->setHttpEquivAndContent(HttpEquivValue::mime, 'text/plain');
$this->assertEquals(HttpEquivValue::mime->value, $tag->attributes()['http-equiv']);
$this->assertEquals('text/plain', $tag->attributes()['content']);
}
@ -36,8 +36,8 @@ class MetaTagTest extends TagTestCase
{
$tag = new MetaTag();
$tag->setCharset(true);
$tag->setHttpEquivAndContent(HttpEquiv_meta::mime, 'text/plain');
$tag->setNameAndContent(Name_meta::application, 'test');
$tag->setHttpEquivAndContent(HttpEquivValue::mime, 'text/plain');
$tag->setNameAndContent(NameValue::application, 'test');
$this->assertNull($tag->attributes()['charset']);
$this->assertNull($tag->attributes()['http-equiv']);
}
@ -46,8 +46,8 @@ class MetaTagTest extends TagTestCase
{
$tag = new MetaTag();
$tag->setCharset(true);
$tag->setNameAndContent(Name_meta::application, 'test');
$tag->setHttpEquivAndContent(HttpEquiv_meta::mime, 'text/plain');
$tag->setNameAndContent(NameValue::application, 'test');
$tag->setHttpEquivAndContent(HttpEquivValue::mime, 'text/plain');
$this->assertNull($tag->attributes()['charset']);
$this->assertNull($tag->attributes()['name']);
}
@ -55,8 +55,8 @@ class MetaTagTest extends TagTestCase
public function testCharsetOverrides(): void
{
$tag = new MetaTag();
$tag->setHttpEquivAndContent(HttpEquiv_meta::mime, 'text/plain');
$tag->setNameAndContent(Name_meta::application, 'test');
$tag->setHttpEquivAndContent(HttpEquivValue::mime, 'text/plain');
$tag->setNameAndContent(NameValue::application, 'test');
$tag->setCharset(true);
$this->assertNull($tag->attributes()['name']);
$this->assertNull($tag->attributes()['http-equiv']);

View file

@ -2,21 +2,21 @@
namespace ByJoby\HTML\Html5\Tags;
use ByJoby\HTML\Html5\Enums\CrossOrigin;
use ByJoby\HTML\Html5\Enums\ReferrerPolicy_script;
use ByJoby\HTML\Html5\Enums\Type_script;
use ByJoby\HTML\Html5\Tags\ScriptTag\ReferrerPolicyValue;
use ByJoby\HTML\Html5\Tags\ScriptTag\TypeValue;
use ByJoby\HTML\Html5\Traits\CrossoriginTrait\CrossOriginValue;
class ScriptTagTest extends TagTestCase
{
public function testAttributeHelpers(): void
{
$this->assertAttributeHelperMethods('crossorigin', ScriptTag::class, CrossOrigin::useCredentials, CrossOrigin::useCredentials->value);
$this->assertAttributeHelperMethods('crossorigin', ScriptTag::class, CrossOriginValue::useCredentials, CrossOriginValue::useCredentials->value);
$this->assertAttributeHelperMethods('integrity', ScriptTag::class);
$this->assertAttributeHelperMethods('integrity', ScriptTag::class);
$this->assertAttributeHelperMethods('nonce', ScriptTag::class);
$this->assertAttributeHelperMethods('referrerpolicy', ScriptTag::class, ReferrerPolicy_script::noReferrer, ReferrerPolicy_script::noReferrer->value);
$this->assertAttributeHelperMethods('referrerpolicy', ScriptTag::class, ReferrerPolicyValue::noReferrer, ReferrerPolicyValue::noReferrer->value);
$this->assertAttributeHelperMethods('src', ScriptTag::class);
$this->assertAttributeHelperMethods('type', ScriptTag::class, Type_script::module, Type_script::module->value);
$this->assertAttributeHelperMethods('type', ScriptTag::class, TypeValue::module, TypeValue::module->value);
$this->assertBooleanAttributeHelperMethods('async', ScriptTag::class);
$this->assertBooleanAttributeHelperMethods('defer', ScriptTag::class);
$this->assertBooleanAttributeHelperMethods('nomodule', ScriptTag::class);

View file

@ -2,18 +2,18 @@
namespace ByJoby\HTML\Html5\TextContentTags;
use ByJoby\HTML\Html5\Enums\Type_list;
use ByJoby\HTML\Html5\Enums\ListTypeValue;
use ByJoby\HTML\Html5\Tags\BaseTagTest;
class LiTagTest extends BaseTagTest
{
public function testAttributeHelpers(): void
{
$this->assertAttributeHelperMethods('type', LiTag::class, Type_list::letterLower, 'a');
$this->assertAttributeHelperMethods('type', LiTag::class, Type_list::letterUpper, 'A');
$this->assertAttributeHelperMethods('type', LiTag::class, Type_list::romanLower, 'i');
$this->assertAttributeHelperMethods('type', LiTag::class, Type_list::romanUpper, 'I');
$this->assertAttributeHelperMethods('type', LiTag::class, Type_list::number, '1');
$this->assertAttributeHelperMethods('type', LiTag::class, ListTypeValue::letterLower, 'a');
$this->assertAttributeHelperMethods('type', LiTag::class, ListTypeValue::letterUpper, 'A');
$this->assertAttributeHelperMethods('type', LiTag::class, ListTypeValue::romanLower, 'i');
$this->assertAttributeHelperMethods('type', LiTag::class, ListTypeValue::romanUpper, 'I');
$this->assertAttributeHelperMethods('type', LiTag::class, ListTypeValue::number, '1');
}
public function testInvalidType(): void

View file

@ -2,7 +2,7 @@
namespace ByJoby\HTML\Html5\TextContentTags;
use ByJoby\HTML\Html5\Enums\Type_list;
use ByJoby\HTML\Html5\Enums\ListTypeValue;
use ByJoby\HTML\Html5\Tags\BaseTagTest;
class OlTagTest extends BaseTagTest
@ -12,11 +12,11 @@ class OlTagTest extends BaseTagTest
$this->assertBooleanAttributeHelperMethods('reversed', OlTag::class);
$this->assertAttributeHelperMethods('start', OlTag::class, 1, '1');
$this->assertAttributeHelperMethods('start', OlTag::class, 0, '0');
$this->assertAttributeHelperMethods('type', OlTag::class, Type_list::letterLower, 'a');
$this->assertAttributeHelperMethods('type', OlTag::class, Type_list::letterUpper, 'A');
$this->assertAttributeHelperMethods('type', OlTag::class, Type_list::romanLower, 'i');
$this->assertAttributeHelperMethods('type', OlTag::class, Type_list::romanUpper, 'I');
$this->assertAttributeHelperMethods('type', OlTag::class, Type_list::number, '1');
$this->assertAttributeHelperMethods('type', OlTag::class, ListTypeValue::letterLower, 'a');
$this->assertAttributeHelperMethods('type', OlTag::class, ListTypeValue::letterUpper, 'A');
$this->assertAttributeHelperMethods('type', OlTag::class, ListTypeValue::romanLower, 'i');
$this->assertAttributeHelperMethods('type', OlTag::class, ListTypeValue::romanUpper, 'I');
$this->assertAttributeHelperMethods('type', OlTag::class, ListTypeValue::number, '1');
}
public function testInvalidType(): void

View file

@ -2,7 +2,7 @@
namespace ByJoby\HTML\Tags;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Nodes\Text;
use ByJoby\HTML\Nodes\UnsanitizedText;
use PHPUnit\Framework\TestCase;

View file

@ -3,8 +3,8 @@
namespace ByJoby\HTML\Tags;
use ByJoby\HTML\Helpers\Attributes;
use ByJoby\HTML\Helpers\BooleanAttribute;
use ByJoby\HTML\Helpers\Classes;
use ByJoby\HTML\Html5\Enums\BooleanAttribute;
use PHPUnit\Framework\TestCase;
class AbstractTagTest extends TestCase