@vituum/vite-plugin-latte 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +6 -6
  2. package/vendor/autoload.php +1 -1
  3. package/vendor/composer/autoload_real.php +4 -4
  4. package/vendor/composer/autoload_static.php +2 -2
  5. package/vendor/composer/installed.json +21 -20
  6. package/vendor/composer/installed.php +8 -8
  7. package/vendor/latte/latte/composer.json +6 -5
  8. package/vendor/latte/latte/readme.md +27 -9
  9. package/vendor/latte/latte/src/Bridges/Tracy/templates/LattePanel.panel.phtml +4 -1
  10. package/vendor/latte/latte/src/Latte/Compiler/TagLexer.php +1 -1
  11. package/vendor/latte/latte/src/Latte/Compiler/TagParserData.php +129 -129
  12. package/vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php +1 -1
  13. package/vendor/latte/latte/src/Latte/Compiler/TemplateParser.php +1 -1
  14. package/vendor/latte/latte/src/Latte/Engine.php +22 -2
  15. package/vendor/latte/latte/src/Latte/Essential/CachingIterator.php +2 -3
  16. package/vendor/latte/latte/src/Latte/Essential/CoreExtension.php +9 -1
  17. package/vendor/latte/latte/src/Latte/Essential/Filters.php +110 -10
  18. package/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php +8 -2
  19. package/vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php +14 -18
  20. package/vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php +1 -1
  21. package/vendor/latte/latte/src/Latte/Loaders/FileLoader.php +5 -4
  22. package/vendor/latte/latte/src/Latte/Runtime/Template.php +1 -1
  23. package/vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php +0 -1
  24. package/vendor/nette/utils/composer.json +1 -1
  25. package/vendor/nette/utils/readme.md +25 -26
  26. package/vendor/nette/utils/src/Iterators/CachingIterator.php +5 -19
  27. package/vendor/nette/utils/src/Iterators/Mapper.php +1 -2
  28. package/vendor/nette/utils/src/Utils/Arrays.php +59 -28
  29. package/vendor/nette/utils/src/Utils/Callback.php +1 -1
  30. package/vendor/nette/utils/src/Utils/Image.php +14 -12
  31. package/vendor/nette/utils/src/Utils/Iterables.php +99 -20
  32. package/vendor/nette/utils/src/Utils/Reflection.php +5 -3
  33. package/vendor/nette/utils/src/Utils/Strings.php +26 -6
@@ -163,10 +163,7 @@ class Image
163
163
  */
164
164
  public static function fromFile(string $file, ?int &$type = null): static
165
165
  {
166
- if (!extension_loaded('gd')) {
167
- throw new Nette\NotSupportedException('PHP extension GD is not loaded.');
168
- }
169
-
166
+ self::ensureExtension();
170
167
  $type = self::detectTypeFromFile($file);
171
168
  if (!$type) {
172
169
  throw new UnknownImageFileException(is_file($file) ? "Unknown type of file '$file'." : "File '$file' not found.");
@@ -183,10 +180,7 @@ class Image
183
180
  */
184
181
  public static function fromString(string $s, ?int &$type = null): static
185
182
  {
186
- if (!extension_loaded('gd')) {
187
- throw new Nette\NotSupportedException('PHP extension GD is not loaded.');
188
- }
189
-
183
+ self::ensureExtension();
190
184
  $type = self::detectTypeFromString($s);
191
185
  if (!$type) {
192
186
  throw new UnknownImageFileException('Unknown type of image.');
@@ -221,10 +215,7 @@ class Image
221
215
  */
222
216
  public static function fromBlank(int $width, int $height, ImageColor|array|null $color = null): static
223
217
  {
224
- if (!extension_loaded('gd')) {
225
- throw new Nette\NotSupportedException('PHP extension GD is not loaded.');
226
- }
227
-
218
+ self::ensureExtension();
228
219
  if ($width < 1 || $height < 1) {
229
220
  throw new Nette\InvalidArgumentException('Image width and height must be greater than zero.');
230
221
  }
@@ -308,6 +299,7 @@ class Image
308
299
  */
309
300
  public static function isTypeSupported(int $type): bool
310
301
  {
302
+ self::ensureExtension();
311
303
  return (bool) (imagetypes() & match ($type) {
312
304
  ImageType::JPEG => IMG_JPG,
313
305
  ImageType::PNG => IMG_PNG,
@@ -323,6 +315,7 @@ class Image
323
315
  /** @return ImageType[] */
324
316
  public static function getSupportedTypes(): array
325
317
  {
318
+ self::ensureExtension();
326
319
  $flag = imagetypes();
327
320
  return array_filter([
328
321
  $flag & IMG_GIF ? ImageType::GIF : null,
@@ -640,6 +633,7 @@ class Image
640
633
  array $options = [],
641
634
  ): array
642
635
  {
636
+ self::ensureExtension();
643
637
  $box = imagettfbbox($size, $angle, $fontFile, $text, $options);
644
638
  return [
645
639
  'left' => $minX = min([$box[0], $box[2], $box[4], $box[6]]),
@@ -826,4 +820,12 @@ class Image
826
820
  $color = $color instanceof ImageColor ? $color->toRGBA() : array_values($color);
827
821
  return imagecolorallocatealpha($this->image, ...$color) ?: imagecolorresolvealpha($this->image, ...$color);
828
822
  }
823
+
824
+
825
+ private static function ensureExtension(): void
826
+ {
827
+ if (!extension_loaded('gd')) {
828
+ throw new Nette\NotSupportedException('PHP extension GD is not loaded.');
829
+ }
830
+ }
829
831
  }
@@ -49,10 +49,11 @@ final class Iterables
49
49
 
50
50
  /**
51
51
  * Returns the first item (matching the specified predicate if given). If there is no such item, it returns result of invoking $else or null.
52
- * The $predicate has the signature `function (mixed $value, mixed $key, iterable $iterable): bool`.
53
- * @template T
54
- * @param iterable<T> $iterable
55
- * @return ?T
52
+ * @template K
53
+ * @template V
54
+ * @param iterable<K, V> $iterable
55
+ * @param ?callable(V, K, iterable<K, V>): bool $predicate
56
+ * @return ?V
56
57
  */
57
58
  public static function first(iterable $iterable, ?callable $predicate = null, ?callable $else = null): mixed
58
59
  {
@@ -67,10 +68,11 @@ final class Iterables
67
68
 
68
69
  /**
69
70
  * Returns the key of first item (matching the specified predicate if given). If there is no such item, it returns result of invoking $else or null.
70
- * The $predicate has the signature `function (mixed $value, mixed $key, iterable $iterable): bool`.
71
- * @template T
72
- * @param iterable<T, mixed> $iterable
73
- * @return ?T
71
+ * @template K
72
+ * @template V
73
+ * @param iterable<K, V> $iterable
74
+ * @param ?callable(V, K, iterable<K, V>): bool $predicate
75
+ * @return ?K
74
76
  */
75
77
  public static function firstKey(iterable $iterable, ?callable $predicate = null, ?callable $else = null): mixed
76
78
  {
@@ -84,11 +86,10 @@ final class Iterables
84
86
 
85
87
 
86
88
  /**
87
- * Tests whether at least one element in the iterator passes the test implemented by the
88
- * provided callback with signature `function (mixed $value, mixed $key, iterable $iterable): bool`.
89
+ * Tests whether at least one element in the iterator passes the test implemented by the provided function.
89
90
  * @template K
90
91
  * @template V
91
- * @param iterable<K, V> $iterable
92
+ * @param iterable<K, V> $iterable
92
93
  * @param callable(V, K, iterable<K, V>): bool $predicate
93
94
  */
94
95
  public static function some(iterable $iterable, callable $predicate): bool
@@ -103,11 +104,10 @@ final class Iterables
103
104
 
104
105
 
105
106
  /**
106
- * Tests whether all elements in the iterator pass the test implemented by the provided function,
107
- * which has the signature `function (mixed $value, mixed $key, iterable $iterable): bool`.
107
+ * Tests whether all elements in the iterator pass the test implemented by the provided function.
108
108
  * @template K
109
109
  * @template V
110
- * @param iterable<K, V> $iterable
110
+ * @param iterable<K, V> $iterable
111
111
  * @param callable(V, K, iterable<K, V>): bool $predicate
112
112
  */
113
113
  public static function every(iterable $iterable, callable $predicate): bool
@@ -123,11 +123,10 @@ final class Iterables
123
123
 
124
124
  /**
125
125
  * Iterator that filters elements according to a given $predicate. Maintains original keys.
126
- * The callback has the signature `function (mixed $value, mixed $key, iterable $iterable): bool`.
127
126
  * @template K
128
127
  * @template V
129
- * @param iterable<K, V> $iterable
130
- * @param callable(V, K, iterable<K, V>): bool $predicate
128
+ * @param iterable<K, V> $iterable
129
+ * @param callable(V, K, iterable<K, V>): bool $predicate
131
130
  * @return \Generator<K, V>
132
131
  */
133
132
  public static function filter(iterable $iterable, callable $predicate): \Generator
@@ -142,12 +141,11 @@ final class Iterables
142
141
 
143
142
  /**
144
143
  * Iterator that transforms values by calling $transformer. Maintains original keys.
145
- * The callback has the signature `function (mixed $value, mixed $key, iterable $iterable): bool`.
146
144
  * @template K
147
145
  * @template V
148
146
  * @template R
149
- * @param iterable<K, V> $iterable
150
- * @param callable(V, K, iterable<K, V>): R $transformer
147
+ * @param iterable<K, V> $iterable
148
+ * @param callable(V, K, iterable<K, V>): R $transformer
151
149
  * @return \Generator<K, R>
152
150
  */
153
151
  public static function map(iterable $iterable, callable $transformer): \Generator
@@ -156,4 +154,85 @@ final class Iterables
156
154
  yield $k => $transformer($v, $k, $iterable);
157
155
  }
158
156
  }
157
+
158
+
159
+ /**
160
+ * Iterator that transforms keys and values by calling $transformer. If it returns null, the element is skipped.
161
+ * @template K
162
+ * @template V
163
+ * @template ResV
164
+ * @template ResK
165
+ * @param iterable<K, V> $iterable
166
+ * @param callable(V, K, iterable<K, V>): ?array{ResV, ResK} $transformer
167
+ * @return \Generator<ResV, ResK>
168
+ */
169
+ public static function mapWithKeys(iterable $iterable, callable $transformer): \Generator
170
+ {
171
+ foreach ($iterable as $k => $v) {
172
+ $pair = $transformer($v, $k, $iterable);
173
+ if ($pair) {
174
+ yield $pair[0] => $pair[1];
175
+ }
176
+ }
177
+ }
178
+
179
+
180
+ /**
181
+ * Wraps around iterator and caches its keys and values during iteration.
182
+ * This allows the data to be re-iterated multiple times.
183
+ * @template K
184
+ * @template V
185
+ * @param iterable<K, V> $iterable
186
+ * @return \IteratorAggregate<K, V>
187
+ */
188
+ public static function memoize(iterable $iterable): iterable
189
+ {
190
+ return new class (self::toIterator($iterable)) implements \IteratorAggregate {
191
+ public function __construct(
192
+ private \Iterator $iterator,
193
+ private array $cache = [],
194
+ ) {
195
+ }
196
+
197
+
198
+ public function getIterator(): \Generator
199
+ {
200
+ if (!$this->cache) {
201
+ $this->iterator->rewind();
202
+ }
203
+ $i = 0;
204
+ while (true) {
205
+ if (isset($this->cache[$i])) {
206
+ [$k, $v] = $this->cache[$i];
207
+ } elseif ($this->iterator->valid()) {
208
+ $k = $this->iterator->key();
209
+ $v = $this->iterator->current();
210
+ $this->iterator->next();
211
+ $this->cache[$i] = [$k, $v];
212
+ } else {
213
+ break;
214
+ }
215
+ yield $k => $v;
216
+ $i++;
217
+ }
218
+ }
219
+ };
220
+ }
221
+
222
+
223
+ /**
224
+ * Creates an iterator from anything that is iterable.
225
+ * @template K
226
+ * @template V
227
+ * @param iterable<K, V> $iterable
228
+ * @return \Iterator<K, V>
229
+ */
230
+ public static function toIterator(iterable $iterable): \Iterator
231
+ {
232
+ return match (true) {
233
+ $iterable instanceof \Iterator => $iterable,
234
+ $iterable instanceof \IteratorAggregate => self::toIterator($iterable->getIterator()),
235
+ is_array($iterable) => new \ArrayIterator($iterable),
236
+ };
237
+ }
159
238
  }
@@ -100,7 +100,7 @@ final class Reflection
100
100
 
101
101
  $hash = [$method->getFileName(), $method->getStartLine(), $method->getEndLine()];
102
102
  if (($alias = $decl->getTraitAliases()[$method->name] ?? null)
103
- && ($m = new \ReflectionMethod($alias))
103
+ && ($m = new \ReflectionMethod(...explode('::', $alias, 2)))
104
104
  && $hash === [$m->getFileName(), $m->getStartLine(), $m->getEndLine()]
105
105
  ) {
106
106
  return self::getMethodDeclaringMethod($m);
@@ -125,7 +125,7 @@ final class Reflection
125
125
  public static function areCommentsAvailable(): bool
126
126
  {
127
127
  static $res;
128
- return $res ?? $res = (bool) (new \ReflectionMethod(__METHOD__))->getDocComment();
128
+ return $res ?? $res = (bool) (new \ReflectionMethod(self::class, __FUNCTION__))->getDocComment();
129
129
  }
130
130
 
131
131
 
@@ -136,7 +136,9 @@ final class Reflection
136
136
  } elseif ($ref instanceof \ReflectionMethod) {
137
137
  return $ref->getDeclaringClass()->name . '::' . $ref->name . '()';
138
138
  } elseif ($ref instanceof \ReflectionFunction) {
139
- return $ref->name . '()';
139
+ return PHP_VERSION_ID >= 80200 && $ref->isAnonymous()
140
+ ? '{closure}()'
141
+ : $ref->name . '()';
140
142
  } elseif ($ref instanceof \ReflectionProperty) {
141
143
  return self::getPropertyDeclaringClass($ref)->name . '::$' . $ref->name;
142
144
  } elseif ($ref instanceof \ReflectionParameter) {
@@ -589,6 +589,7 @@ class Strings
589
589
  /**
590
590
  * Searches the string for all occurrences matching the regular expression and
591
591
  * returns an array of arrays containing the found expression and each subexpression.
592
+ * @return ($lazy is true ? \Generator<int, array> : array[])
592
593
  */
593
594
  public static function matchAll(
594
595
  string $subject,
@@ -599,21 +600,41 @@ class Strings
599
600
  bool $unmatchedAsNull = false,
600
601
  bool $patternOrder = false,
601
602
  bool $utf8 = false,
602
- ): array
603
+ bool $lazy = false,
604
+ ): array|\Generator
603
605
  {
604
- $flags = is_int($captureOffset) // back compatibility
605
- ? $captureOffset
606
- : ($captureOffset ? PREG_OFFSET_CAPTURE : 0) | ($unmatchedAsNull ? PREG_UNMATCHED_AS_NULL : 0) | ($patternOrder ? PREG_PATTERN_ORDER : 0);
607
-
608
606
  if ($utf8) {
609
607
  $offset = strlen(self::substring($subject, 0, $offset));
610
608
  $pattern .= 'u';
611
609
  }
612
610
 
611
+ if ($lazy) {
612
+ $flags = PREG_OFFSET_CAPTURE | ($unmatchedAsNull ? PREG_UNMATCHED_AS_NULL : 0);
613
+ return (function () use ($utf8, $captureOffset, $flags, $subject, $pattern, $offset) {
614
+ $counter = 0;
615
+ while (
616
+ $offset <= strlen($subject) - ($counter ? 1 : 0)
617
+ && self::pcre('preg_match', [$pattern, $subject, &$m, $flags, $offset])
618
+ ) {
619
+ $offset = $m[0][1] + max(1, strlen($m[0][0]));
620
+ if (!$captureOffset) {
621
+ $m = array_map(fn($item) => $item[0], $m);
622
+ } elseif ($utf8) {
623
+ $m = self::bytesToChars($subject, [$m])[0];
624
+ }
625
+ yield $counter++ => $m;
626
+ }
627
+ })();
628
+ }
629
+
613
630
  if ($offset > strlen($subject)) {
614
631
  return [];
615
632
  }
616
633
 
634
+ $flags = is_int($captureOffset) // back compatibility
635
+ ? $captureOffset
636
+ : ($captureOffset ? PREG_OFFSET_CAPTURE : 0) | ($unmatchedAsNull ? PREG_UNMATCHED_AS_NULL : 0) | ($patternOrder ? PREG_PATTERN_ORDER : 0);
637
+
617
638
  self::pcre('preg_match_all', [
618
639
  $pattern, $subject, &$m,
619
640
  ($flags & PREG_PATTERN_ORDER) ? $flags : ($flags | PREG_SET_ORDER),
@@ -622,7 +643,6 @@ class Strings
622
643
  return $utf8 && $captureOffset
623
644
  ? self::bytesToChars($subject, $m)
624
645
  : $m;
625
-
626
646
  }
627
647
 
628
648