modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									18b05b7ed7
								
							
						
					
					
						commit
						b82a74418d
					
				@ -3,6 +3,7 @@ namespace nur;
 | 
			
		||||
 | 
			
		||||
use nur\b\ui\IContent;
 | 
			
		||||
use nur\b\ui\IPrintable;
 | 
			
		||||
use nur\sery\php\content\c;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class co: affichage générique de données formatées avec {@link c}
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ namespace nur\ref;
 | 
			
		||||
use nur\data\types\Metadata;
 | 
			
		||||
use nur\md;
 | 
			
		||||
use nur\sery\os\file\file;
 | 
			
		||||
use nur\sery\php\content\c;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class ref_type: référence des types utilisables dans les schémas
 | 
			
		||||
@ -102,7 +103,7 @@ class ref_type {
 | 
			
		||||
  /** comme {@link KEY} mais nullable */
 | 
			
		||||
  const NKEY = "?".self::KEY;
 | 
			
		||||
 | 
			
		||||
  /** comme {@link CONTENT} mais nullable */
 | 
			
		||||
  /** comme {@link c} mais nullable */
 | 
			
		||||
  const NCONTENT = "?".self::CONTENT;
 | 
			
		||||
 | 
			
		||||
  /** comme {@link \nur\sery\FILE} mais nullable */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								src/php/content/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/php/content/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
# nulib\php\content
 | 
			
		||||
 | 
			
		||||
un contenu est une liste de valeurs, avec une syntaxe pour que certains éléments
 | 
			
		||||
soient dynamiquement calculés.
 | 
			
		||||
 | 
			
		||||
le contenu final est résolu selon les règles suivantes:
 | 
			
		||||
- Si le contenu n'est pas un tableau:
 | 
			
		||||
  - une chaine est quotée avec `htmlspecialchars()`
 | 
			
		||||
  - un scalaire ou une instance d'objet sont pris tels quels
 | 
			
		||||
- Sinon, le contenu doit être un tableau, séquentiel ou associatif, ça n'a pas
 | 
			
		||||
  d'incidence
 | 
			
		||||
  - les éléments scalaires ou instance d'objets sont pris tels quels
 | 
			
		||||
  - les tableaux représentent un traitement dynamique: appel de fonction,
 | 
			
		||||
    instanciation, etc.
 | 
			
		||||
 | 
			
		||||
Les syntaxes possibles sont:
 | 
			
		||||
 | 
			
		||||
`[[], $args...]`
 | 
			
		||||
: merge littéral: les valeurs $args... sont insérées dans le
 | 
			
		||||
  flux du contenu sans modification. c'est la seule façon d'insérer un tableau
 | 
			
		||||
  dans la liste des valeurs
 | 
			
		||||
 | 
			
		||||
`["class_or_function", $args...]`
 | 
			
		||||
`[["class_or_function"], $args...]`
 | 
			
		||||
: instantiation ou appel de fonction
 | 
			
		||||
 | 
			
		||||
`["->method", $args...]`
 | 
			
		||||
`[["->method"], $args...]`
 | 
			
		||||
`[[null, "method"], $args...]`
 | 
			
		||||
: appel de méthode sur l'objet contexte spécifié lors de la résolution du contenu
 | 
			
		||||
 | 
			
		||||
`[[$object, "method"], $args...]`
 | 
			
		||||
: appel de méthode sur l'objet spécifié 
 | 
			
		||||
 | 
			
		||||
`[["class", "method"], $args...]`
 | 
			
		||||
: appel de méthode statique de la classe spécifiée
 | 
			
		||||
 | 
			
		||||
Le fait de transformer un contenu en une liste de valeurs statiques s'appelle
 | 
			
		||||
la résolution. la résolution se fait par rapport à un objet contexte, qui est
 | 
			
		||||
utilisé lors des appels de méthodes.
 | 
			
		||||
 | 
			
		||||
## Affichage d'un contenu
 | 
			
		||||
 | 
			
		||||
Deux interfaces sont utilisées pour modéliser un élément de contenu à afficher:
 | 
			
		||||
- IContent: objet capable de produire du contenu
 | 
			
		||||
- IPrintable: objet capable d'afficher un contenu
 | 
			
		||||
 | 
			
		||||
Tous les autres éléments de contenus sont transformés en string avant affichage.
 | 
			
		||||
Un système de formatters permet de définir des fonctions ou méthodes à utiliser
 | 
			
		||||
pour formatter des objets de certains types.
 | 
			
		||||
 | 
			
		||||
Lors de l'affichage du contenu, deux éléments contigûs $a et $b sont affichés
 | 
			
		||||
séparés par un espace sauf si:
 | 
			
		||||
- $a se termine par `[> ]` OU
 | 
			
		||||
- $b commence par `[< ]`
 | 
			
		||||
- $a et $b sont dans une section littérale e.g `[[], $a, $b]`
 | 
			
		||||
 | 
			
		||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
			
		||||
							
								
								
									
										163
									
								
								src/php/content/c.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								src/php/content/c.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,163 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\php\content;
 | 
			
		||||
 | 
			
		||||
use nur\sery\cl;
 | 
			
		||||
use nur\sery\php\func;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class c: classe outil pour gérer du contenu
 | 
			
		||||
 */
 | 
			
		||||
class c {
 | 
			
		||||
  /** s'assure que $c est un contenu. quoter $c si c'est une chaine */
 | 
			
		||||
  static final function q($content): iterable {
 | 
			
		||||
    if (is_string($content)) return [htmlspecialchars($content)];
 | 
			
		||||
    elseif (is_iterable($content)) return $content;
 | 
			
		||||
    elseif ($content === null || $content === false) return [];
 | 
			
		||||
    else return [$content];
 | 
			
		||||
  }
 | 
			
		||||
  const q = [self::class, "q"];
 | 
			
		||||
 | 
			
		||||
  /** s'assure que $c est un contenu. ne jamais quoter la valeur */
 | 
			
		||||
  static final function nq($content): iterable {
 | 
			
		||||
    if (is_iterable($content)) return $content;
 | 
			
		||||
    elseif ($content === null || $content === false) return [];
 | 
			
		||||
    else return [$content];
 | 
			
		||||
  }
 | 
			
		||||
  const nq = [self::class, "nq"];
 | 
			
		||||
 | 
			
		||||
  /** résoudre le contenu, et retourner la liste des valeurs */
 | 
			
		||||
  static final function resolve($content, $object_or_class=null, bool $quote=true, ?array &$dest=null): array {
 | 
			
		||||
    if ($dest === null) $dest = [];
 | 
			
		||||
    $content = $quote? self::q($content): self::nq($content);
 | 
			
		||||
    $index = 0;
 | 
			
		||||
    foreach ($content as $key => $value) {
 | 
			
		||||
      if ($key === $index) {
 | 
			
		||||
        $index++;
 | 
			
		||||
        $seq = true;
 | 
			
		||||
      } else {
 | 
			
		||||
        $seq = false;
 | 
			
		||||
      }
 | 
			
		||||
      if (is_array($value)) {
 | 
			
		||||
        # contenu dynamique
 | 
			
		||||
        if (count($value) == 0) continue;
 | 
			
		||||
        $func = cl::first($value);
 | 
			
		||||
        $args = array_slice($value, 1);
 | 
			
		||||
        if ($func === []) {
 | 
			
		||||
          # merge statique
 | 
			
		||||
          $sindex = 0;
 | 
			
		||||
          foreach ($args as $skey => $arg) {
 | 
			
		||||
            if ($skey === $sindex) {
 | 
			
		||||
              $sindex++;
 | 
			
		||||
              if ($seq) {
 | 
			
		||||
                $dest[] = $arg;
 | 
			
		||||
              } else {
 | 
			
		||||
                # la première sous-clé séquentielle est ajoutée avec la clé du
 | 
			
		||||
                # merge statique
 | 
			
		||||
                $dest[$key] = $arg;
 | 
			
		||||
                $seq = true;
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              $dest[$skey] = $arg;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          continue;
 | 
			
		||||
        } else {
 | 
			
		||||
          # chaque argument est aussi un contenu
 | 
			
		||||
          foreach ($args as &$arg) {
 | 
			
		||||
            $array = is_array($arg);
 | 
			
		||||
            $arg = self::resolve($arg, $object_or_class, false);
 | 
			
		||||
            if (!$array) $arg = $arg[0];
 | 
			
		||||
          }; unset($arg);
 | 
			
		||||
          if (func::is_static($func)) {
 | 
			
		||||
            func::ensure_func($func, $object_or_class, $args);
 | 
			
		||||
            $value = func::call($func, ...$args);
 | 
			
		||||
          } elseif (func::is_class($func)) {
 | 
			
		||||
            func::fix_class_args($func, $args);
 | 
			
		||||
            $value = func::cons($func, ...$args);
 | 
			
		||||
          } else {
 | 
			
		||||
            func::ensure_func($func, $object_or_class, $args);
 | 
			
		||||
            $value = func::call($func, ...$args);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if ($seq) $dest[] = $value;
 | 
			
		||||
      else $dest[$key] = $value;
 | 
			
		||||
    }
 | 
			
		||||
    return $dest;
 | 
			
		||||
  }
 | 
			
		||||
  const resolve = [self::class, "resolve"];
 | 
			
		||||
 | 
			
		||||
  private static final function wend(?string $value): bool {
 | 
			
		||||
    return $value !== null && preg_match('/(\w|\w\.)$/', $value);
 | 
			
		||||
  }
 | 
			
		||||
  private static final function startw(?string $value): bool {
 | 
			
		||||
    return $value !== null && preg_match('/^\w/', $value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static final function to_values($content, ?array &$values=null): void {
 | 
			
		||||
    $pvalue = cl::last($values);
 | 
			
		||||
    $wend = self::wend($pvalue);
 | 
			
		||||
    foreach ($content as $value) {
 | 
			
		||||
      if ($value === null || $value === false) {
 | 
			
		||||
        continue;
 | 
			
		||||
      } elseif ($value instanceof IContent) {
 | 
			
		||||
        self::to_values($value->getContent(), $values);
 | 
			
		||||
        continue;
 | 
			
		||||
      } elseif ($value instanceof IPrintable) {
 | 
			
		||||
        ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
 | 
			
		||||
        $value->print();
 | 
			
		||||
        $value = ob_get_clean();
 | 
			
		||||
      } else {
 | 
			
		||||
        $value = strval($value);
 | 
			
		||||
        #XXX rendre paramétrable le formatage de $value
 | 
			
		||||
      }
 | 
			
		||||
      if ($value !== "") {
 | 
			
		||||
        $startw = self::startw($value);
 | 
			
		||||
        if ($wend && $startw) $values[] = " ";
 | 
			
		||||
        $values[] = $value;
 | 
			
		||||
        $wend = self::wend($value);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** écrire le contenu sur la resource spécifiée, qui vaut STDOUT par défaut */
 | 
			
		||||
  static final function write($content, $fd=null, bool $resolve=true): void {
 | 
			
		||||
    if ($resolve) $content = self::resolve($content);
 | 
			
		||||
    $wend = false;
 | 
			
		||||
    foreach ($content as $value) {
 | 
			
		||||
      if ($value === null || $value === false) {
 | 
			
		||||
        continue;
 | 
			
		||||
      } elseif ($value instanceof IPrintable) {
 | 
			
		||||
        if ($fd === null) {
 | 
			
		||||
          $value->print();
 | 
			
		||||
        } else {
 | 
			
		||||
          ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
 | 
			
		||||
          $value->print();
 | 
			
		||||
          fwrite($fd, ob_get_clean());
 | 
			
		||||
        }
 | 
			
		||||
        $wend = false;
 | 
			
		||||
        continue;
 | 
			
		||||
      } elseif ($value instanceof IContent) {
 | 
			
		||||
        $values = [];
 | 
			
		||||
        self::to_values($content, $values);
 | 
			
		||||
        $value = implode("", $values);
 | 
			
		||||
      } else {
 | 
			
		||||
        $value = strval($value);
 | 
			
		||||
        #XXX rendre paramétrable le formattage de $value
 | 
			
		||||
      }
 | 
			
		||||
      $startw = self::startw($value);
 | 
			
		||||
      if (!$wend && !$startw) $value = " $value";
 | 
			
		||||
      if ($fd === null) echo $value;
 | 
			
		||||
      else fwrite($fd, $value);
 | 
			
		||||
      $wend = self::wend($value);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** retourner le contenu sous forme de chaine */
 | 
			
		||||
  static final function to_string($content, bool $resolve=true): string {
 | 
			
		||||
    if ($resolve) $content = self::resolve($content);
 | 
			
		||||
    $values = [];
 | 
			
		||||
    self::to_values($content, $values);
 | 
			
		||||
    return implode("", $values);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -4,7 +4,6 @@ namespace nur\sery\php;
 | 
			
		||||
use Closure;
 | 
			
		||||
use nur\sery\cl;
 | 
			
		||||
use nur\sery\ref\php\ref_func;
 | 
			
		||||
use nur\sery\schema\Schema;
 | 
			
		||||
use nur\sery\ValueException;
 | 
			
		||||
use ReflectionClass;
 | 
			
		||||
use ReflectionFunction;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										71
									
								
								src/wip/web/content/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/wip/web/content/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
# nulib\web\content
 | 
			
		||||
 | 
			
		||||
un contenu web est un type spécial de contenu permettant de gérer aussi les
 | 
			
		||||
attributs avec une syntaxe particulière.
 | 
			
		||||
 | 
			
		||||
les règles diffèrent légèrement:
 | 
			
		||||
- Si le contenu n'est pas un tableau:
 | 
			
		||||
  - une chaine est quotée avec `htmlspecialchars()`
 | 
			
		||||
  - un scalaire ou une instance d'objet sont pris tels quels
 | 
			
		||||
- Sinon, le contenu doit être un tableau, séquentiel ou associatif
 | 
			
		||||
  - les éléments séquentiels scalaires ou instance d'objets sont pris tels quels
 | 
			
		||||
  - les éléments associatifs sont des attributs, et sont fusionnés le cas échéant
 | 
			
		||||
  - les éléments séquentiels de type tableau séqentiel sont du contenu dynamique
 | 
			
		||||
  - les éléments séquentiels de type tableau associatif sont évalues
 | 
			
		||||
    récursivement avec les mêmes règles (sauf la partie chaine quotée avec
 | 
			
		||||
    `htmlspecialchars()`)
 | 
			
		||||
 | 
			
		||||
Par exemple, les deux contenus web suivants sont équivalents:
 | 
			
		||||
~~~php
 | 
			
		||||
# ce contenu:
 | 
			
		||||
$content1 = [
 | 
			
		||||
  "before",
 | 
			
		||||
  "class" => "first",
 | 
			
		||||
  ["class" => "second"],
 | 
			
		||||
  ["func", "arg"],
 | 
			
		||||
  "after",
 | 
			
		||||
];
 | 
			
		||||
# donne le même résultat que:
 | 
			
		||||
$content2 = [
 | 
			
		||||
  "class" => "first second",
 | 
			
		||||
  "before",
 | 
			
		||||
  func("arg"),
 | 
			
		||||
  "after",
 | 
			
		||||
];
 | 
			
		||||
~~~
 | 
			
		||||
 | 
			
		||||
lors de la définition d'attributs,
 | 
			
		||||
- un tableau séquentiel est un appel de fonction
 | 
			
		||||
- un tableau associatif permet de faire des définitions conditionnelles
 | 
			
		||||
 | 
			
		||||
Par exemple, les deux contenus web suivants sont équivalents:
 | 
			
		||||
~~~php
 | 
			
		||||
# ce contenu:
 | 
			
		||||
$content1 = [
 | 
			
		||||
  ["class" => ["func", "arg"]],
 | 
			
		||||
];
 | 
			
		||||
# donne le même résultat que:
 | 
			
		||||
$content2 = [
 | 
			
		||||
  "class" => func("arg"),
 | 
			
		||||
];
 | 
			
		||||
~~~
 | 
			
		||||
De même, les deux contenus web suivants sont équivalents:
 | 
			
		||||
~~~php
 | 
			
		||||
# si $is_primary && !$is_danger
 | 
			
		||||
# alors ce contenu:
 | 
			
		||||
$content1 = [
 | 
			
		||||
  ["class" => [
 | 
			
		||||
    "btn",
 | 
			
		||||
    "btn-primary" => $is_primary,
 | 
			
		||||
    "btn-danger" => $is_danger,
 | 
			
		||||
    "btn-default" => !$is_primary && !$is_danger,
 | 
			
		||||
  ]],
 | 
			
		||||
];
 | 
			
		||||
# donne le même résultat que:
 | 
			
		||||
$content2 = [
 | 
			
		||||
  "class" => "btn btn-primary",
 | 
			
		||||
];
 | 
			
		||||
~~~
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
			
		||||
							
								
								
									
										8
									
								
								src/wip/web/content/v.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/wip/web/content/v.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\wip\web\content;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class v: classe outil pour gérer du contenu pour le web
 | 
			
		||||
 */
 | 
			
		||||
class v {
 | 
			
		||||
}
 | 
			
		||||
@ -5,27 +5,23 @@ use nur\sery\php\content\impl\html;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class contentTest extends TestCase {
 | 
			
		||||
  function testFlattern() {
 | 
			
		||||
    self::assertSame([], content::flatten(null));
 | 
			
		||||
    self::assertSame([], content::flatten([null]));
 | 
			
		||||
    self::assertSame([""], content::flatten(""));
 | 
			
		||||
    self::assertSame([""], content::flatten([""]));
 | 
			
		||||
 | 
			
		||||
    self::assertSame(["a", "b", "c", "d"], content::flatten(["a", ["b", ["c"], "d"]]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function testResolve_static() {
 | 
			
		||||
    self::assertSame([], content::resolve_static(null, null));
 | 
			
		||||
    self::assertSame([], content::resolve_static([null], [null]));
 | 
			
		||||
    self::assertSame([""], content::resolve_static("", ""));
 | 
			
		||||
    self::assertSame([""], content::resolve_static([""], [""]));
 | 
			
		||||
 | 
			
		||||
    self::assertSame(["<quoted>"], content::resolve_static("<quoted>", "<quoted>"));
 | 
			
		||||
    self::assertSame(["<non-quoted>"], content::resolve_static(["<non-quoted>"], ["<non-quoted>"]));
 | 
			
		||||
  function testTo_string() {
 | 
			
		||||
    self::assertSame("", c::to_string(null));
 | 
			
		||||
    self::assertSame("", c::to_string(false));
 | 
			
		||||
    self::assertSame("pouet<q/>", c::to_string("pouet<q/>"));
 | 
			
		||||
    self::assertSame("pouet<q/>", c::to_string(["pouet<q/>"]));
 | 
			
		||||
    self::assertSame("hello world", c::to_string(["hello", "world"]));
 | 
			
		||||
    self::assertSame("hello1 world", c::to_string(["hello1", "world"]));
 | 
			
		||||
    self::assertSame("hello<world>", c::to_string(["hello", "<world>"]));
 | 
			
		||||
    self::assertSame("<hello>world", c::to_string(["<hello>", "world"]));
 | 
			
		||||
    self::assertSame("hello,world", c::to_string(["hello,", "world"]));
 | 
			
		||||
    self::assertSame("hello world", c::to_string(["hello ", "world"]));
 | 
			
		||||
    self::assertSame("hello. world", c::to_string(["hello.", "world"]));
 | 
			
		||||
    self::assertSame("hello.<world>", c::to_string(["hello.", "<world>"]));
 | 
			
		||||
 | 
			
		||||
    self::assertSame(
 | 
			
		||||
      "<h1>title<q/></h1><p>hello<nq/><span>brave<q/></span><span>world<nq/></span></p>",
 | 
			
		||||
      content::to_string([
 | 
			
		||||
      c::to_string([
 | 
			
		||||
        [html::H1, "title<q/>"],
 | 
			
		||||
        [html::P, [
 | 
			
		||||
          "hello<nq/>",
 | 
			
		||||
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\php\content\impl;
 | 
			
		||||
 | 
			
		||||
use nur\sery\php\content\IStaticContent;
 | 
			
		||||
 | 
			
		||||
class AStaticContent implements IStaticContent {
 | 
			
		||||
  function getContent(): iterable {
 | 
			
		||||
    return [
 | 
			
		||||
      [html::P, "static content"],
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +1,22 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\php\content\impl;
 | 
			
		||||
 | 
			
		||||
use nur\sery\php\content\content;
 | 
			
		||||
use nur\sery\php\content\IStaticContent;
 | 
			
		||||
use nur\sery\php\content\c;
 | 
			
		||||
use nur\sery\php\content\IContent;
 | 
			
		||||
 | 
			
		||||
class ATag implements IStaticContent {
 | 
			
		||||
  function __construct(string $tag, $contents=null) {
 | 
			
		||||
class ATag implements IContent {
 | 
			
		||||
  function __construct(string $tag, $content=null) {
 | 
			
		||||
    $this->tag = $tag;
 | 
			
		||||
    $this->contents = $contents;
 | 
			
		||||
    $this->content = $content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected $tag;
 | 
			
		||||
  protected $contents;
 | 
			
		||||
  protected $content;
 | 
			
		||||
 | 
			
		||||
  function getContent(): iterable {
 | 
			
		||||
    return [
 | 
			
		||||
      "<$this->tag>",
 | 
			
		||||
      ...content::quote($this->contents),
 | 
			
		||||
      ...c::q($this->content),
 | 
			
		||||
      "</$this->tag>",
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,8 @@ class html {
 | 
			
		||||
  const P = [self::class, "p"];
 | 
			
		||||
  const SPAN = [self::class, "span"];
 | 
			
		||||
 | 
			
		||||
  static function h1($contents) { return new ATag("h1", $contents); }
 | 
			
		||||
  static function div($contents) { return new ATag("div", $contents); }
 | 
			
		||||
  static function p($contents) { return new ATag("p", $contents); }
 | 
			
		||||
  static function span($contents) { return new ATag("span", $contents); }
 | 
			
		||||
  static function h1($content) { return new ATag("h1", $content); }
 | 
			
		||||
  static function div($content) { return new ATag("div", $content); }
 | 
			
		||||
  static function p($content) { return new ATag("p", $content); }
 | 
			
		||||
  static function span($content) { return new ATag("span", $content); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user