From 704e11f357dd5911b7a142076f41dad672656e84 Mon Sep 17 00:00:00 2001
From: Stefan Mielke
Date: Fri, 26 Jan 2024 08:38:21 +0100
Subject: [PATCH 001/202] Add option to change number of threads for
imagemagick convert
---
src/Image/Darkroom/ImageMagick.php | 5 +++--
tests/Image/Darkroom/ImageMagickTest.php | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Image/Darkroom/ImageMagick.php b/src/Image/Darkroom/ImageMagick.php
index 49892368e0..8e65e5412b 100644
--- a/src/Image/Darkroom/ImageMagick.php
+++ b/src/Image/Darkroom/ImageMagick.php
@@ -62,8 +62,8 @@ protected function convert(string $file, array $options): string
{
$command = escapeshellarg($options['bin']);
- // limit to single-threading to keep CPU usage sane
- $command .= ' -limit thread 1';
+ // default is limiting to single-threading to keep CPU usage sane
+ $command .= ' -limit thread ' . escapeshellarg($options['thread']);
// add JPEG size hint to optimize CPU and memory usage
if (F::mime($file) === 'image/jpeg') {
@@ -85,6 +85,7 @@ protected function defaults(): array
return parent::defaults() + [
'bin' => 'convert',
'interlace' => false,
+ 'thread' => 1,
];
}
diff --git a/tests/Image/Darkroom/ImageMagickTest.php b/tests/Image/Darkroom/ImageMagickTest.php
index 9d04f3f05c..c7baec5ebc 100644
--- a/tests/Image/Darkroom/ImageMagickTest.php
+++ b/tests/Image/Darkroom/ImageMagickTest.php
@@ -45,6 +45,7 @@ public function testProcess()
'width' => 500,
'bin' => 'convert',
'interlace' => false,
+ 'thread' => 1,
'sourceWidth' => 500,
'sourceHeight' => 500
], $im->process($file));
From b83dfeb5157a57d9873ab2b142d60cd218d3abba Mon Sep 17 00:00:00 2001
From: Stefan Mielke
Date: Tue, 30 Jan 2024 12:33:21 +0100
Subject: [PATCH 002/202] rename option to threads
---
src/Image/Darkroom/ImageMagick.php | 4 ++--
tests/Image/Darkroom/ImageMagickTest.php | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Image/Darkroom/ImageMagick.php b/src/Image/Darkroom/ImageMagick.php
index 8e65e5412b..1c0f281bc6 100644
--- a/src/Image/Darkroom/ImageMagick.php
+++ b/src/Image/Darkroom/ImageMagick.php
@@ -63,7 +63,7 @@ protected function convert(string $file, array $options): string
$command = escapeshellarg($options['bin']);
// default is limiting to single-threading to keep CPU usage sane
- $command .= ' -limit thread ' . escapeshellarg($options['thread']);
+ $command .= ' -limit thread ' . escapeshellarg($options['threads']);
// add JPEG size hint to optimize CPU and memory usage
if (F::mime($file) === 'image/jpeg') {
@@ -85,7 +85,7 @@ protected function defaults(): array
return parent::defaults() + [
'bin' => 'convert',
'interlace' => false,
- 'thread' => 1,
+ 'threads' => 1,
];
}
diff --git a/tests/Image/Darkroom/ImageMagickTest.php b/tests/Image/Darkroom/ImageMagickTest.php
index c7baec5ebc..2b2718ad44 100644
--- a/tests/Image/Darkroom/ImageMagickTest.php
+++ b/tests/Image/Darkroom/ImageMagickTest.php
@@ -45,7 +45,7 @@ public function testProcess()
'width' => 500,
'bin' => 'convert',
'interlace' => false,
- 'thread' => 1,
+ 'threads' => 1,
'sourceWidth' => 500,
'sourceHeight' => 500
], $im->process($file));
From 53143ecf5dc7c40f40a27359920a3e9d7c3195e8 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 15:12:38 +0100
Subject: [PATCH 003/202] Fix `A::prepend()`
---
src/Toolkit/A.php | 2 +-
tests/Toolkit/ATest.php | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/Toolkit/A.php b/src/Toolkit/A.php
index 850fb5cf48..a62d9c2a55 100644
--- a/src/Toolkit/A.php
+++ b/src/Toolkit/A.php
@@ -588,7 +588,7 @@ public static function pluck(array $array, string $key): array
*/
public static function prepend(array $array, array $prepend): array
{
- return $prepend + $array;
+ return static::merge($prepend, $array, A::MERGE_APPEND);
}
/**
diff --git a/tests/Toolkit/ATest.php b/tests/Toolkit/ATest.php
index 0507108c0f..8ea33567cf 100644
--- a/tests/Toolkit/ATest.php
+++ b/tests/Toolkit/ATest.php
@@ -496,6 +496,30 @@ public function testMergeModes()
$this->assertSame($expected, $result);
}
+ /**
+ * @covers ::prepend
+ */
+ public function testPrepend()
+ {
+ // associative
+ $one = ['a' => 'A', 'b' => 'B', 'c' => 'C'];
+ $two = ['d' => 'D', 'e' => 'E', 'f' => 'F'];
+ $result = A::prepend($one, $two);
+ $this->assertSame(['d' => 'D', 'e' => 'E', 'f' => 'F', 'a' => 'A', 'b' => 'B', 'c' => 'C'], $result);
+
+ // numeric
+ $one = ['a', 'b', 'c'];
+ $two = ['d', 'e', 'f'];
+ $result = A::prepend($one, $two);
+ $this->assertSame(['d', 'e', 'f', 'a', 'b', 'c'], $result);
+
+ // mixed
+ $one = ['a' => 'A', 'b' => 'B', 'c' => 'C'];
+ $two = ['d', 'e', 'f'];
+ $result = A::prepend($one, $two);
+ $this->assertSame(['d', 'e', 'f', 'a' => 'A', 'b' => 'B', 'c' => 'C'], $result);
+ }
+
/**
* @covers ::pluck
*/
From 98dbc5e2e6c66b765ab94294555b8f6329028a42 Mon Sep 17 00:00:00 2001
From: Lukas Bestle
Date: Wed, 31 Jan 2024 19:30:51 +0100
Subject: [PATCH 004/202] Fix coding style
---
src/Image/Darkroom/ImageMagick.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Image/Darkroom/ImageMagick.php b/src/Image/Darkroom/ImageMagick.php
index 1c0f281bc6..ecac0f390f 100644
--- a/src/Image/Darkroom/ImageMagick.php
+++ b/src/Image/Darkroom/ImageMagick.php
@@ -85,7 +85,7 @@ protected function defaults(): array
return parent::defaults() + [
'bin' => 'convert',
'interlace' => false,
- 'threads' => 1,
+ 'threads' => 1,
];
}
From 69810e29e734a57f2e90204dc66813c6c6e3192c Mon Sep 17 00:00:00 2001
From: Ahmet Bora
Date: Thu, 1 Feb 2024 21:43:49 +0300
Subject: [PATCH 005/202] Translatable range tooltip #6221
---
config/fields/range.php | 9 ++++++
tests/Form/Fields/RangeFieldTest.php | 46 ++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/config/fields/range.php b/config/fields/range.php
index 04221f1372..d203a7e77e 100644
--- a/config/fields/range.php
+++ b/config/fields/range.php
@@ -1,5 +1,7 @@
'number',
'props' => [
@@ -18,6 +20,13 @@
* Enables/disables the tooltip and set the before and after values
*/
'tooltip' => function ($tooltip = true) {
+ if (is_array($tooltip) === true) {
+ $after = $tooltip['after'] ?? null;
+ $before = $tooltip['before'] ?? null;
+ $tooltip['after'] = I18n::translate($after, $after);
+ $tooltip['before'] = I18n::translate($before, $before);
+ }
+
return $tooltip;
},
]
diff --git a/tests/Form/Fields/RangeFieldTest.php b/tests/Form/Fields/RangeFieldTest.php
index fea86e624b..ccf973ffd1 100644
--- a/tests/Form/Fields/RangeFieldTest.php
+++ b/tests/Form/Fields/RangeFieldTest.php
@@ -2,6 +2,8 @@
namespace Kirby\Form\Fields;
+use Kirby\Toolkit\I18n;
+
class RangeFieldTest extends TestCase
{
public function testDefaultProps()
@@ -40,4 +42,48 @@ public function testMax()
$this->assertFalse($field->isValid());
$this->assertArrayHasKey('max', $field->errors());
}
+
+ public function testTooltip()
+ {
+ $field = $this->field('range', [
+ 'tooltip' => [
+ 'before' => 'per',
+ 'after' => 'months'
+ ]
+ ]);
+
+ $tooltip = $field->tooltip();
+ $this->assertIsArray($tooltip);
+ $this->assertSame('per', $tooltip['before']);
+ $this->assertSame('months', $tooltip['after']);
+ }
+
+ public function testTooltipTranslation()
+ {
+ $props = [
+ 'tooltip' => [
+ 'before' => [
+ 'en' => 'per',
+ 'de' => 'pro'
+ ],
+ 'after' => [
+ 'en' => 'months',
+ 'de' => 'monate'
+ ]
+ ]
+ ];
+
+ I18n::$locale = 'en';
+ $tooltip = $this->field('range', $props)->tooltip();
+ $this->assertIsArray($tooltip);
+ $this->assertSame('per', $tooltip['before']);
+ $this->assertSame('months', $tooltip['after']);
+
+
+ I18n::$locale = 'de';
+ $tooltip = $this->field('range', $props)->tooltip();
+ $this->assertIsArray($tooltip);
+ $this->assertSame('pro', $tooltip['before']);
+ $this->assertSame('monate', $tooltip['after']);
+ }
}
From da033a3a3a1596e46fc807416d4a13e9993c9913 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 25 Jan 2024 20:24:48 +0100
Subject: [PATCH 006/202] Improve input disabled styles
---
panel/src/components/Forms/Field/LinkField.vue | 5 +++--
panel/src/components/Forms/Input/ChoiceInput.vue | 11 ++++++++++-
panel/src/components/Forms/Input/DateInput.vue | 9 ++++++++-
panel/src/components/Forms/Input/TextInput.vue | 10 +++++++++-
panel/src/components/Forms/Input/ToggleInput.vue | 1 +
5 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/panel/src/components/Forms/Field/LinkField.vue b/panel/src/components/Forms/Field/LinkField.vue
index 986f06e7a7..dc2def4a7b 100644
--- a/panel/src/components/Forms/Field/LinkField.vue
+++ b/panel/src/components/Forms/Field/LinkField.vue
@@ -29,7 +29,7 @@
:value="value"
@remove="removeModel"
>
-
+
{{ currentType.placeholder }}
@@ -43,8 +43,9 @@
v-else
:id="id"
ref="input"
+ :disabled="disabled"
+ :placeholder="!disabled ? currentType.placeholder : null"
:pattern="currentType.pattern ?? null"
- :placeholder="currentType.placeholder"
:value="linkValue"
@invalid="onInvalid"
@input="onInput"
diff --git a/panel/src/components/Forms/Input/ChoiceInput.vue b/panel/src/components/Forms/Input/ChoiceInput.vue
index 4c7a090bb0..9b406f985b 100644
--- a/panel/src/components/Forms/Input/ChoiceInput.vue
+++ b/panel/src/components/Forms/Input/ChoiceInput.vue
@@ -92,11 +92,20 @@ export default {
/* Field context */
:where(.k-checkboxes-field, .k-radio-field) .k-choice-input {
- background: var(--input-color-back);
min-height: var(--input-height);
padding-block: var(--spacing-2);
padding-inline: var(--spacing-3);
border-radius: var(--input-rounded);
+}
+
+:where(.k-checkboxes-field, .k-radio-field)
+ .k-choice-input:not([aria-disabled="true"]) {
+ background: var(--input-color-back);
box-shadow: var(--shadow);
}
+
+:where(.k-checkboxes-field, .k-radio-field)
+ .k-choice-input[aria-disabled="true"] {
+ border: 1px solid var(--input-color-border);
+}
diff --git a/panel/src/components/Forms/Input/DateInput.vue b/panel/src/components/Forms/Input/DateInput.vue
index 642adb5f93..868ae62551 100644
--- a/panel/src/components/Forms/Input/DateInput.vue
+++ b/panel/src/components/Forms/Input/DateInput.vue
@@ -6,7 +6,7 @@
:autofocus="autofocus"
:class="`k-text-input k-${type}-input`"
:disabled="disabled"
- :placeholder="display"
+ :placeholder="placeholder"
:required="required"
:value="formatted"
autocomplete="off"
@@ -108,6 +108,13 @@ export default {
pattern() {
return this.$library.dayjs.pattern(this.display);
},
+ placeholder() {
+ if (this.disabled) {
+ return null;
+ }
+
+ return this.display;
+ },
/**
* Merges step donfiguration with defaults
* @returns {Object}
diff --git a/panel/src/components/Forms/Input/TextInput.vue b/panel/src/components/Forms/Input/TextInput.vue
index b65da51dee..bcb6bbf9da 100644
--- a/panel/src/components/Forms/Input/TextInput.vue
+++ b/panel/src/components/Forms/Input/TextInput.vue
@@ -9,7 +9,7 @@
minlength,
name,
pattern,
- placeholder,
+ placeholder: !disabled && hasPlaceholder ? placeholder : null,
required,
spellcheck,
type,
@@ -78,6 +78,14 @@ export default {
}
};
},
+ computed: {
+ /**
+ * Whether the input has an explicit placeholder set (not the default)
+ */
+ hasPlaceholder() {
+ return this.$options.propsData.placeholder !== undefined;
+ }
+ },
watch: {
value() {
this.onInvalid();
diff --git a/panel/src/components/Forms/Input/ToggleInput.vue b/panel/src/components/Forms/Input/ToggleInput.vue
index 93a6cd0f48..31353cfbf1 100644
--- a/panel/src/components/Forms/Input/ToggleInput.vue
+++ b/panel/src/components/Forms/Input/ToggleInput.vue
@@ -105,5 +105,6 @@ export default {
}
.k-input[data-type="toggle"][data-disabled] {
box-shadow: none;
+ border: 1px solid var(--color-border);
}
From 75bcc6ae0cfb82f8851ba50cb62ae8e6d4c854fc Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Mon, 29 Jan 2024 12:16:43 +0100
Subject: [PATCH 007/202] Hide placeholders in disabled inputs via CSS
---
panel/src/components/Forms/Field/LinkField.vue | 11 +++++++++--
panel/src/components/Forms/Input/DateInput.vue | 15 +++++++--------
panel/src/components/Forms/Input/TextInput.vue | 13 ++++---------
panel/src/components/Forms/Input/TimeInput.vue | 6 ++++++
4 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/panel/src/components/Forms/Field/LinkField.vue b/panel/src/components/Forms/Field/LinkField.vue
index dc2def4a7b..fda80f9744 100644
--- a/panel/src/components/Forms/Field/LinkField.vue
+++ b/panel/src/components/Forms/Field/LinkField.vue
@@ -29,7 +29,7 @@
:value="value"
@remove="removeModel"
>
-
+
{{ currentType.placeholder }}
@@ -44,8 +44,8 @@
:id="id"
ref="input"
:disabled="disabled"
- :placeholder="!disabled ? currentType.placeholder : null"
:pattern="currentType.pattern ?? null"
+ :placeholder="currentType.placeholder"
:value="linkValue"
@invalid="onInvalid"
@input="onInput"
@@ -345,4 +345,11 @@ export default {
.k-link-field .k-bubbles-field-preview .k-bubble {
font-size: var(--text-sm);
}
+
+.k-link-field[data-disabled="true"] .k-link-input-model-placeholder {
+ display: none;
+}
+.k-link-field[data-disabled="true"] input::placeholder {
+ opacity: 0;
+}
diff --git a/panel/src/components/Forms/Input/DateInput.vue b/panel/src/components/Forms/Input/DateInput.vue
index 868ae62551..21aa7297c1 100644
--- a/panel/src/components/Forms/Input/DateInput.vue
+++ b/panel/src/components/Forms/Input/DateInput.vue
@@ -6,7 +6,7 @@
:autofocus="autofocus"
:class="`k-text-input k-${type}-input`"
:disabled="disabled"
- :placeholder="placeholder"
+ :placeholder="display"
:required="required"
:value="formatted"
autocomplete="off"
@@ -108,13 +108,6 @@ export default {
pattern() {
return this.$library.dayjs.pattern(this.display);
},
- placeholder() {
- if (this.disabled) {
- return null;
- }
-
- return this.display;
- },
/**
* Merges step donfiguration with defaults
* @returns {Object}
@@ -463,3 +456,9 @@ export default {
}
};
+
+
diff --git a/panel/src/components/Forms/Input/TextInput.vue b/panel/src/components/Forms/Input/TextInput.vue
index bcb6bbf9da..28679281cb 100644
--- a/panel/src/components/Forms/Input/TextInput.vue
+++ b/panel/src/components/Forms/Input/TextInput.vue
@@ -9,7 +9,7 @@
minlength,
name,
pattern,
- placeholder: !disabled && hasPlaceholder ? placeholder : null,
+ placeholder,
required,
spellcheck,
type,
@@ -78,14 +78,6 @@ export default {
}
};
},
- computed: {
- /**
- * Whether the input has an explicit placeholder set (not the default)
- */
- hasPlaceholder() {
- return this.$options.propsData.placeholder !== undefined;
- }
- },
watch: {
value() {
this.onInvalid();
@@ -145,4 +137,7 @@ export default {
.k-text-input[data-font="monospace"] {
font-family: var(--font-mono);
}
+.k-text-input:disabled::placeholder {
+ opacity: 0;
+}
diff --git a/panel/src/components/Forms/Input/TimeInput.vue b/panel/src/components/Forms/Input/TimeInput.vue
index 685599ab54..18554704da 100644
--- a/panel/src/components/Forms/Input/TimeInput.vue
+++ b/panel/src/components/Forms/Input/TimeInput.vue
@@ -72,3 +72,9 @@ export default {
}
};
+
+
From 25104b663b581da601da39bee687c415b99d8ac0 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Mon, 1 Jan 2024 22:29:54 +0100
Subject: [PATCH 008/202] Skip `FileActions::changeSort` when same `$sort`
---
src/Cms/FileActions.php | 5 +++++
tests/Cms/Files/FileActionsTest.php | 17 +++++++++++------
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/Cms/FileActions.php b/src/Cms/FileActions.php
index da657dd09f..890610fe82 100644
--- a/src/Cms/FileActions.php
+++ b/src/Cms/FileActions.php
@@ -100,6 +100,11 @@ public function changeName(
*/
public function changeSort(int $sort): static
{
+ // skip if the sort number stays the same
+ if ($this->sort()->value() === $sort) {
+ return $this;
+ }
+
return $this->commit(
'changeSort',
['file' => $this, 'position' => $sort],
diff --git a/tests/Cms/Files/FileActionsTest.php b/tests/Cms/Files/FileActionsTest.php
index ae189fc8e5..3d8b91aaa7 100644
--- a/tests/Cms/Files/FileActionsTest.php
+++ b/tests/Cms/Files/FileActionsTest.php
@@ -973,13 +973,16 @@ public function testChangeSortHooks()
'site' => [
'files' => [
[
- 'filename' => 'site-1.csv'
+ 'filename' => 'site-1.csv',
+ 'content' => ['sort' => 1]
],
[
- 'filename' => 'site-2.csv'
+ 'filename' => 'site-2.csv',
+ 'content' => ['sort' => 2]
],
[
- 'filename' => 'site-3.csv'
+ 'filename' => 'site-3.csv',
+ 'content' => ['sort' => 3]
]
],
],
@@ -987,21 +990,23 @@ public function testChangeSortHooks()
'file.changeSort:before' => function (File $file, $position) use ($phpunit, &$calls) {
$phpunit->assertIsFile($file);
$phpunit->assertSame(3, $position);
- $phpunit->assertNull($file->sort()->value());
+ $phpunit->assertSame(1, $file->sort()->value());
$calls++;
},
'file.changeSort:after' => function (File $newFile, File $oldFile) use ($phpunit, &$calls) {
$phpunit->assertIsFile($newFile);
$phpunit->assertIsFile($oldFile);
$phpunit->assertSame(3, $newFile->sort()->value());
- $phpunit->assertNull($oldFile->sort()->value());
+ $phpunit->assertSame(1, $oldFile->sort()->value());
$calls++;
},
]
]);
- $app->site()->file()->changeSort(3);
+ $app->site()->file()->changeSort(1);
+ $this->assertSame(0, $calls);
+ $app->site()->file()->changeSort(3);
$this->assertSame(2, $calls);
}
From f91d4569e521eca518988cde17fa33a524e31fbc Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Mon, 1 Jan 2024 22:31:57 +0100
Subject: [PATCH 009/202] =?UTF-8?q?API=20`files/sort`=20doesn=E2=80=99t=20?=
=?UTF-8?q?return=20whole=20files=20object?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
config/api/routes/files.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/config/api/routes/files.php b/config/api/routes/files.php
index ec53b6b86b..1d67edab58 100644
--- a/config/api/routes/files.php
+++ b/config/api/routes/files.php
@@ -71,10 +71,11 @@
'pattern' => $parentPattern . '/sort',
'method' => 'PATCH',
'action' => function (string $path) {
- return $this->files($path)->changeSort(
+ $this->files($path)->changeSort(
$this->requestBody('files'),
$this->requestBody('index')
);
+ return true;
}
],
[
From b55254e17b08761d121ea5867c974742d0927468 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Mon, 1 Jan 2024 22:41:19 +0100
Subject: [PATCH 010/202] Cache file blueprints for files from same parent
---
src/Cms/File.php | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/Cms/File.php b/src/Cms/File.php
index 6e60ab0d7b..0df495ff66 100644
--- a/src/Cms/File.php
+++ b/src/Cms/File.php
@@ -9,6 +9,7 @@
use Kirby\Filesystem\IsFile;
use Kirby\Panel\File as Panel;
use Kirby\Toolkit\Str;
+use WeakMap;
/**
* The `$file` object provides a set
@@ -157,14 +158,26 @@ public function blueprint(): FileBlueprint
*/
public function blueprints(string $inSection = null): array
{
+ // get cached results for the current file model
+ // (except when collecting for a specific section)
if ($inSection === null && $this->blueprints !== null) {
return $this->blueprints; // @codeCoverageIgnore
}
+ $parent = $this->parent();
+
+ // get cached results from other models that share the same parent
+ // and thus the same available blueprints
+ // (except when collecting for a specific section)
+ static $cache = new WeakMap();
+
+ if ($inSection === null && $cache->offsetExists($parent)) {
+ return $cache->offsetGet($parent); // @codeCoverageIgnore
+ }
+
// always include the current template as option
$template = $this->template() ?? 'default';
$templates = [$template];
- $parent = $this->parent();
// what file templates/blueprints should be considered is
// defined bythe parent's blueprint: which templates it allows
@@ -272,6 +285,8 @@ public function blueprints(string $inSection = null): array
return $blueprints; // @codeCoverageIgnore
}
+ $cache->offsetSet($parent, $blueprints);
+
return $this->blueprints = $blueprints;
}
From 3a533d655af3ad482120bd3ed82046715761fedb Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 18 Jan 2024 22:52:55 +0100
Subject: [PATCH 011/202] `File::blueprints()` w/ `:: acceptedFileTemplates`
---
src/Cms/File.php | 77 +++----------------------------------------
src/Cms/HasFiles.php | 78 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 82 insertions(+), 73 deletions(-)
diff --git a/src/Cms/File.php b/src/Cms/File.php
index 0df495ff66..90675b04c0 100644
--- a/src/Cms/File.php
+++ b/src/Cms/File.php
@@ -164,78 +164,11 @@ public function blueprints(string $inSection = null): array
return $this->blueprints; // @codeCoverageIgnore
}
- $parent = $this->parent();
-
- // get cached results from other models that share the same parent
- // and thus the same available blueprints
- // (except when collecting for a specific section)
- static $cache = new WeakMap();
-
- if ($inSection === null && $cache->offsetExists($parent)) {
- return $cache->offsetGet($parent); // @codeCoverageIgnore
- }
-
// always include the current template as option
- $template = $this->template() ?? 'default';
- $templates = [$template];
-
- // what file templates/blueprints should be considered is
- // defined bythe parent's blueprint: which templates it allows
- // in files sections as well as files fields
- $blueprint = $parent->blueprint();
-
- $fromFields = function ($fields) use (&$fromFields, $parent) {
- $templates = [];
-
- foreach ($fields as $field) {
- // files or textare field
- if (
- $field['type'] === 'files' ||
- $field['type'] === 'textarea'
- ) {
- $uploads = $field['uploads'] ?? null;
-
- // only if the `uploads` parent is the actual parent
- if ($target = $uploads['parent'] ?? null) {
- if ($parent->id() !== $target) {
- continue;
- }
- }
-
- $templates[] = $uploads['template'] ?? 'default';
- continue;
- }
-
- // structure field
- if ($field['type'] === 'structure') {
- $fields = $fromFields($field['fields']);
- $templates = array_merge($templates, $fields);
- continue;
- }
- }
-
- return $templates;
- };
-
- // collect all allowed templates…
- foreach ($blueprint->sections() as $section) {
- // if collecting for a specific section, skip all others
- if ($inSection !== null && $section->name() !== $inSection) {
- continue;
- }
-
- // …from files sections
- if ($section->type() === 'files') {
- $templates[] = $section->template() ?? 'default';
- continue;
- }
-
- // …from fields
- if ($section->type() === 'fields') {
- $fields = $fromFields($section->fields());
- $templates = array_merge($templates, $fields);
- }
- }
+ $templates = [
+ $this->template() ?? 'default',
+ ...$this->parent()->acceptedFileTemplates($inSection)
+ ];
// make sure every template is only included once
$templates = array_unique(array_filter($templates));
@@ -285,8 +218,6 @@ public function blueprints(string $inSection = null): array
return $blueprints; // @codeCoverageIgnore
}
- $cache->offsetSet($parent, $blueprints);
-
return $this->blueprints = $blueprints;
}
diff --git a/src/Cms/HasFiles.php b/src/Cms/HasFiles.php
index 86788d28e5..59b2bfa8a1 100644
--- a/src/Cms/HasFiles.php
+++ b/src/Cms/HasFiles.php
@@ -20,6 +20,84 @@ trait HasFiles
*/
protected Files|array|null $files = null;
+ protected array|null $fileTemplates = null;
+
+ /**
+ * Gathers what file templates are allowed in
+ * this model based on the blueprint
+ */
+ public function acceptedFileTemplates(string $inSection = null): array
+ {
+ // get cached results for the current file model
+ // (except when collecting for a specific section)
+ if ($inSection === null && $this->fileTemplates !== null) {
+ return $this->fileTemplates; // @codeCoverageIgnore
+ }
+
+ $templates = [];
+
+ // collect all allowed file templates from blueprint…
+ foreach ($this->blueprint()->sections() as $section) {
+ // if collecting for a specific section, skip all others
+ if ($inSection !== null && $section->name() !== $inSection) {
+ continue;
+ }
+
+ $templates = match ($section->type()) {
+ 'files' => [...$templates, $section->template() ?? 'default'],
+ 'fields' => [
+ ...$templates,
+ ...$this->acceptedFileTemplatesFromFields($section->fields())
+ ],
+ default => $templates
+ };
+ }
+
+ // no caching for when collecting for specific section
+ if ($inSection !== null) {
+ return $templates; // @codeCoverageIgnore
+ }
+
+ return $this->fileTemplates = $templates;
+ }
+
+ /**
+ * Gathers the allowed file templates from model's fields
+ */
+ protected function acceptedFileTemplatesFromFields(array $fields): array
+ {
+ $templates = [];
+
+ foreach ($fields as $field) {
+ // files or textare field
+ if (
+ $field['type'] === 'files' ||
+ $field['type'] === 'textarea'
+ ) {
+ $uploads = $field['uploads'] ?? null;
+
+ // only if the `uploads` parent is this model
+ if ($target = $uploads['parent'] ?? null) {
+ if ($this->id() !== $target) {
+ continue;
+ }
+ }
+
+ $templates[] = $uploads['template'] ?? 'default';
+ continue;
+ }
+
+ // structure field
+ if ($field['type'] === 'structure') {
+ $fields = $this->acceptedFileTemplatesFromFields($field['fields']);
+ $templates = array_merge($templates, $fields);
+ continue;
+ }
+ }
+
+ return $templates;
+ }
+
/**
* Filters the Files collection by type audio
*/
From cb4d5d6a277fdb5cde93a42eb824b0334e76b136 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Tue, 30 Jan 2024 22:31:26 +0100
Subject: [PATCH 012/202] Move `acceptedFileTemplates()` to blueprint class
---
src/Cms/Blueprint.php | 78 +++++++++++++++++++++++++++++++++++++++++++
src/Cms/File.php | 2 +-
src/Cms/HasFiles.php | 78 -------------------------------------------
3 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/src/Cms/Blueprint.php b/src/Cms/Blueprint.php
index 289ff111ba..757d7ae385 100644
--- a/src/Cms/Blueprint.php
+++ b/src/Cms/Blueprint.php
@@ -34,6 +34,8 @@ class Blueprint
protected $sections = [];
protected $tabs = [];
+ protected array|null $fileTemplates = null;
+
/**
* Magic getter/caller for any blueprint prop
*/
@@ -96,6 +98,82 @@ public function __debugInfo(): array
return $this->props ?? [];
}
+ /**
+ * Gathers what file templates are allowed in
+ * this model based on the blueprint
+ */
+ public function acceptedFileTemplates(string $inSection = null): array
+ {
+ // get cached results for the current file model
+ // (except when collecting for a specific section)
+ if ($inSection === null && $this->fileTemplates !== null) {
+ return $this->fileTemplates; // @codeCoverageIgnore
+ }
+
+ $templates = [];
+
+ // collect all allowed file templates from blueprint…
+ foreach ($this->sections() as $section) {
+ // if collecting for a specific section, skip all others
+ if ($inSection !== null && $section->name() !== $inSection) {
+ continue;
+ }
+
+ $templates = match ($section->type()) {
+ 'files' => [...$templates, $section->template() ?? 'default'],
+ 'fields' => [
+ ...$templates,
+ ...$this->acceptedFileTemplatesFromFields($section->fields())
+ ],
+ default => $templates
+ };
+ }
+
+ // no caching for when collecting for specific section
+ if ($inSection !== null) {
+ return $templates; // @codeCoverageIgnore
+ }
+
+ return $this->fileTemplates = $templates;
+ }
+
+ /**
+ * Gathers the allowed file templates from model's fields
+ */
+ protected function acceptedFileTemplatesFromFields(array $fields): array
+ {
+ $templates = [];
+
+ foreach ($fields as $field) {
+ // files or textare field
+ if (
+ $field['type'] === 'files' ||
+ $field['type'] === 'textarea'
+ ) {
+ $uploads = $field['uploads'] ?? null;
+
+ // only if the `uploads` parent is this model
+ if ($target = $uploads['parent'] ?? null) {
+ if ($this->model->id() !== $target) {
+ continue;
+ }
+ }
+
+ $templates[] = $uploads['template'] ?? 'default';
+ continue;
+ }
+
+ // structure field
+ if ($field['type'] === 'structure') {
+ $fields = $this->acceptedFileTemplatesFromFields($field['fields']);
+ $templates = array_merge($templates, $fields);
+ continue;
+ }
+ }
+
+ return $templates;
+ }
+
/**
* Converts all column definitions, that
* are not wrapped in a tab, into a generic tab
diff --git a/src/Cms/File.php b/src/Cms/File.php
index 90675b04c0..9b1de9ef9d 100644
--- a/src/Cms/File.php
+++ b/src/Cms/File.php
@@ -167,7 +167,7 @@ public function blueprints(string $inSection = null): array
// always include the current template as option
$templates = [
$this->template() ?? 'default',
- ...$this->parent()->acceptedFileTemplates($inSection)
+ ...$this->parent()->blueprint()->acceptedFileTemplates($inSection)
];
// make sure every template is only included once
diff --git a/src/Cms/HasFiles.php b/src/Cms/HasFiles.php
index 59b2bfa8a1..86788d28e5 100644
--- a/src/Cms/HasFiles.php
+++ b/src/Cms/HasFiles.php
@@ -20,84 +20,6 @@ trait HasFiles
*/
protected Files|array|null $files = null;
- protected array|null $fileTemplates = null;
-
- /**
- * Gathers what file templates are allowed in
- * this model based on the blueprint
- */
- public function acceptedFileTemplates(string $inSection = null): array
- {
- // get cached results for the current file model
- // (except when collecting for a specific section)
- if ($inSection === null && $this->fileTemplates !== null) {
- return $this->fileTemplates; // @codeCoverageIgnore
- }
-
- $templates = [];
-
- // collect all allowed file templates from blueprint…
- foreach ($this->blueprint()->sections() as $section) {
- // if collecting for a specific section, skip all others
- if ($inSection !== null && $section->name() !== $inSection) {
- continue;
- }
-
- $templates = match ($section->type()) {
- 'files' => [...$templates, $section->template() ?? 'default'],
- 'fields' => [
- ...$templates,
- ...$this->acceptedFileTemplatesFromFields($section->fields())
- ],
- default => $templates
- };
- }
-
- // no caching for when collecting for specific section
- if ($inSection !== null) {
- return $templates; // @codeCoverageIgnore
- }
-
- return $this->fileTemplates = $templates;
- }
-
- /**
- * Gathers the allowed file templates from model's fields
- */
- protected function acceptedFileTemplatesFromFields(array $fields): array
- {
- $templates = [];
-
- foreach ($fields as $field) {
- // files or textare field
- if (
- $field['type'] === 'files' ||
- $field['type'] === 'textarea'
- ) {
- $uploads = $field['uploads'] ?? null;
-
- // only if the `uploads` parent is this model
- if ($target = $uploads['parent'] ?? null) {
- if ($this->id() !== $target) {
- continue;
- }
- }
-
- $templates[] = $uploads['template'] ?? 'default';
- continue;
- }
-
- // structure field
- if ($field['type'] === 'structure') {
- $fields = $this->acceptedFileTemplatesFromFields($field['fields']);
- $templates = array_merge($templates, $fields);
- continue;
- }
- }
-
- return $templates;
- }
-
/**
* Filters the Files collection by type audio
*/
From a9d1844c0545a9c41377a141f5fc5a9b73695021 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Tue, 30 Jan 2024 22:32:55 +0100
Subject: [PATCH 013/202] Fix cs
---
src/Cms/File.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Cms/File.php b/src/Cms/File.php
index 9b1de9ef9d..41208db6e2 100644
--- a/src/Cms/File.php
+++ b/src/Cms/File.php
@@ -9,7 +9,6 @@
use Kirby\Filesystem\IsFile;
use Kirby\Panel\File as Panel;
use Kirby\Toolkit\Str;
-use WeakMap;
/**
* The `$file` object provides a set
From 3858266c091b6fc648f71d435c63d8a7f0f6a13a Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 31 Jan 2024 11:32:18 +0100
Subject: [PATCH 014/202] Revert breaking change in sort route
---
config/api/routes/files.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/config/api/routes/files.php b/config/api/routes/files.php
index 1d67edab58..ec53b6b86b 100644
--- a/config/api/routes/files.php
+++ b/config/api/routes/files.php
@@ -71,11 +71,10 @@
'pattern' => $parentPattern . '/sort',
'method' => 'PATCH',
'action' => function (string $path) {
- $this->files($path)->changeSort(
+ return $this->files($path)->changeSort(
$this->requestBody('files'),
$this->requestBody('index')
);
- return true;
}
],
[
From ed0bfb697090eb5ad4922d29679c95bb906ff3b6 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 31 Jan 2024 13:47:52 +0100
Subject: [PATCH 015/202] Add unit tests and improve template detection in
fields
---
src/Cms/Blueprint.php | 37 +++--
tests/Cms/Blueprints/BlueprintTest.php | 207 +++++++++++++++++++++++++
2 files changed, 227 insertions(+), 17 deletions(-)
diff --git a/src/Cms/Blueprint.php b/src/Cms/Blueprint.php
index 757d7ae385..3bdfe8e7b9 100644
--- a/src/Cms/Blueprint.php
+++ b/src/Cms/Blueprint.php
@@ -145,26 +145,14 @@ protected function acceptedFileTemplatesFromFields(array $fields): array
$templates = [];
foreach ($fields as $field) {
- // files or textare field
- if (
- $field['type'] === 'files' ||
- $field['type'] === 'textarea'
- ) {
- $uploads = $field['uploads'] ?? null;
-
- // only if the `uploads` parent is this model
- if ($target = $uploads['parent'] ?? null) {
- if ($this->model->id() !== $target) {
- continue;
- }
- }
-
- $templates[] = $uploads['template'] ?? 'default';
+ // fields with uploads settings
+ if (isset($field['uploads']) === true && is_array($field['uploads']) === true) {
+ $templates = array_merge($templates, $this->acceptedFileTemplatesFromFieldUploads($field['uploads']));
continue;
}
- // structure field
- if ($field['type'] === 'structure') {
+ // structure and object fields
+ if (isset($field['fields']) === true && is_array($field['fields']) === true) {
$fields = $this->acceptedFileTemplatesFromFields($field['fields']);
$templates = array_merge($templates, $fields);
continue;
@@ -174,6 +162,21 @@ protected function acceptedFileTemplatesFromFields(array $fields): array
return $templates;
}
+ /**
+ * Extracts templates from field uploads settings
+ */
+ protected function acceptedFileTemplatesFromFieldUploads(array $uploads): array
+ {
+ // only if the `uploads` parent is this model
+ if ($target = $uploads['parent'] ?? null) {
+ if ($this->model->id() !== $target) {
+ return [];
+ }
+ }
+
+ return [($uploads['template'] ?? 'default')];
+ }
+
/**
* Converts all column definitions, that
* are not wrapped in a tab, into a generic tab
diff --git a/tests/Cms/Blueprints/BlueprintTest.php b/tests/Cms/Blueprints/BlueprintTest.php
index fc2711fca3..a1f766f4ff 100644
--- a/tests/Cms/Blueprints/BlueprintTest.php
+++ b/tests/Cms/Blueprints/BlueprintTest.php
@@ -113,6 +113,213 @@ public function testConvertColumnsToTabs()
$this->assertSame($expected['main'], $blueprint->tab());
}
+ /**
+ * @covers ::acceptedFileTemplates
+ */
+ public function testAcceptedFileTemplatesDefault()
+ {
+ $blueprint = new Blueprint([
+ 'model' => $this->model,
+ 'name' => 'default',
+ 'sections' => [
+ 'files' => [
+ 'type' => 'files',
+ ],
+ ]
+ ]);
+
+ $this->assertSame(['default'], $blueprint->acceptedFileTemplates());
+ }
+
+ /**
+ * @covers ::acceptedFileTemplates
+ */
+ public function testAcceptedFileTemplatesFromFields()
+ {
+ $this->app = new App([
+ 'roots' => [
+ 'index' => '/dev/null'
+ ],
+ 'blueprints' => [
+ 'files/a' => [
+ 'name' => 'a',
+ ],
+ 'files/b' => [
+ 'name' => 'b',
+ ],
+ 'files/c' => [
+ 'name' => 'c',
+ ],
+ 'files/d' => [
+ 'name' => 'd',
+ ],
+ ]
+ ]);
+
+ $blueprint = new Blueprint([
+ 'model' => $this->model,
+ 'name' => 'default',
+ 'fields' => [
+ 'a' => [
+ 'type' => 'files',
+ 'uploads' => [
+ 'template' => 'a'
+ ]
+ ],
+ 'b' => [
+ 'type' => 'textarea',
+ 'uploads' => [
+ 'template' => 'b'
+ ]
+ ],
+ 'c' => [
+ 'type' => 'structure',
+ 'fields' => [
+ 'text' => [
+ 'type' => 'textarea',
+ 'uploads' => [
+ 'template' => 'c'
+ ]
+ ]
+ ]
+ ],
+ 'd' => [
+ 'type' => 'object',
+ 'fields' => [
+ 'text' => [
+ 'type' => 'object',
+ 'uploads' => [
+ 'template' => 'd'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $this->assertSame(['a', 'b', 'c', 'd'], $blueprint->acceptedFileTemplates());
+ }
+
+ /**
+ * @covers ::acceptedFileTemplates
+ */
+ public function testAcceptedFileTemplatesFromFieldsAndSections()
+ {
+ $this->app = new App([
+ 'roots' => [
+ 'index' => '/dev/null'
+ ],
+ 'blueprints' => [
+ 'files/a' => [
+ 'name' => 'a',
+ ],
+ 'files/b' => [
+ 'name' => 'b',
+ ],
+ 'files/c' => [
+ 'name' => 'c',
+ ],
+ ]
+ ]);
+
+ $blueprint = new Blueprint([
+ 'model' => $this->model,
+ 'name' => 'default',
+ 'sections' => [
+ 'fields' => [
+ 'type' => 'fields',
+ 'fields' => [
+ 'a' => [
+ 'type' => 'files',
+ 'uploads' => [
+ 'template' => 'a'
+ ]
+ ],
+ 'b' => [
+ 'type' => 'textarea',
+ 'uploads' => [
+ 'template' => 'b'
+ ]
+ ],
+ ],
+ ],
+ 'files' => [
+ 'type' => 'files',
+ 'template' => 'c'
+ ]
+ ]
+ ]);
+
+ $this->assertSame(['a', 'b', 'c'], $blueprint->acceptedFileTemplates());
+ }
+
+ /**
+ * @covers ::acceptedFileTemplates
+ */
+ public function testAcceptedFileTemplatesFromSection()
+ {
+ $this->app = new App([
+ 'roots' => [
+ 'index' => '/dev/null'
+ ],
+ 'blueprints' => [
+ 'files/a' => [
+ 'name' => 'a',
+ ]
+ ]
+ ]);
+
+ $blueprint = new Blueprint([
+ 'model' => $this->model,
+ 'name' => 'default',
+ 'sections' => [
+ 'a' => [
+ 'type' => 'files',
+ 'template' => 'a'
+ ],
+ ]
+ ]);
+
+ $this->assertSame(['a'], $blueprint->acceptedFileTemplates('a'));
+ }
+
+ /**
+ * @covers ::acceptedFileTemplates
+ */
+ public function testAcceptedFileTemplatesFromSections()
+ {
+ $this->app = new App([
+ 'roots' => [
+ 'index' => '/dev/null'
+ ],
+ 'blueprints' => [
+ 'files/a' => [
+ 'name' => 'a',
+ ],
+ 'files/b' => [
+ 'name' => 'b',
+ ],
+ ]
+ ]);
+
+ $blueprint = new Blueprint([
+ 'model' => $this->model,
+ 'name' => 'default',
+ 'sections' => [
+ 'a' => [
+ 'type' => 'files',
+ 'template' => 'a'
+ ],
+ 'b' => [
+ 'type' => 'files',
+ 'template' => 'b'
+ ]
+ ]
+ ]);
+
+ $this->assertSame(['a', 'b'], $blueprint->acceptedFileTemplates());
+ }
+
/**
* @covers ::__debugInfo
*/
From f599d5cbf2870a8dae14425bcdce89d2bc29628d Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 5 Feb 2024 12:25:01 +0100
Subject: [PATCH 016/202] Gather templates from fieldsets
---
src/Cms/Blueprint.php | 23 +++++++++++++++++++++++
tests/Cms/Blueprints/BlueprintTest.php | 20 +++++++++++++++++++-
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/src/Cms/Blueprint.php b/src/Cms/Blueprint.php
index 3bdfe8e7b9..34a3f0ca5c 100644
--- a/src/Cms/Blueprint.php
+++ b/src/Cms/Blueprint.php
@@ -157,6 +157,29 @@ protected function acceptedFileTemplatesFromFields(array $fields): array
$templates = array_merge($templates, $fields);
continue;
}
+
+ // layout and blocks fields
+ if (isset($field['fieldsets']) === true && is_array($field['fieldsets']) === true) {
+ $fieldsets = $this->acceptedFileTemplatesFromFieldsets($field['fieldsets']);
+ $templates = array_merge($templates, $fieldsets);
+ continue;
+ }
+ }
+
+ return $templates;
+ }
+
+ /**
+ * Gathers the allowed file templates from fieldsets
+ */
+ protected function acceptedFileTemplatesFromFieldsets(array $fieldsets): array
+ {
+ $templates = [];
+
+ foreach ($fieldsets as $fieldset) {
+ foreach (($fieldset['tabs'] ?? []) as $tab) {
+ $templates = array_merge($templates, $this->acceptedFileTemplatesFromFields($tab['fields'] ?? []));
+ }
}
return $templates;
diff --git a/tests/Cms/Blueprints/BlueprintTest.php b/tests/Cms/Blueprints/BlueprintTest.php
index a1f766f4ff..978f2bfe0d 100644
--- a/tests/Cms/Blueprints/BlueprintTest.php
+++ b/tests/Cms/Blueprints/BlueprintTest.php
@@ -153,6 +153,9 @@ public function testAcceptedFileTemplatesFromFields()
'files/d' => [
'name' => 'd',
],
+ 'files/e' => [
+ 'name' => 'e',
+ ],
]
]);
@@ -193,11 +196,26 @@ public function testAcceptedFileTemplatesFromFields()
]
]
]
+ ],
+ 'e' => [
+ 'type' => 'blocks',
+ 'fieldsets' => [
+ 'text' => [
+ 'fields' => [
+ 'text' => [
+ 'type' => 'object',
+ 'uploads' => [
+ 'template' => 'e'
+ ]
+ ]
+ ]
+ ]
+ ]
]
]
]);
- $this->assertSame(['a', 'b', 'c', 'd'], $blueprint->acceptedFileTemplates());
+ $this->assertSame(['a', 'b', 'c', 'd', 'e'], $blueprint->acceptedFileTemplates());
}
/**
From 99b5601be573f88918cba9f1fa056841fa1d0e30 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 5 Feb 2024 12:30:07 +0100
Subject: [PATCH 017/202] Clean up merges
---
src/Cms/Blueprint.php | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/Cms/Blueprint.php b/src/Cms/Blueprint.php
index 34a3f0ca5c..c20d7edcf6 100644
--- a/src/Cms/Blueprint.php
+++ b/src/Cms/Blueprint.php
@@ -147,21 +147,28 @@ protected function acceptedFileTemplatesFromFields(array $fields): array
foreach ($fields as $field) {
// fields with uploads settings
if (isset($field['uploads']) === true && is_array($field['uploads']) === true) {
- $templates = array_merge($templates, $this->acceptedFileTemplatesFromFieldUploads($field['uploads']));
+ $templates = [
+ ...$templates,
+ ...$this->acceptedFileTemplatesFromFieldUploads($field['uploads'])
+ ];
continue;
}
// structure and object fields
if (isset($field['fields']) === true && is_array($field['fields']) === true) {
- $fields = $this->acceptedFileTemplatesFromFields($field['fields']);
- $templates = array_merge($templates, $fields);
+ $templates = [
+ ...$templates,
+ ...$this->acceptedFileTemplatesFromFields($field['fields']),
+ ];
continue;
}
// layout and blocks fields
if (isset($field['fieldsets']) === true && is_array($field['fieldsets']) === true) {
- $fieldsets = $this->acceptedFileTemplatesFromFieldsets($field['fieldsets']);
- $templates = array_merge($templates, $fieldsets);
+ $templates = [
+ ...$templates,
+ ...$this->acceptedFileTemplatesFromFieldsets($field['fieldsets'])
+ ];
continue;
}
}
From df5976b2d44fecd3db936b62491fa1e2c3e86b95 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 31 Jan 2024 11:29:44 +0100
Subject: [PATCH 018/202] Section API routes
---
config/api/routes/files.php | 9 +++++++++
config/api/routes/pages.php | 11 +++++++++--
config/api/routes/site.php | 10 ++++++++--
config/api/routes/users.php | 10 ++++++++++
src/Cms/Api.php | 23 +++++++++++++++++++++++
src/Cms/Section.php | 16 ++++++++++++++++
6 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/config/api/routes/files.php b/config/api/routes/files.php
index ec53b6b86b..6dd8fc74c8 100644
--- a/config/api/routes/files.php
+++ b/config/api/routes/files.php
@@ -25,6 +25,15 @@
}
}
],
+ [
+ 'pattern' => $filePattern . '/fields/(:any)/(:all?)',
+ 'method' => 'ALL',
+ 'action' => function (string $parent, string $filename, string $sectionName, string $path = null) {
+ if ($file = $this->file($parent, $filename)) {
+ return $this->sectionApi($file, $sectionName, $path);
+ }
+ }
+ ],
[
'pattern' => $parentPattern,
'method' => 'GET',
diff --git a/config/api/routes/pages.php b/config/api/routes/pages.php
index bb91f6e4fd..84e9876b77 100644
--- a/config/api/routes/pages.php
+++ b/config/api/routes/pages.php
@@ -4,8 +4,6 @@
/**
* Page Routes
*/
-
-
return [
[
'pattern' => 'pages/(:any)',
@@ -117,4 +115,13 @@
}
}
],
+ [
+ 'pattern' => 'pages/(:any)/sections/(:any)/(:all?)',
+ 'method' => 'ALL',
+ 'action' => function (string $id, string $sectionName, string $path = null) {
+ if ($page = $this->page($id)) {
+ return $this->sectionApi($page, $sectionName, $path);
+ }
+ }
+ ],
];
diff --git a/config/api/routes/site.php b/config/api/routes/site.php
index e2e34f225f..70e1752982 100644
--- a/config/api/routes/site.php
+++ b/config/api/routes/site.php
@@ -97,6 +97,12 @@
'action' => function (string $fieldName, string $path = null) {
return $this->fieldApi($this->site(), $fieldName, $path);
}
- ]
-
+ ],
+ [
+ 'pattern' => 'site/sections/(:any)/(:all?)',
+ 'method' => 'ALL',
+ 'action' => function (string $sectionName, string $path = null) {
+ return $this->sectionApi($this->site(), $sectionName, $path);
+ }
+ ],
];
diff --git a/config/api/routes/users.php b/config/api/routes/users.php
index 0f97f2b145..f443f1065e 100644
--- a/config/api/routes/users.php
+++ b/config/api/routes/users.php
@@ -208,4 +208,14 @@ function ($source, $filename) use ($id) {
return $this->fieldApi($this->user($id), $fieldName, $path);
}
],
+ [
+ 'pattern' => [
+ '(account)/sections/(:any)/(:all?)',
+ 'users/(:any)/sections/(:any)/(:all?)',
+ ],
+ 'method' => 'ALL',
+ 'action' => function (string $id, string $sectionName, string $path = null) {
+ return $this->sectionApi($this->user($id), $sectionName, $path);
+ }
+ ],
];
diff --git a/src/Cms/Api.php b/src/Cms/Api.php
index 04e4d759de..a5ce610319 100644
--- a/src/Cms/Api.php
+++ b/src/Cms/Api.php
@@ -185,6 +185,29 @@ public function searchPages(string|null $parent = null): Pages
return $pages->query($this->requestBody());
}
+ /**
+ * @throws \Kirby\Exception\NotFoundException if the section type cannot be found or the section cannot be loaded
+ */
+ public function sectionApi(
+ ModelWithContent $model,
+ string $name,
+ string|null $path = null
+ ): mixed {
+
+ $section = $model->blueprint()?->section($name);
+
+ $sectionApi = $this->clone([
+ 'data' => array_merge($this->data(), ['section' => $section]),
+ 'routes' => $section->api(),
+ ]);
+
+ return $sectionApi->call(
+ $path,
+ $this->requestMethod(),
+ $this->requestData()
+ );
+ }
+
/**
* Returns the current Session instance
*
diff --git a/src/Cms/Section.php b/src/Cms/Section.php
index 56402be063..42ee388a79 100644
--- a/src/Cms/Section.php
+++ b/src/Cms/Section.php
@@ -2,6 +2,7 @@
namespace Kirby\Cms;
+use Closure;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Toolkit\Component;
@@ -46,6 +47,21 @@ public function __construct(string $type, array $attrs = [])
parent::__construct($type, $attrs);
}
+ /**
+ * Returns field api call
+ */
+ public function api(): mixed
+ {
+ if (
+ isset($this->options['api']) === true &&
+ $this->options['api'] instanceof Closure
+ ) {
+ return $this->options['api']->call($this);
+ }
+
+ return null;
+ }
+
public function errors(): array
{
if (array_key_exists('errors', $this->methods) === true) {
From 8fc9ebcc5f2a6a7742e11677b9d2e6dfc8ee5706 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 31 Jan 2024 11:29:53 +0100
Subject: [PATCH 019/202] New sort API for the files section
---
config/sections/files.php | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/config/sections/files.php b/config/sections/files.php
index 8dd9090af5..6b0a35c6d4 100644
--- a/config/sections/files.php
+++ b/config/sections/files.php
@@ -205,6 +205,21 @@
];
}
],
+ 'api' => function () {
+ return [
+ [
+ 'pattern' => 'sort',
+ 'action' => function () {
+ $this->section()->model()->files()->changeSort(
+ $this->requestBody('files'),
+ $this->requestBody('index')
+ );
+
+ return true;
+ }
+ ]
+ ];
+ },
'toArray' => function () {
return [
'data' => $this->data,
From b202ba7a062d1e0daf79fdcb0cdbaec580b61d48 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 31 Jan 2024 11:41:18 +0100
Subject: [PATCH 020/202] Use PATCH for the sort endpoint and change the API
URL
---
config/sections/files.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/config/sections/files.php b/config/sections/files.php
index 6b0a35c6d4..d56b58f867 100644
--- a/config/sections/files.php
+++ b/config/sections/files.php
@@ -209,6 +209,7 @@
return [
[
'pattern' => 'sort',
+ 'method' => 'PATCH',
'action' => function () {
$this->section()->model()->files()->changeSort(
$this->requestBody('files'),
@@ -226,7 +227,7 @@
'errors' => $this->errors,
'options' => [
'accept' => $this->accept,
- 'apiUrl' => $this->parent->apiUrl(true),
+ 'apiUrl' => $this->parent->apiUrl(true) . '/sections/' . $this->name,
'columns' => $this->columnsWithTypes(),
'empty' => $this->empty,
'headline' => $this->headline,
From 8a72bef44d65b8d1e25d5a1664e3249b90053b97 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 31 Jan 2024 11:42:08 +0100
Subject: [PATCH 021/202] Use the new API URL to sort files
---
panel/src/components/Sections/FilesSection.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/panel/src/components/Sections/FilesSection.vue b/panel/src/components/Sections/FilesSection.vue
index 31835b7807..a611f31665 100644
--- a/panel/src/components/Sections/FilesSection.vue
+++ b/panel/src/components/Sections/FilesSection.vue
@@ -89,7 +89,7 @@ export default {
this.isProcessing = true;
try {
- await this.$api.patch(this.options.apiUrl + "/files/sort", {
+ await this.$api.patch(this.options.apiUrl + "/sort", {
files: items.map((item) => item.id),
index: this.pagination.offset
});
From 33f748b44e33eb392a136521c8d2a7bae6c96f43 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 5 Feb 2024 16:12:56 +0100
Subject: [PATCH 022/202] Fix cs issue
---
src/Cms/Api.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/Cms/Api.php b/src/Cms/Api.php
index a5ce610319..be46ae050b 100644
--- a/src/Cms/Api.php
+++ b/src/Cms/Api.php
@@ -193,7 +193,6 @@ public function sectionApi(
string $name,
string|null $path = null
): mixed {
-
$section = $model->blueprint()?->section($name);
$sectionApi = $this->clone([
From 9dd7d26ce631bf9f736ebe79013d0daa27486c29 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 5 Feb 2024 16:57:23 +0100
Subject: [PATCH 023/202] Clean up routes for section and field APIs
---
config/api/routes/files.php | 21 ++++++++++-----------
config/api/routes/pages.php | 18 +++++++++---------
config/api/routes/site.php | 16 ++++++++--------
config/api/routes/users.php | 22 +++++++++++-----------
4 files changed, 38 insertions(+), 39 deletions(-)
diff --git a/config/api/routes/files.php b/config/api/routes/files.php
index 6dd8fc74c8..7cf1073611 100644
--- a/config/api/routes/files.php
+++ b/config/api/routes/files.php
@@ -8,27 +8,26 @@
* Files Routes
*/
return [
-
- [
- 'pattern' => $filePattern . '/sections/(:any)',
- 'method' => 'GET',
- 'action' => function (string $path, string $filename, string $sectionName) {
- return $this->file($path, $filename)->blueprint()->section($sectionName)?->toResponse();
- }
- ],
[
'pattern' => $filePattern . '/fields/(:any)/(:all?)',
'method' => 'ALL',
- 'action' => function (string $parent, string $filename, string $fieldName, string $path = null) {
+ 'action' => function (string $parent, string $filename, string $fieldName, string|null $path = null) {
if ($file = $this->file($parent, $filename)) {
return $this->fieldApi($file, $fieldName, $path);
}
}
],
[
- 'pattern' => $filePattern . '/fields/(:any)/(:all?)',
+ 'pattern' => $filePattern . '/sections/(:any)',
+ 'method' => 'GET',
+ 'action' => function (string $path, string $filename, string $sectionName) {
+ return $this->file($path, $filename)->blueprint()->section($sectionName)?->toResponse();
+ }
+ ],
+ [
+ 'pattern' => $filePattern . '/sections/(:any)/(:all?)',
'method' => 'ALL',
- 'action' => function (string $parent, string $filename, string $sectionName, string $path = null) {
+ 'action' => function (string $parent, string $filename, string $sectionName, string|null $path = null) {
if ($file = $this->file($parent, $filename)) {
return $this->sectionApi($file, $sectionName, $path);
}
diff --git a/config/api/routes/pages.php b/config/api/routes/pages.php
index 84e9876b77..1e7e262655 100644
--- a/config/api/routes/pages.php
+++ b/config/api/routes/pages.php
@@ -99,26 +99,26 @@
return $this->page($id)->changeTitle($this->requestBody('title'));
}
],
- [
- 'pattern' => 'pages/(:any)/sections/(:any)',
- 'method' => 'GET',
- 'action' => function (string $id, string $sectionName) {
- return $this->page($id)->blueprint()->section($sectionName)?->toResponse();
- }
- ],
[
'pattern' => 'pages/(:any)/fields/(:any)/(:all?)',
'method' => 'ALL',
- 'action' => function (string $id, string $fieldName, string $path = null) {
+ 'action' => function (string $id, string $fieldName, string|null $path = null) {
if ($page = $this->page($id)) {
return $this->fieldApi($page, $fieldName, $path);
}
}
],
+ [
+ 'pattern' => 'pages/(:any)/sections/(:any)',
+ 'method' => 'GET',
+ 'action' => function (string $id, string $sectionName) {
+ return $this->page($id)->blueprint()->section($sectionName)?->toResponse();
+ }
+ ],
[
'pattern' => 'pages/(:any)/sections/(:any)/(:all?)',
'method' => 'ALL',
- 'action' => function (string $id, string $sectionName, string $path = null) {
+ 'action' => function (string $id, string $sectionName, string|null $path = null) {
if ($page = $this->page($id)) {
return $this->sectionApi($page, $sectionName, $path);
}
diff --git a/config/api/routes/site.php b/config/api/routes/site.php
index 70e1752982..9ab4827765 100644
--- a/config/api/routes/site.php
+++ b/config/api/routes/site.php
@@ -84,6 +84,13 @@
return $pages->query($this->requestBody());
}
],
+ [
+ 'pattern' => 'site/fields/(:any)/(:all?)',
+ 'method' => 'ALL',
+ 'action' => function (string $fieldName, string|null $path = null) {
+ return $this->fieldApi($this->site(), $fieldName, $path);
+ }
+ ],
[
'pattern' => 'site/sections/(:any)',
'method' => 'GET',
@@ -91,17 +98,10 @@
return $this->site()->blueprint()->section($sectionName)?->toResponse();
}
],
- [
- 'pattern' => 'site/fields/(:any)/(:all?)',
- 'method' => 'ALL',
- 'action' => function (string $fieldName, string $path = null) {
- return $this->fieldApi($this->site(), $fieldName, $path);
- }
- ],
[
'pattern' => 'site/sections/(:any)/(:all?)',
'method' => 'ALL',
- 'action' => function (string $sectionName, string $path = null) {
+ 'action' => function (string $sectionName, string|null $path = null) {
return $this->sectionApi($this->site(), $sectionName, $path);
}
],
diff --git a/config/api/routes/users.php b/config/api/routes/users.php
index f443f1065e..5cf9d581f2 100644
--- a/config/api/routes/users.php
+++ b/config/api/routes/users.php
@@ -186,6 +186,16 @@ function ($source, $filename) use ($id) {
return $this->user($id)->roles();
}
],
+ [
+ 'pattern' => [
+ '(account)/fields/(:any)/(:all?)',
+ 'users/(:any)/fields/(:any)/(:all?)',
+ ],
+ 'method' => 'ALL',
+ 'action' => function (string $id, string $fieldName, string|null $path = null) {
+ return $this->fieldApi($this->user($id), $fieldName, $path);
+ }
+ ],
[
'pattern' => [
'(account)/sections/(:any)',
@@ -198,23 +208,13 @@ function ($source, $filename) use ($id) {
}
}
],
- [
- 'pattern' => [
- '(account)/fields/(:any)/(:all?)',
- 'users/(:any)/fields/(:any)/(:all?)',
- ],
- 'method' => 'ALL',
- 'action' => function (string $id, string $fieldName, string $path = null) {
- return $this->fieldApi($this->user($id), $fieldName, $path);
- }
- ],
[
'pattern' => [
'(account)/sections/(:any)/(:all?)',
'users/(:any)/sections/(:any)/(:all?)',
],
'method' => 'ALL',
- 'action' => function (string $id, string $sectionName, string $path = null) {
+ 'action' => function (string $id, string $sectionName, string|null $path = null) {
return $this->sectionApi($this->user($id), $sectionName, $path);
}
],
From 629cb648c15c54f77e207cb6310d4c21cc706e44 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 5 Feb 2024 16:58:55 +0100
Subject: [PATCH 024/202] Remove array_merge
---
src/Cms/Api.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Cms/Api.php b/src/Cms/Api.php
index be46ae050b..89dc736403 100644
--- a/src/Cms/Api.php
+++ b/src/Cms/Api.php
@@ -71,7 +71,7 @@ public function fieldApi(
$field = Form::for($model)->field($name);
$fieldApi = $this->clone([
- 'data' => array_merge($this->data(), ['field' => $field]),
+ 'data' => [...$this->data(), 'field' => $field],
'routes' => $field->api(),
]);
@@ -196,7 +196,7 @@ public function sectionApi(
$section = $model->blueprint()?->section($name);
$sectionApi = $this->clone([
- 'data' => array_merge($this->data(), ['section' => $section]),
+ 'data' => [...$this->data(), 'section' => $section],
'routes' => $section->api(),
]);
From c818b89b1d6ee83785cba2f6d95dd0cc91294477 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Mon, 5 Feb 2024 18:48:15 +0100
Subject: [PATCH 025/202] Add unit test
---
tests/Cms/Sections/SectionTest.php | 33 ++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/tests/Cms/Sections/SectionTest.php b/tests/Cms/Sections/SectionTest.php
index 7b3b38571f..e50ce64e68 100644
--- a/tests/Cms/Sections/SectionTest.php
+++ b/tests/Cms/Sections/SectionTest.php
@@ -28,6 +28,39 @@ public function tearDown(): void
Section::$types = $this->sectionTypes;
}
+ public function testApi()
+ {
+ // no defined as default
+ Section::$types = [
+ 'test' => []
+ ];
+
+ $model = new Page(['slug' => 'test']);
+
+ $section = new Section('test', [
+ 'model' => $model,
+ ]);
+
+ $this->assertNull($section->api());
+
+ // return simple string
+ Section::$types = [
+ 'test' => [
+ 'api' => function () {
+ return 'Hello World';
+ }
+ ]
+ ];
+
+ $model = new Page(['slug' => 'test']);
+
+ $section = new Section('test', [
+ 'model' => $model,
+ ]);
+
+ $this->assertSame('Hello World', $section->api());
+ }
+
public function testMissingModel()
{
Section::$types['test'] = [];
From c1704325808cfd62c9facd7365369529a2c0935e Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 12:18:34 +0100
Subject: [PATCH 026/202] Proper error handling if the section does not exist
---
src/Cms/Api.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Cms/Api.php b/src/Cms/Api.php
index 89dc736403..49dcac9f84 100644
--- a/src/Cms/Api.php
+++ b/src/Cms/Api.php
@@ -193,7 +193,9 @@ public function sectionApi(
string $name,
string|null $path = null
): mixed {
- $section = $model->blueprint()?->section($name);
+ if (!$section = $model->blueprint()?->section($name)) {
+ throw new NotFoundException('The section "' . $name . '" could not be found');
+ }
$sectionApi = $this->clone([
'data' => [...$this->data(), 'section' => $section],
From 91534d2d2bfe9495143de807b5b80942fd6eaef3 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 12:18:51 +0100
Subject: [PATCH 027/202] Always start with a fresh set of sections and fields
---
src/Cms/AppPlugins.php | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/Cms/AppPlugins.php b/src/Cms/AppPlugins.php
index 350d93db38..5971f2148f 100644
--- a/src/Cms/AppPlugins.php
+++ b/src/Cms/AppPlugins.php
@@ -659,6 +659,11 @@ protected function extensionsFromProps(array $props): void
*/
protected function extensionsFromSystem(): void
{
+ // Always start with fresh fields and sections
+ // from the core and add plugins on top of that
+ FormField::$types = [];
+ Section::$types = [];
+
// mixins
FormField::$mixins = $this->core->fieldMixins();
Section::$mixins = $this->core->sectionMixins();
@@ -674,8 +679,8 @@ protected function extensionsFromSystem(): void
$this->extendCacheTypes($this->core->cacheTypes());
$this->extendComponents($this->core->components());
$this->extendBlueprints($this->core->blueprints());
- $this->extendFields($this->core->fields());
$this->extendFieldMethods($this->core->fieldMethods());
+ $this->extendFields($this->core->fields());
$this->extendSections($this->core->sections());
$this->extendSnippets($this->core->snippets());
$this->extendTags($this->core->kirbyTags());
From 632660e6bd05d23ce49cfa381dfe6149b67fe0d2 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 12:19:02 +0100
Subject: [PATCH 028/202] Additional unit tests for the section api
---
tests/Cms/Api/ApiTest.php | 64 +++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/tests/Cms/Api/ApiTest.php b/tests/Cms/Api/ApiTest.php
index a8fd9b91f1..75263425d2 100644
--- a/tests/Cms/Api/ApiTest.php
+++ b/tests/Cms/Api/ApiTest.php
@@ -658,4 +658,68 @@ public function testRenderExceptionWithDebugging()
$this->assertInstanceOf(Response::class, $result);
$this->assertSame(json_encode($expected), $result->body());
}
+
+ public function testSectionApi()
+ {
+ $app = $this->app->clone([
+ 'sections' => [
+ 'test' => [
+ 'api' => function () {
+ return [
+ [
+ 'pattern' => '/message',
+ 'action' => function () {
+ return [
+ 'message' => 'Test'
+ ];
+ }
+ ]
+ ];
+ }
+ ]
+ ],
+ 'blueprints' => [
+ 'pages/test' => [
+ 'title' => 'Test',
+ 'name' => 'test',
+ 'sections' => [
+ 'test' => [
+ 'type' => 'test',
+ ]
+ ]
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'template' => 'test',
+ ]
+ ]
+ ]
+ ]);
+
+ $app->impersonate('kirby');
+ $page = $app->page('test');
+
+ $response = $app->api()->sectionApi($page, 'test', 'message');
+ $this->assertSame('Test', $response['message']);
+ }
+
+ public function testSectionApiWithInvalidSection()
+ {
+ $app = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ ['slug' => 'test']
+ ]
+ ]
+ ]);
+
+ $this->expectException(NotFoundException::class);
+ $this->expectExceptionMessage('The section "nonexists" could not be found');
+
+ $page = $app->page('test');
+ $app->api()->sectionApi($page, 'nonexists');
+ }
}
From b0c0f7dde143ee0e8946c772a296239a5d7e8db9 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 12:32:05 +0100
Subject: [PATCH 029/202] Improve unit tests after the the sections and fields
are being reset
---
.../Fields/Mixins/PagePickerMixinTest.php | 126 +++++++++---------
1 file changed, 65 insertions(+), 61 deletions(-)
diff --git a/tests/Form/Fields/Mixins/PagePickerMixinTest.php b/tests/Form/Fields/Mixins/PagePickerMixinTest.php
index 8bbd3c2166..64cf47b945 100644
--- a/tests/Form/Fields/Mixins/PagePickerMixinTest.php
+++ b/tests/Form/Fields/Mixins/PagePickerMixinTest.php
@@ -19,18 +19,17 @@ public function setUp(): void
public function testPagesWithoutParent()
{
- Field::$types = [
- 'test' => [
- 'mixins' => ['pagepicker'],
- 'methods' => [
- 'pages' => function () {
- return $this->pagepicker();
- }
- ]
- ]
- ];
-
$app = $this->app->clone([
+ 'fields' => [
+ 'test' => [
+ 'mixins' => ['pagepicker'],
+ 'methods' => [
+ 'pages' => function () {
+ return $this->pagepicker();
+ }
+ ]
+ ]
+ ],
'site' => [
'children' => [
['slug' => 'a'],
@@ -65,20 +64,19 @@ public function testPagesWithoutParent()
public function testPagesWithParent()
{
- Field::$types = [
- 'test' => [
- 'mixins' => ['pagepicker'],
- 'methods' => [
- 'pages' => function () {
- return $this->pagepicker([
- 'parent' => 'a'
- ]);
- }
- ]
- ]
- ];
-
$app = $this->app->clone([
+ 'fields' => [
+ 'test' => [
+ 'mixins' => ['pagepicker'],
+ 'methods' => [
+ 'pages' => function () {
+ return $this->pagepicker([
+ 'parent' => 'a'
+ ]);
+ }
+ ]
+ ]
+ ],
'site' => [
'children' => [
[
@@ -116,18 +114,20 @@ public function testPagesWithParent()
public function testPageChildren()
{
- Field::$types = [
- 'test' => [
- 'mixins' => ['pagepicker'],
- 'methods' => [
- 'pages' => function () {
- return $this->pagepicker([
- 'query' => 'page.children'
- ]);
- }
+ $this->app->clone([
+ 'fields' => [
+ 'test' => [
+ 'mixins' => ['pagepicker'],
+ 'methods' => [
+ 'pages' => function () {
+ return $this->pagepicker([
+ 'query' => 'page.children'
+ ]);
+ }
+ ]
]
- ]
- ];
+ ],
+ ]);
$page = new Page([
'slug' => 'test',
@@ -166,19 +166,21 @@ public function testPageChildren()
public function testPageChildrenWithoutSubpages()
{
- Field::$types = [
- 'test' => [
- 'mixins' => ['pagepicker'],
- 'methods' => [
- 'pages' => function () {
- return $this->pagepicker([
- 'query' => 'page.children',
- 'subpages' => false
- ]);
- }
+ $this->app->clone([
+ 'fields' => [
+ 'test' => [
+ 'mixins' => ['pagepicker'],
+ 'methods' => [
+ 'pages' => function () {
+ return $this->pagepicker([
+ 'query' => 'page.children',
+ 'subpages' => false
+ ]);
+ }
+ ]
]
- ]
- ];
+ ],
+ ]);
$page = new Page([
'slug' => 'test',
@@ -213,21 +215,23 @@ public function testPageChildrenWithoutSubpages()
public function testMap()
{
- Field::$types = [
- 'test' => [
- 'mixins' => ['pagepicker'],
- 'methods' => [
- 'pages' => function () {
- return $this->pagepicker([
- 'query' => 'page.children',
- 'map' => function ($page) {
- return $page->id();
- }
- ]);
- }
+ $this->app->clone([
+ 'fields' => [
+ 'test' => [
+ 'mixins' => ['pagepicker'],
+ 'methods' => [
+ 'pages' => function () {
+ return $this->pagepicker([
+ 'query' => 'page.children',
+ 'map' => function ($page) {
+ return $page->id();
+ }
+ ]);
+ }
+ ]
]
- ]
- ];
+ ],
+ ]);
$page = new Page([
'slug' => 'test',
From 66ef4532a98813cd0ea39567eb544f60224d1cee Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 12:33:51 +0100
Subject: [PATCH 030/202] Fix CS issue
---
tests/Form/Fields/Mixins/PagePickerMixinTest.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/Form/Fields/Mixins/PagePickerMixinTest.php b/tests/Form/Fields/Mixins/PagePickerMixinTest.php
index 64cf47b945..bd51252302 100644
--- a/tests/Form/Fields/Mixins/PagePickerMixinTest.php
+++ b/tests/Form/Fields/Mixins/PagePickerMixinTest.php
@@ -3,7 +3,6 @@
namespace Kirby\Form\Fields;
use Kirby\Cms\Page;
-use Kirby\Form\Field;
class PagePickerMixinTest extends TestCase
{
From 2ecec90d7dfffbb78649d4c74a306c41d8e88ba3 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 13:29:06 +0100
Subject: [PATCH 031/202] Ignore code coverage for the new files section API
---
config/sections/files.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/config/sections/files.php b/config/sections/files.php
index d56b58f867..d269152384 100644
--- a/config/sections/files.php
+++ b/config/sections/files.php
@@ -205,6 +205,7 @@
];
}
],
+ // @codeCoverageIgnoreStart
'api' => function () {
return [
[
@@ -221,6 +222,7 @@
]
];
},
+ // @codeCoverageIgnoreEnd
'toArray' => function () {
return [
'data' => $this->data,
From 3d59963745462a5a95429b3650451afd4ff94f59 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Tue, 6 Feb 2024 14:41:54 +0100
Subject: [PATCH 032/202] Ignore routes in test coverage
---
config/api/routes/pages.php | 2 ++
config/api/routes/site.php | 3 ++-
config/api/routes/users.php | 2 ++
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/config/api/routes/pages.php b/config/api/routes/pages.php
index 1e7e262655..6de9c1a328 100644
--- a/config/api/routes/pages.php
+++ b/config/api/routes/pages.php
@@ -5,6 +5,7 @@
* Page Routes
*/
return [
+ // @codeCoverageIgnoreStart
[
'pattern' => 'pages/(:any)',
'method' => 'GET',
@@ -124,4 +125,5 @@
}
}
],
+ // @codeCoverageIgnoreEnd
];
diff --git a/config/api/routes/site.php b/config/api/routes/site.php
index 9ab4827765..abc2ac5f07 100644
--- a/config/api/routes/site.php
+++ b/config/api/routes/site.php
@@ -5,7 +5,7 @@
* Site Routes
*/
return [
-
+ // @codeCoverageIgnoreStart
[
'pattern' => 'site',
'action' => function () {
@@ -105,4 +105,5 @@
return $this->sectionApi($this->site(), $sectionName, $path);
}
],
+ // @codeCoverageIgnoreEnd
];
diff --git a/config/api/routes/users.php b/config/api/routes/users.php
index 5cf9d581f2..cfc3f8088c 100644
--- a/config/api/routes/users.php
+++ b/config/api/routes/users.php
@@ -6,6 +6,7 @@
* User Routes
*/
return [
+ // @codeCoverageIgnoreStart
[
'pattern' => 'users',
'method' => 'GET',
@@ -218,4 +219,5 @@ function ($source, $filename) use ($id) {
return $this->sectionApi($this->user($id), $sectionName, $path);
}
],
+ // @codeCoverageIgnoreEnd
];
From 48b60f7bc62dc44be73edc8fdeb7ec2d33e9d7bc Mon Sep 17 00:00:00 2001
From: Ahmet Bora
Date: Mon, 18 Sep 2023 14:50:20 +0300
Subject: [PATCH 033/202] `prefers-color-scheme` for custom panel favicons
---
panel/public/apple-touch-icon-dark.png | Bin 0 -> 1106 bytes
panel/public/favicon-dark.png | Bin 0 -> 416 bytes
src/Panel/Assets.php | 63 +++++++++++---
tests/Panel/AssetsTest.php | 109 +++++++++++++++++++++----
views/panel.php | 5 +-
5 files changed, 144 insertions(+), 33 deletions(-)
create mode 100644 panel/public/apple-touch-icon-dark.png
create mode 100644 panel/public/favicon-dark.png
diff --git a/panel/public/apple-touch-icon-dark.png b/panel/public/apple-touch-icon-dark.png
new file mode 100644
index 0000000000000000000000000000000000000000..6952b59f259a7b57e367fc1d1916f97b48139d76
GIT binary patch
literal 1106
zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD8Ax&oe*=;XO9OmDT!HleK@WEPeH;pOs98yn
zUogW0fd>utU;li_;Cy{sM~?01k(m-x3c@V5Up;@S#$A1Xe`mSqlZ2>1LuD!6MbGYU
zXkM{txv%%O{d3kbFfglmx;TbZ+%uF5X}+N?7diC%mrmYoN%xix1_`U368{
zdG0eqKXG5ifhmqGn{&%-61O+*ytB}GY5wh6t#cP{ES0?%xbix~g0SU9;)h($=W4B8
z*{XkSi|f+AJeOHikKH@g(R*J)o7KRx_*uZq-VgnO{awb{ha^@{f0E?qt@n1i=$Qw;
zD?)aO`EA%GswK?7{ri=l(q9aYNj_%RntDz+Z*^t-(n~*%nA=H*torVI=YspHCy$>0
zKCrf8W%;~J)yfO{zpqdIJNv5s&rRVwZfNaXu;BL1&cL~*o6j!H%Hn%D{a@ooVTHvD
z4uA0vvVXmC(hb(wo!eL0L|xFao#Ol_V20G6s+)VCoU@z%+39?n-)rXNrM&AlX&RPA
zI8V0Fy-(_)_-(N*t1bmHcOjpg!|pYBUaE5)nI
zhU>q4J$KT)7k`C%dNB4($SxlH~m
zsAuqMGMnq<$sGR$eLW5@I@#QwU%`IqKt|E_W0J3BGc!!0?=q;f+!Z_9t2TFWtH|pY
z6WrV+pqTB^hj3qCV`77$|0LubbL&1%Kx3G+S;XdJ9ksT#U&RnEJHD>T+^SIi}Gw^NDMN36EXP5Em5_OrlSw>ek$iG1X{t$r%`
z(^O5TxW_kVlxf{fOFk6y_=x_ZOJ3S*w_NgCuXp$Dz6IP$dlmof3y8{G8k}kDV?RNx
z`RS(#oE|CHrp$cR`fT}3&(aKah0NdUE-TJ^u3xQp#!Ya`Zr0qBj=ww3JX7D2%$;j&
zT>bb$+rJcU#rmzS6OP|@YFOuI@ZENqx7OcU&!zl(moVL3)3}b=uzbdX?(hq_hA+CL
mi}m?;`EcBA5D|ofpGQRd%X~ZIixlKQrG%%epUXO@geCw?@?VPp
literal 0
HcmV?d00001
diff --git a/panel/public/favicon-dark.png b/panel/public/favicon-dark.png
new file mode 100644
index 0000000000000000000000000000000000000000..dcf5e582e9ad387f5d38ce5ab89e02df74468ec5
GIT binary patch
literal 416
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyX#qYVu0Z-f?ZMRfnJa)cDV7BJ
z1v4!8!0k{e@ZHL}1%TrB_SaTu*Uf=WI+3e|=x4xgAq}zI7h8_=dtx{Hln$fMo_FIKnB^$48
zbLMw+n!@tI>GxgzpdXhN)#Wn_W$!snDGB1*GSO;}`_mixpXYGZuHo4(v};1d^W`ib
z+%FmY;wVeJd*Z;^U-<{@zTa4)_CRUwQ?(~^4qatq2ow-yGGJ@aVdi11%DFdDi#J;5
zW}beV?k5}Z2*K4C@)th%Cp4j)_2=95Y4c~>N<4dVWAW4T^Yr=RZTIcT`8)sT9nk~w
T&+k|P{lwtu>gTe~DWM4f__*m5
literal 0
HcmV?d00001
diff --git a/src/Panel/Assets.php b/src/Panel/Assets.php
index 5e02a59dfc..9eb64db67a 100644
--- a/src/Panel/Assets.php
+++ b/src/Panel/Assets.php
@@ -121,35 +121,72 @@ public function external(): array
* Returns array of favicon icons
* based on config option
*
+ * @todo Deprecate `url` option in v5, use `href` option instead
+ * @todo Deprecate `rel` usage as array key in v5, use `rel` option instead
+ *
* @throws \Kirby\Exception\InvalidArgumentException
*/
public function favicons(): array
{
$icons = $this->kirby->option('panel.favicon', [
- 'apple-touch-icon' => [
- 'type' => 'image/png',
- 'url' => $this->url . '/apple-touch-icon.png',
+ [
+ 'rel' => 'apple-touch-icon',
+ 'type' => 'image/png',
+ 'href' => Url::to($this->url . '/apple-touch-icon.png')
+ ],
+ [
+ 'rel' => 'alternate icon',
+ 'type' => 'image/png',
+ 'href' => $this->url . '/favicon.png'
],
- 'alternate icon' => [
- 'type' => 'image/png',
- 'url' => $this->url . '/favicon.png',
+ [
+ 'rel' => 'shortcut icon',
+ 'type' => 'image/svg+xml',
+ 'href' => $this->url . '/favicon.svg'
+ ],
+ [
+ 'rel' => 'apple-touch-icon',
+ 'type' => 'image/png',
+ 'href' => $this->url . '/apple-touch-icon-dark.png',
+ 'media' => '(prefers-color-scheme: dark)'
],
- 'shortcut icon' => [
- 'type' => 'image/svg+xml',
- 'url' => $this->url . '/favicon.svg',
+ [
+ 'rel' => 'alternate icon',
+ 'type' => 'image/png',
+ 'href' => $this->url . '/favicon-dark.png',
+ 'media' => '(prefers-color-scheme: dark)'
]
]);
if (is_array($icons) === true) {
- return $icons;
+ // normalize options
+ foreach ($icons as $rel => &$icon) {
+ // TODO: remove this backward compatibility check in v6
+ if (isset($icon['url']) === true) {
+ $icon['href'] = $icon['url'];
+ unset($icon['url']);
+ }
+
+ // TODO: remove this backward compatibility check in v6
+ if (is_string($rel) === true && isset($icon['rel']) === false) {
+ $icon['rel'] = $rel;
+ }
+
+ $icon['href'] = Url::to($icon['href']);
+ $icon['nonce'] = $this->nonce;
+ }
+
+ return array_values($icons);
}
// make sure to convert favicon string to array
if (is_string($icons) === true) {
return [
- 'shortcut icon' => [
- 'type' => F::mime($icons),
- 'url' => $icons,
+ [
+ 'rel' => 'shortcut icon',
+ 'type' => F::mime($icons),
+ 'href' => Url::to($icons),
+ 'nonce' => $this->nonce
]
];
}
diff --git a/tests/Panel/AssetsTest.php b/tests/Panel/AssetsTest.php
index baaec1658a..f52925b338 100644
--- a/tests/Panel/AssetsTest.php
+++ b/tests/Panel/AssetsTest.php
@@ -214,9 +214,11 @@ public function testFavicons(): void
$favicons = $assets->favicons();
// icons
- $this->assertSame($base . '/apple-touch-icon.png', $favicons['apple-touch-icon']['url']);
- $this->assertSame($base . '/favicon.svg', $favicons['shortcut icon']['url']);
- $this->assertSame($base . '/favicon.png', $favicons['alternate icon']['url']);
+ $this->assertSame($base . '/apple-touch-icon.png', $favicons[0]['href']);
+ $this->assertSame($base . '/favicon.png', $favicons[1]['href']);
+ $this->assertSame($base . '/favicon.svg', $favicons[2]['href']);
+ $this->assertSame($base . '/apple-touch-icon-dark.png', $favicons[3]['href']);
+ $this->assertSame($base . '/favicon-dark.png', $favicons[4]['href']);
}
/**
@@ -230,9 +232,11 @@ public function testFaviconsInDevMode(): void
$base = 'http://sandbox.test:3000';
$favicons = $assets->favicons();
- $this->assertSame($base . '/apple-touch-icon.png', $favicons['apple-touch-icon']['url']);
- $this->assertSame($base . '/favicon.svg', $favicons['shortcut icon']['url']);
- $this->assertSame($base . '/favicon.png', $favicons['alternate icon']['url']);
+ $this->assertSame($base . '/apple-touch-icon.png', $favicons[0]['href']);
+ $this->assertSame($base . '/favicon.png', $favicons[1]['href']);
+ $this->assertSame($base . '/favicon.svg', $favicons[2]['href']);
+ $this->assertSame($base . '/apple-touch-icon-dark.png', $favicons[3]['href']);
+ $this->assertSame($base . '/favicon-dark.png', $favicons[4]['href']);
}
/**
@@ -245,13 +249,15 @@ public function testFaviconsWithCustomArraySetup(): void
'options' => [
'panel' => [
'favicon' => [
- 'shortcut icon' => [
+ [
+ 'rel' => 'shortcut icon',
'type' => 'image/svg+xml',
- 'url' => 'assets/my-favicon.svg',
+ 'href' => 'assets/my-favicon.svg',
],
- 'alternate icon' => [
+ [
+ 'rel' => 'alternate icon',
'type' => 'image/png',
- 'url' => 'assets/my-favicon.png',
+ 'href' => 'assets/my-favicon.png',
]
]
]
@@ -263,8 +269,8 @@ public function testFaviconsWithCustomArraySetup(): void
$favicons = $assets->favicons();
// icons
- $this->assertSame('assets/my-favicon.svg', $favicons['shortcut icon']['url']);
- $this->assertSame('assets/my-favicon.png', $favicons['alternate icon']['url']);
+ $this->assertSame('/assets/my-favicon.svg', $favicons[0]['href']);
+ $this->assertSame('/assets/my-favicon.png', $favicons[1]['href']);
}
/**
@@ -286,8 +292,9 @@ public function testFaviconsWithCustomStringSetup(): void
$favicons = $assets->favicons();
// icons
- $this->assertSame('image/x-icon', $favicons['shortcut icon']['type']);
- $this->assertSame('assets/favicon.ico', $favicons['shortcut icon']['url']);
+ $this->assertSame('shortcut icon', $favicons[0]['rel']);
+ $this->assertSame('image/x-icon', $favicons[0]['type']);
+ $this->assertSame('/assets/favicon.ico', $favicons[0]['href']);
}
/**
@@ -325,9 +332,77 @@ public function testFaviconsWithCustomUrl(): void
$favicons = $assets->favicons();
// favicons
- $this->assertSame($base . '/apple-touch-icon.png', $favicons['apple-touch-icon']['url']);
- $this->assertSame($base . '/favicon.svg', $favicons['shortcut icon']['url']);
- $this->assertSame($base . '/favicon.png', $favicons['alternate icon']['url']);
+ $this->assertSame($base . '/apple-touch-icon.png', $favicons[0]['href']);
+ $this->assertSame($base . '/favicon.png', $favicons[1]['href']);
+ $this->assertSame($base . '/favicon.svg', $favicons[2]['href']);
+ }
+
+ /**
+ * @todo Remove backward compatibility part test in v5
+ */
+ public function testFaviconsWithRelIndex(): void
+ {
+ // array
+ $this->app->clone([
+ 'options' => [
+ 'panel' => [
+ 'favicon' => [
+ 'shortcut icon' => [
+ 'type' => 'image/svg+xml',
+ 'url' => 'assets/my-favicon.svg',
+ ],
+ 'alternate icon' => [
+ 'type' => 'image/png',
+ 'url' => 'assets/my-favicon.png',
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ // default asset setup
+ $assets = new Assets();
+ $favicons = $assets->favicons();
+
+ // icons
+ $this->assertSame('shortcut icon', $favicons[0]['rel']);
+ $this->assertSame('/assets/my-favicon.svg', $favicons[0]['href']);
+ $this->assertSame('alternate icon', $favicons[1]['rel']);
+ $this->assertSame('/assets/my-favicon.png', $favicons[1]['href']);
+ }
+
+ /**
+ * @todo Remove backward compatibility part test in v5
+ */
+ public function testFaviconsWithUrlOption(): void
+ {
+ // array
+ $this->app->clone([
+ 'options' => [
+ 'panel' => [
+ 'favicon' => [
+ [
+ 'rel' => 'shortcut icon',
+ 'type' => 'image/svg+xml',
+ 'url' => 'assets/my-favicon.svg',
+ ],
+ [
+ 'rel' => 'alternate icon',
+ 'type' => 'image/png',
+ 'url' => 'assets/my-favicon.png',
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ // default asset setup
+ $assets = new Assets();
+ $favicons = $assets->favicons();
+
+ // icons
+ $this->assertSame('/assets/my-favicon.svg', $favicons[0]['href']);
+ $this->assertSame('/assets/my-favicon.png', $favicons[1]['href']);
}
/**
diff --git a/views/panel.php b/views/panel.php
index b82eba4f17..4638fb8511 100644
--- a/views/panel.php
+++ b/views/panel.php
@@ -1,6 +1,5 @@
" rel="stylesheet" href="= $css ?>">
- $icon): ?>
-
+
+ = Html::tag('link', null, $icon) ?>
From 7e83d9cdf787e21448b7fcf1d8382a7d85f36649 Mon Sep 17 00:00:00 2001
From: Ahmet Bora
Date: Tue, 26 Sep 2023 15:07:54 +0300
Subject: [PATCH 034/202] Update dark apple-touch-icon
---
panel/public/apple-touch-icon-dark.png | Bin 1106 -> 1148 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/panel/public/apple-touch-icon-dark.png b/panel/public/apple-touch-icon-dark.png
index 6952b59f259a7b57e367fc1d1916f97b48139d76..321598b9dd0244c8d5488bc932ba41a61f248207 100644
GIT binary patch
delta 1127
zcmV-t1ep8M2>b|;B!ALSOjJbx00960|Dd3t5D*aH;NXCOfCU8wKtMqK{r&p-`W_x0
z7#JAN&dz6NX9)=j>gwv2mX>^cd{$OgM@L5t3=H%0^Y8EP-QC^U+1bCpzp${dkB^Uc
zcXu~8HzXt^_4W0rsHl^ZlPxVR6%`ft_xJJf@#N&>)z#I>$$!bk#l@PMnu&>tZ*Om4
zU|?EWT1-q#J3BiuF)=78C>k0X!otGl=H}AU(u0G8a&mG~Qc^1`E4R0|?Ck8hxw*8o
zw4R=xYinyzP*6fbLOwn|jEsybDk^bUT}l7|17%4>K~#9!?AVD;;!qfd;qRkTp+IG;
zEP{%N;(`K#2!G=4{a@20WZIq#ATYLYn*7fdyiLyzA%qY@2qA$a^kwHxywLRiewwb6
zoDEIo_q@u3j0u>T1G@I|&{6NoD@=YHm@&SSbY1nJn}5_>!po~3!*g7vEAf_sPRyF)
zwOtkfRpF8@r)EMMCt0~{(2lr*VT2Cf+M=d$LT~T7*9;)BBE0Y)hpJ$s`shRah(#r(9U}V+V
zwfUUQ8h_X}^=Fqpu(prVk^vPyb;oGc%+2c(&+!q|W9zPML<7#kssD~KU!)#cJH_DN|j$f-Q
z*M^%SLXkNL{9WMgLK)f!-j{MsjoS!_9apZxUw;T#j-FuOx~x-ratM|;Yua4|tlReH
zb~w?)4noiwh8Z2!953F47;PXVhD1xWL`$?pOSDAqB-%2uHq+81I$q9WP5E+MmuNCw
zz#0l^Qln_HQpXDQ3aME%S)JeqlPalUG!rokOIWc4^^7KyjT9D0HIk&Z(WEmn=7L5J
zseg4eIjz}H*tIFCeKa}DnEo5n$S;}K3Um_zDJ=<+&dr73C$-#h(Tr{b5^w{Cr
zPR5!<|7qupaS()}AZXNxN<&3MVnivaiHWuMzmir2KPs45yfHH;n2!I#?k>(%Gf%mx
z@+j}=2l*WBU6IE*0($KU<$a{fW&FYzvwvM4Vx3z(`(pQ2IogdlrM*4g;vKfn+Sk!n
z<`nW8&xX{gbe#_rkh0;nZJ(f1Z^ap7%SS}Bl
zfJA0ZnW?F(kl1==WrcDJA{Ic6Ub+WbsAwwKLRhd4yX7TRWJ_F%@L
z4gF*bp?tN4P{!LrfUZt3_dWV0mE;w)szNWRKsRfWb)YWGI>I^-bB77Kcm>@SgRZzS
t_wu02gwPF05fKp)5fKp)5fPD3+yRY4Qf2hT%)utU;li_;Cy{sM~?01k(m-x3c@V5Up;@S#$A1Xe`mSqlZ2>1LuD!6MbGYU
zXkM{txv%%O{d3kbFfglmx;TbZ+%uF5X}+N?7diC%mrmYoN%xix1_`U368{
zdG0eqKXG5ifhmqGn{&%-61O+*ytB}GY5wh6t#cP{ES0?%xbix~g0SU9;)h($=W4B8
z*{XkSi|f+AJeOHikKH@g(R*J)o7KRx_*uZq-VgnO{awb{ha^@{f0E?qt@n1i=$Qw;
zD?)aO`EA%GswK?7{ri=l(q9aYNj_%RntDz+Z*^t-(n~*%nA=H*torVI=YspHCy$>0
zKCrf8W%;~J)yfO{zpqdIJNv5s&rRVwZfNaXu;BL1&cL~*o6j!H%Hn%D{a@ooVTHvD
z4uA0vvVXmC(hb(wo!eL0L|xFao#Ol_V20G6s+)VCoU@z%+39?n-)rXNrM&AlX&RPA
zI8V0Fy-(_)_-(N*t1bmHcOjpg!|pYBUaE5)nI
zhU>q4J$KT)7k`C%dNB4($SxlH~m
zsAuqMGMnq<$sGR$eLW5@I@#QwU%`IqKt|E_W0J3BGc!!0?=q;f+!Z_9t2TFWtH|pY
z6WrV+pqTB^hj3qCV`77$|0LubbL&1%Kx3G+S;XdJ9ksT#U&RnEJHD>T+^SIi}Gw^NDMN36EXP5Em5_OrlSw>ek$iG1X{t$r%`
z(^O5TxW_kVlxf{fOFk6y_=x_ZOJ3S*w_NgCuXp$Dz6IP$dlmof3y8{G8k}kDV?RNx
z`RS(#oE|CHrp$cR`fT}3&(aKah0NdUE-TJ^u3xQp#!Ya`Zr0qBj=ww3JX7D2%$;j&
zT>bb$+rJcU#rmzS6OP|@YFOuI@ZENqx7OcU&!zl(moVL3)3}b=uzbdX?(hq_hA+CL
mi}m?;`EcBA5D|ofpGQRd%X~ZIixlKQrG%%epUXO@geCw?@?VPp
From 87729386eb21caf8f4d9ba4724d7db546429a997 Mon Sep 17 00:00:00 2001
From: Ahmet Bora
Date: Tue, 26 Sep 2023 23:29:23 +0300
Subject: [PATCH 035/202] Update src/Panel/Assets.php
Co-authored-by: Lukas Bestle
---
src/Panel/Assets.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Panel/Assets.php b/src/Panel/Assets.php
index 9eb64db67a..808026b430 100644
--- a/src/Panel/Assets.php
+++ b/src/Panel/Assets.php
@@ -132,7 +132,7 @@ public function favicons(): array
[
'rel' => 'apple-touch-icon',
'type' => 'image/png',
- 'href' => Url::to($this->url . '/apple-touch-icon.png')
+ 'href' => $this->url . '/apple-touch-icon.png'
],
[
'rel' => 'alternate icon',
From feb0dbab684b3db552cc5adc3b937909466d1cf5 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 8 Feb 2024 13:27:38 +0100
Subject: [PATCH 036/202] Upgrade to vite 5.1
---
panel/package-lock.json | 116 ++++++++++++++++++++--------------------
panel/package.json | 8 +--
panel/vite.config.mjs | 3 +-
3 files changed, 64 insertions(+), 63 deletions(-)
diff --git a/panel/package-lock.json b/panel/package-lock.json
index e7014202d9..c9eba93abc 100644
--- a/panel/package-lock.json
+++ b/panel/package-lock.json
@@ -31,11 +31,11 @@
"glob": "^10.3.10",
"jsdom": "^23.2.0",
"prettier": "^3.2.4",
- "rollup-plugin-external-globals": "^0.9.1",
+ "rollup-plugin-external-globals": "^0.9.2",
"terser": "^5.27.0",
- "vite": "^5.0.12",
- "vite-plugin-static-copy": "^1.0.0",
- "vitest": "^1.2.1",
+ "vite": "^5.1.0",
+ "vite-plugin-static-copy": "^1.0.1",
+ "vitest": "^1.2.2",
"vue-docgen-api": "^4.75.1",
"vue-template-compiler": "^2.7.16"
}
@@ -704,9 +704,9 @@
}
},
"node_modules/@rollup/pluginutils": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
- "integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+ "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0",
@@ -924,13 +924,13 @@
}
},
"node_modules/@vitest/expect": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.1.tgz",
- "integrity": "sha512-/bqGXcHfyKgFWYwIgFr1QYDaR9e64pRKxgBNWNXPefPFRhgm+K3+a/dS0cUGEreWngets3dlr8w8SBRw2fCfFQ==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.2.tgz",
+ "integrity": "sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==",
"dev": true,
"dependencies": {
- "@vitest/spy": "1.2.1",
- "@vitest/utils": "1.2.1",
+ "@vitest/spy": "1.2.2",
+ "@vitest/utils": "1.2.2",
"chai": "^4.3.10"
},
"funding": {
@@ -938,12 +938,12 @@
}
},
"node_modules/@vitest/runner": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.1.tgz",
- "integrity": "sha512-zc2dP5LQpzNzbpaBt7OeYAvmIsRS1KpZQw4G3WM/yqSV1cQKNKwLGmnm79GyZZjMhQGlRcSFMImLjZaUQvNVZQ==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.2.tgz",
+ "integrity": "sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==",
"dev": true,
"dependencies": {
- "@vitest/utils": "1.2.1",
+ "@vitest/utils": "1.2.2",
"p-limit": "^5.0.0",
"pathe": "^1.1.1"
},
@@ -979,9 +979,9 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.1.tgz",
- "integrity": "sha512-Tmp/IcYEemKaqAYCS08sh0vORLJkMr0NRV76Gl8sHGxXT5151cITJCET20063wk0Yr/1koQ6dnmP6eEqezmd/Q==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.2.tgz",
+ "integrity": "sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==",
"dev": true,
"dependencies": {
"magic-string": "^0.30.5",
@@ -999,9 +999,9 @@
"dev": true
},
"node_modules/@vitest/snapshot/node_modules/magic-string": {
- "version": "0.30.5",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
- "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
+ "version": "0.30.7",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
+ "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -1011,9 +1011,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.1.tgz",
- "integrity": "sha512-vG3a/b7INKH7L49Lbp0IWrG6sw9j4waWAucwnksPB1r1FTJgV7nkBByd9ufzu6VWya/QTvQW4V9FShZbZIB2UQ==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.2.tgz",
+ "integrity": "sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==",
"dev": true,
"dependencies": {
"tinyspy": "^2.2.0"
@@ -1023,9 +1023,9 @@
}
},
"node_modules/@vitest/utils": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.1.tgz",
- "integrity": "sha512-bsH6WVZYe/J2v3+81M5LDU8kW76xWObKIURpPrOXm2pjBniBu2MERI/XP60GpS4PHU3jyK50LUutOwrx4CyHUg==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.2.tgz",
+ "integrity": "sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==",
"dev": true,
"dependencies": {
"diff-sequences": "^29.6.3",
@@ -3600,9 +3600,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "version": "8.4.35",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
+ "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
"funding": [
{
"type": "opencollective",
@@ -4097,12 +4097,12 @@
}
},
"node_modules/rollup-plugin-external-globals": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/rollup-plugin-external-globals/-/rollup-plugin-external-globals-0.9.1.tgz",
- "integrity": "sha512-A5bxaS1ZxswieycelVGdEjvV2FqA24IGY1ya17ZpshLoncDjyWR508hzUWOtGYIjr1t5PRu/zVRXmu1KBlJxlw==",
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-external-globals/-/rollup-plugin-external-globals-0.9.2.tgz",
+ "integrity": "sha512-BUzbNhcN20irgWFNOL9XYSAN8pVRL7BfyZJce7oJMxjgPuxMOlQo3oTp3LRH1ehddXQEnp0/XxglMisl/GhnJQ==",
"dev": true,
"dependencies": {
- "@rollup/pluginutils": "^5.0.5",
+ "@rollup/pluginutils": "^5.1.0",
"estree-walker": "^3.0.3",
"is-reference": "^3.0.2",
"magic-string": "^0.30.5"
@@ -4487,9 +4487,9 @@
"dev": true
},
"node_modules/tinypool": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz",
- "integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==",
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz",
+ "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==",
"dev": true,
"engines": {
"node": ">=14.0.0"
@@ -4674,13 +4674,13 @@
"dev": true
},
"node_modules/vite": {
- "version": "5.0.12",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
- "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.0.tgz",
+ "integrity": "sha512-STmSFzhY4ljuhz14bg9LkMTk3d98IO6DIArnTY6MeBwiD1Za2StcQtz7fzOUnRCqrHSD5+OS2reg4HOz1eoLnw==",
"dev": true,
"dependencies": {
"esbuild": "^0.19.3",
- "postcss": "^8.4.32",
+ "postcss": "^8.4.35",
"rollup": "^4.2.0"
},
"bin": {
@@ -4729,9 +4729,9 @@
}
},
"node_modules/vite-node": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.1.tgz",
- "integrity": "sha512-fNzHmQUSOY+y30naohBvSW7pPn/xn3Ib/uqm+5wAJQJiqQsU0NBR78XdRJb04l4bOFKjpTWld0XAfkKlrDbySg==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.2.tgz",
+ "integrity": "sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==",
"dev": true,
"dependencies": {
"cac": "^6.7.14",
@@ -4751,9 +4751,9 @@
}
},
"node_modules/vite-plugin-static-copy": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.0.tgz",
- "integrity": "sha512-kMlrB3WDtC5GzFedNIPkpjnOAr8M11PfWOiUaONrUZ3AqogTsOmIhTt6w7Fh311wl8pN81ld7sfuOEogFJ9N8A==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.1.tgz",
+ "integrity": "sha512-3eGL4mdZoPJMDBT68pv/XKIHR4MgVolStIxxv1gIBP4R8TpHn9C9EnaU0hesqlseJ4ycLGUxckFTu/jpuJXQlA==",
"dev": true,
"dependencies": {
"chokidar": "^3.5.3",
@@ -4783,16 +4783,16 @@
}
},
"node_modules/vitest": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.1.tgz",
- "integrity": "sha512-TRph8N8rnSDa5M2wKWJCMnztCZS9cDcgVTQ6tsTFTG/odHJ4l5yNVqvbeDJYJRZ6is3uxaEpFs8LL6QM+YFSdA==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.2.tgz",
+ "integrity": "sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==",
"dev": true,
"dependencies": {
- "@vitest/expect": "1.2.1",
- "@vitest/runner": "1.2.1",
- "@vitest/snapshot": "1.2.1",
- "@vitest/spy": "1.2.1",
- "@vitest/utils": "1.2.1",
+ "@vitest/expect": "1.2.2",
+ "@vitest/runner": "1.2.2",
+ "@vitest/snapshot": "1.2.2",
+ "@vitest/spy": "1.2.2",
+ "@vitest/utils": "1.2.2",
"acorn-walk": "^8.3.2",
"cac": "^6.7.14",
"chai": "^4.3.10",
@@ -4805,9 +4805,9 @@
"std-env": "^3.5.0",
"strip-literal": "^1.3.0",
"tinybench": "^2.5.1",
- "tinypool": "^0.8.1",
+ "tinypool": "^0.8.2",
"vite": "^5.0.0",
- "vite-node": "1.2.1",
+ "vite-node": "1.2.2",
"why-is-node-running": "^2.2.2"
},
"bin": {
diff --git a/panel/package.json b/panel/package.json
index edac85c120..5a16c9df82 100644
--- a/panel/package.json
+++ b/panel/package.json
@@ -36,11 +36,11 @@
"glob": "^10.3.10",
"jsdom": "^23.2.0",
"prettier": "^3.2.4",
- "rollup-plugin-external-globals": "^0.9.1",
+ "rollup-plugin-external-globals": "^0.9.2",
"terser": "^5.27.0",
- "vite": "^5.0.12",
- "vite-plugin-static-copy": "^1.0.0",
- "vitest": "^1.2.1",
+ "vite": "^5.1.0",
+ "vite-plugin-static-copy": "^1.0.1",
+ "vitest": "^1.2.2",
"vue-docgen-api": "^4.75.1",
"vue-template-compiler": "^2.7.16"
},
diff --git a/panel/vite.config.mjs b/panel/vite.config.mjs
index 4cab22b88f..f7270d3894 100644
--- a/panel/vite.config.mjs
+++ b/panel/vite.config.mjs
@@ -69,7 +69,8 @@ export default defineConfig(({ command }) => {
},
optimizeDeps: {
entries: "src/**/*.{js,vue}",
- exclude: ["vitest", "vue"]
+ exclude: ["vitest", "vue"],
+ holdUntilCrawlEnd: false
},
resolve: {
alias: {
From 2d97c9c4867d014c0f34a04d2a4b88601b355780 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Fri, 9 Feb 2024 16:25:09 +0100
Subject: [PATCH 037/202] implement acceptAttribute method
---
config/fields/mixins/upload.php | 2 +-
config/sections/files.php | 2 +-
src/Cms/FileBlueprint.php | 78 +++++++++++++++++++++++++++++++++
src/Filesystem/Mime.php | 23 ++++++++--
4 files changed, 99 insertions(+), 6 deletions(-)
diff --git a/config/fields/mixins/upload.php b/config/fields/mixins/upload.php
index 700cef9ccb..aad39338e4 100644
--- a/config/fields/mixins/upload.php
+++ b/config/fields/mixins/upload.php
@@ -39,7 +39,7 @@
'template' => $template
]);
- $uploads['accept'] = $file->blueprint()->acceptMime();
+ $uploads['accept'] = $file->blueprint()->acceptAttribute();
}
return $uploads;
diff --git a/config/sections/files.php b/config/sections/files.php
index d269152384..bb8532fb5d 100644
--- a/config/sections/files.php
+++ b/config/sections/files.php
@@ -47,7 +47,7 @@
'template' => $this->template
]);
- return $file->blueprint()->acceptMime();
+ return $file->blueprint()->acceptAttribute();
}
return null;
diff --git a/src/Cms/FileBlueprint.php b/src/Cms/FileBlueprint.php
index 6d6bfed515..ca0306ae13 100644
--- a/src/Cms/FileBlueprint.php
+++ b/src/Cms/FileBlueprint.php
@@ -57,6 +57,8 @@ public function accept(): array
/**
* Returns the list of all accepted MIME types for
* file upload or `*` if all MIME types are allowed
+ *
+ * @deprecated 4.2.0 Use `acceptAttribute` instead
*/
public function acceptMime(): string
{
@@ -116,6 +118,82 @@ public function acceptMime(): string
return '*';
}
+
+ /**
+ * Returns the list of all accepted file extensions
+ * for file upload or `*` if all extensions are allowed
+ *
+ * If a mime type is specified in the blueprint, the extensions and types options are ignored for the browser.
+ * Extensions and Types, however, are still used to validate an uploaded file on the server.
+ * This behavior might change in the future to better represent what file extensions are actually allowed.
+ *
+ * If no mime type is specified, the intersection between manually defined extensions and the Kirby "file types" is returned.
+ * If the intersection is empty, an empty string is returned.
+ * This behavior might change in the future to instead return the union of mime, extensions and types.
+ *
+ * @since 4.2.0
+ * @return string
+ */
+ public function acceptAttribute(): string
+ {
+ // don't disclose the specific default types
+ if ($this->defaultTypes === true) {
+ return '*';
+ }
+
+ $accept = $this->accept();
+
+ // get extensions from "mime" option
+ if (is_array($accept['mime']) === true) {
+ // determine the extensions for each MIME type
+ $extensions = array_map(
+ fn($pattern) => Mime::toExtensions($pattern, true),
+ $accept['mime']
+ );
+
+ $fromMime = array_unique(array_merge(...$extensions));
+
+ // return early to ignore the other options
+ return implode(',', array_map(fn($ext) => ".$ext", $fromMime));
+ }
+
+ $restrictions = [];
+
+ // get extensions from "type" option
+ if (is_array($accept['type']) === true) {
+ $extensions = array_map(
+ F::typeToExtensions(...),
+ $accept['type']
+ );
+
+ // F::typeToExtensions might return null instead of empty arrays,
+ // we need to filter those out
+ $fromType = array_merge(...array_filter($extensions));
+ $restrictions[] = $fromType;
+ }
+
+ // get extensions from "extension" option
+ if (is_array($accept['extension']) === true) {
+ $fromExtension = $accept['extension'];
+ $restrictions[] = $fromExtension;
+ }
+
+ // intersect all restrictions
+ if (count($restrictions) > 1) {
+ $list = array_intersect(...$restrictions);
+ } else {
+ $list = $restrictions[0];
+ }
+
+ $list = array_unique($list);
+
+ // format the list to include a leading dot on each extension
+ return implode(',', array_map(fn($ext) => ".$ext", $list));
+
+ // unknown restrictions, accept everything
+ return '*';
+ }
+
protected function normalizeAccept(mixed $accept = null): array
{
$accept = match (true) {
diff --git a/src/Filesystem/Mime.php b/src/Filesystem/Mime.php
index 61bf3dc28a..00accb8f45 100644
--- a/src/Filesystem/Mime.php
+++ b/src/Filesystem/Mime.php
@@ -2,6 +2,7 @@
namespace Kirby\Filesystem;
+use Kirby\Toolkit\A;
use Kirby\Toolkit\Str;
use SimpleXMLElement;
@@ -268,17 +269,31 @@ public static function toExtension(string $mime = null): string|false
/**
* Returns all available extensions for a given MIME type
*/
- public static function toExtensions(string $mime = null): array
+ public static function toExtensions(string $mime = null, bool $matchWildcards = false): array
{
$extensions = [];
+ $testMime = fn (string $v) => static::matches($v, $mime);
foreach (static::$types as $key => $value) {
- if (is_array($value) === true && in_array($mime, $value) === true) {
- $extensions[] = $key;
+ $isArray = is_array($value) === true;
+
+ if ($matchWildcards === true) {
+ if ($isArray === true && A::some($value, $testMime)) {
+ $extensions[] = $key;
+ }
+
+ if ($isArray === false && $testMime($value) === true) {
+ $extensions[] = $key;
+ }
+
continue;
}
- if ($value === $mime) {
+ if ($isArray === true && in_array($mime, $value) === true) {
+ $extensions[] = $key;
+ }
+
+ if ($isArray === false && $value === $mime) {
$extensions[] = $key;
}
}
From e0c630ae1b8fe584a2c990ecc1c11f2c25013f4f Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 11:57:10 +0100
Subject: [PATCH 038/202] Lab: add styling for invalid inputs
---
panel/src/components/Lab/PlaygroundView.vue | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/panel/src/components/Lab/PlaygroundView.vue b/panel/src/components/Lab/PlaygroundView.vue
index 85006ca62e..e5fe4b7d64 100644
--- a/panel/src/components/Lab/PlaygroundView.vue
+++ b/panel/src/components/Lab/PlaygroundView.vue
@@ -126,6 +126,11 @@ export default {
margin-bottom: 0;
}
+.k-lab-input-examples .k-lab-example-canvas:has(:invalid) {
+ outline: 2px solid var(--color-red-500);
+ outline-offset: -2px;
+}
+
.k-lab-input-examples-focus .k-lab-example-canvas > .k-button {
margin-top: var(--spacing-6);
}
From a06f153910aeaf80f41893b0cef2904d351a0b5b Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 14:21:05 +0100
Subject: [PATCH 039/202] Slug input: add prop descriptions
---
panel/src/components/Forms/Input/SlugInput.vue | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/panel/src/components/Forms/Input/SlugInput.vue b/panel/src/components/Forms/Input/SlugInput.vue
index b13b412d97..5e830fec45 100644
--- a/panel/src/components/Forms/Input/SlugInput.vue
+++ b/panel/src/components/Forms/Input/SlugInput.vue
@@ -27,14 +27,23 @@ import TextInput, { props as TextInputProps } from "./TextInput.vue";
export const props = {
mixins: [TextInputProps],
props: {
+ /**
+ * Allow only specific characters for slug generation
+ */
allow: {
type: String,
default: ""
},
+ /**
+ * Values of other form inputs available for slug generation
+ */
formData: {
type: Object,
default: () => ({})
},
+ /**
+ * Name of the input to generate the slug from
+ */
sync: {
type: String
}
From ec9f3cd53823b01d0d2bf561f7cecba79e7eafd7 Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Sun, 11 Feb 2024 10:26:08 +0000
Subject: [PATCH 040/202] Added call to parent::tearDown()
Added missing call to parent::tearDown() so error handlers get cleaned up.
---
tests/Cms/Helpers/HelperFunctionsTest.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/Cms/Helpers/HelperFunctionsTest.php b/tests/Cms/Helpers/HelperFunctionsTest.php
index 85a9736c5b..2d2bf32bd4 100644
--- a/tests/Cms/Helpers/HelperFunctionsTest.php
+++ b/tests/Cms/Helpers/HelperFunctionsTest.php
@@ -34,6 +34,7 @@ public function setUp(): void
public function tearDown(): void
{
+ parent::tearDown();
Dir::remove(static::TMP);
}
From 2f08ea0ab7ec84d83b758eea20e99cd8b67f2fa4 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 13:08:42 +0100
Subject: [PATCH 041/202] fix cs
---
src/Cms/FileBlueprint.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Cms/FileBlueprint.php b/src/Cms/FileBlueprint.php
index ca0306ae13..1760dc3cc6 100644
--- a/src/Cms/FileBlueprint.php
+++ b/src/Cms/FileBlueprint.php
@@ -147,14 +147,14 @@ public function acceptAttribute(): string
if (is_array($accept['mime']) === true) {
// determine the extensions for each MIME type
$extensions = array_map(
- fn($pattern) => Mime::toExtensions($pattern, true),
+ fn ($pattern) => Mime::toExtensions($pattern, true),
$accept['mime']
);
$fromMime = array_unique(array_merge(...$extensions));
// return early to ignore the other options
- return implode(',', array_map(fn($ext) => ".$ext", $fromMime));
+ return implode(',', array_map(fn ($ext) => ".$ext", $fromMime));
}
$restrictions = [];
@@ -188,7 +188,7 @@ public function acceptAttribute(): string
$list = array_unique($list);
// format the list to include a leading dot on each extension
- return implode(',', array_map(fn($ext) => ".$ext", $list));
+ return implode(',', array_map(fn ($ext) => ".$ext", $list));
// unknown restrictions, accept everything
return '*';
From ff305a9557a67fcab3bd0f07f6cd1ed166570f05 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 13:29:14 +0100
Subject: [PATCH 042/202] Add tests for Mime::toExtensions() method, check
wildcard expansion
---
tests/Filesystem/MimeTest.php | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tests/Filesystem/MimeTest.php b/tests/Filesystem/MimeTest.php
index 78c8d4a28d..2d5649b404 100644
--- a/tests/Filesystem/MimeTest.php
+++ b/tests/Filesystem/MimeTest.php
@@ -130,6 +130,23 @@ public function testToExtensions()
$extensions = Mime::toExtensions('text/css');
$this->assertSame(['css'], $extensions);
+
+ // test matchWildcards: false (default value)
+ $extensions = Mime::toExtensions('image/*');
+ $this->assertSame(0, count($extensions));
+
+ // test matchWildcards: true
+ $extensions = Mime::toExtensions('image/*', true);
+ // use we only check for a positive and negative subset instead of a complete list,
+ // this should make sure the test doesn't break when a new image type is added
+ $shouldContain = ['jpg', 'jpeg', 'gif', 'png'];
+ $shouldNotContain = ['js', 'pdf', 'zip', 'docx'];
+ foreach ($shouldContain as $ext) {
+ $this->assertContains($ext, $extensions);
+ }
+ foreach ($shouldNotContain as $ext) {
+ $this->assertNotContains($ext, $extensions);
+ }
}
/**
From db466f9d6c264147319a691abf46f95df74c3d28 Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Mon, 12 Feb 2024 12:57:55 +0000
Subject: [PATCH 043/202] Fix to handle invalid PHP version strings
Some versions of PHP have extra information in the version string that does not conform to semantic versioning, this fix strips off that extra info with a regex taken from Composer's source code to handle the same situation.
---
src/Cms/System/UpdateStatus.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Cms/System/UpdateStatus.php b/src/Cms/System/UpdateStatus.php
index 0daa25b293..557d09a9bd 100644
--- a/src/Cms/System/UpdateStatus.php
+++ b/src/Cms/System/UpdateStatus.php
@@ -158,7 +158,9 @@ public function messages(): array|null
// collect all matching custom messages
$filters = [
'kirby' => $this->app->version(),
- 'php' => phpversion()
+ // Some PHP version strings contain extra info that makes them
+ // invalid so we need to strip it off.
+ 'php' => preg_replace('#^([^~+-]+).*$#', '$1', phpversion())
];
if ($type === 'plugin') {
From 5e2c59832d7a7413dd661e2f77a1c3592738de8f Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 14:03:11 +0100
Subject: [PATCH 044/202] Add FileBlueprintTest to test the acceptAttribute
method
---
tests/Cms/Blueprints/FileBlueprintTest.php | 117 +++++++++++++++++++++
1 file changed, 117 insertions(+)
create mode 100644 tests/Cms/Blueprints/FileBlueprintTest.php
diff --git a/tests/Cms/Blueprints/FileBlueprintTest.php b/tests/Cms/Blueprints/FileBlueprintTest.php
new file mode 100644
index 0000000000..eaae193ae1
--- /dev/null
+++ b/tests/Cms/Blueprints/FileBlueprintTest.php
@@ -0,0 +1,117 @@
+parent = Page::factory([
+ 'slug' => 'test'
+ ]);
+
+ $this->acceptCases = [
+ 'acceptWildcard' => [
+ 'accept' => 'image/*',
+ 'expected' => ['.jpg', '.jpeg', '.gif', '.png'],
+ 'notExpected' => ['.js', '.pdf', '.docx', '.zip']
+ ],
+ 'acceptMimeAsString' => [
+ 'accept' => 'image/jpeg, image/png',
+ 'expected' => ['.jpg', '.jpeg', '.png'],
+ 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip']
+ ],
+ 'acceptMimeAsProperty' => [
+ 'accept' => [
+ 'mime' => 'image/jpeg, image/png'
+ ],
+ 'expected' => ['.jpg', '.jpeg', '.png'],
+ 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip']
+ ],
+ 'acceptExtensions' => [
+ 'accept' => [
+ 'extension' => 'jpg, png'
+ ],
+ 'expected' => ['.jpg', '.png'],
+ 'notExpected' => ['.gif', '.jpeg', '.js', '.pdf', '.docx', '.zip']
+ ],
+ 'acceptExtensionsAndMime' => [
+ 'accept' => [
+ 'extension' => 'foo, bar', // when mime is present, extensions are ignored
+ 'mime' => 'image/jpeg, image/png'
+ ],
+ 'expected' => ['.jpg', '.jpeg', '.png'],
+ 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
+ ],
+ 'acceptType' => [
+ 'accept' => [
+ 'type' => 'image'
+ ],
+ 'expected' => ['.jpg', '.jpeg', '.gif', '.png'],
+ 'notExpected' => ['.js', '.pdf', '.docx', '.zip']
+ ],
+ 'acceptTypeAndMime' => [
+ 'accept' => [
+ 'type' => 'document', // when mime is present, type is ignored
+ 'mime' => 'image/jpeg, image/png'
+ ],
+ 'expected' => ['.jpg', '.jpeg', '.png'],
+ 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip']
+ ],
+ 'acceptInteresect' => [
+ 'accept' => [
+ 'type' => 'image',
+ 'extension' => 'jpg, png, foo, bar', // foo bar should be ignored
+ ],
+ 'expected' => ['.jpg', '.png'],
+ 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
+ ],
+ ];
+
+ // set up the blueprint files
+ foreach ($this->acceptCases as $name => $case) {
+ Blueprint::$loaded['files/' . $name] = [
+ 'accept' => $case['accept']
+ ];
+ }
+ }
+
+ protected function tearDown(): void {
+ Blueprint::$loaded = [];
+ $this->parent = null;
+ }
+
+ /**
+ * @covers ::acceptAttribute
+ */
+ public function testAcceptAttribute() {
+ foreach($this->acceptCases as $name => $case) {
+ $file = new File([
+ 'filename' => 'tmp',
+ 'parent' => $this->parent,
+ 'template' => $name
+ ]);
+ $acceptAttribute = $file->blueprint()->acceptAttribute();
+
+ $expected = $case['expected'];
+ $notExpected = $case['notExpected'];
+
+ foreach ($expected as $extension) {
+ $this->assertStringContainsString($extension, $acceptAttribute, "Case $name: $extension should be accepted");
+ }
+
+ foreach ($notExpected as $extension) {
+ $this->assertStringNotContainsString($extension, $acceptAttribute, "Case $name: $extension should not be accepted");
+ }
+ }
+ }
+}
From 8c08254df15225c66d449b90c6ef8c572011fed6 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 14:06:41 +0100
Subject: [PATCH 045/202] fix cs
---
tests/Cms/Blueprints/FileBlueprintTest.php | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/tests/Cms/Blueprints/FileBlueprintTest.php b/tests/Cms/Blueprints/FileBlueprintTest.php
index eaae193ae1..168a396912 100644
--- a/tests/Cms/Blueprints/FileBlueprintTest.php
+++ b/tests/Cms/Blueprints/FileBlueprintTest.php
@@ -14,7 +14,8 @@ class FileBlueprintTest extends TestCase
protected ?Page $parent;
protected array $acceptCases;
- protected function setUp(): void {
+ protected function setUp(): void
+ {
$this->parent = Page::factory([
'slug' => 'test'
]);
@@ -85,7 +86,8 @@ protected function setUp(): void {
}
}
- protected function tearDown(): void {
+ protected function tearDown(): void
+ {
Blueprint::$loaded = [];
$this->parent = null;
}
@@ -93,8 +95,9 @@ protected function tearDown(): void {
/**
* @covers ::acceptAttribute
*/
- public function testAcceptAttribute() {
- foreach($this->acceptCases as $name => $case) {
+ public function testAcceptAttribute()
+ {
+ foreach ($this->acceptCases as $name => $case) {
$file = new File([
'filename' => 'tmp',
'parent' => $this->parent,
From a31faf57ba4a936a2663a1b2d20b3eef8194474e Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 14:08:49 +0100
Subject: [PATCH 046/202] Remove unused import statement in
FileBlueprintTest.php
---
tests/Cms/Blueprints/FileBlueprintTest.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/Cms/Blueprints/FileBlueprintTest.php b/tests/Cms/Blueprints/FileBlueprintTest.php
index 168a396912..7f7029cc8a 100644
--- a/tests/Cms/Blueprints/FileBlueprintTest.php
+++ b/tests/Cms/Blueprints/FileBlueprintTest.php
@@ -2,7 +2,6 @@
use Kirby\Cms\Blueprint;
use Kirby\Cms\File;
-use Kirby\Cms\FileBlueprint;
use Kirby\Cms\Page;
use Kirby\TestCase;
From 5abd98037a7503da894fd60622149ae1151e6b2e Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 14:11:45 +0100
Subject: [PATCH 047/202] Fix array merging with keys in FileBlueprint.php
---
src/Cms/FileBlueprint.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Cms/FileBlueprint.php b/src/Cms/FileBlueprint.php
index 1760dc3cc6..e3cf2de787 100644
--- a/src/Cms/FileBlueprint.php
+++ b/src/Cms/FileBlueprint.php
@@ -151,7 +151,7 @@ public function acceptAttribute(): string
$accept['mime']
);
- $fromMime = array_unique(array_merge(...$extensions));
+ $fromMime = array_unique(array_merge(...array_values($extensions)));
// return early to ignore the other options
return implode(',', array_map(fn ($ext) => ".$ext", $fromMime));
@@ -168,7 +168,7 @@ public function acceptAttribute(): string
// F::typeToExtensions might return null instead of empty arrays,
// we need to filter those out
- $fromType = array_merge(...array_filter($extensions));
+ $fromType = array_merge(...array_values(array_filter($extensions)));
$restrictions[] = $fromType;
}
From 1ef54d4e842a2ce2b1fd24514e38d934c234f8d4 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 12 Feb 2024 16:01:54 +0100
Subject: [PATCH 048/202] remove unreachable code
---
src/Cms/FileBlueprint.php | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/Cms/FileBlueprint.php b/src/Cms/FileBlueprint.php
index e3cf2de787..97fef9837c 100644
--- a/src/Cms/FileBlueprint.php
+++ b/src/Cms/FileBlueprint.php
@@ -189,9 +189,6 @@ public function acceptAttribute(): string
// format the list to include a leading dot on each extension
return implode(',', array_map(fn ($ext) => ".$ext", $list));
-
- // unknown restrictions, accept everything
- return '*';
}
protected function normalizeAccept(mixed $accept = null): array
From c128e09caa8bbd51d78841c397fdb05fed8d1b1d Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Mon, 12 Feb 2024 19:37:38 +0000
Subject: [PATCH 049/202] Fix for floor giving different results in different
timezones
---
src/Toolkit/Date.php | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/Toolkit/Date.php b/src/Toolkit/Date.php
index e412d7f368..e7dec7241c 100644
--- a/src/Toolkit/Date.php
+++ b/src/Toolkit/Date.php
@@ -107,16 +107,16 @@ public function floor(string $unit): static
static::validateUnit($unit);
$formats = [
- 'year' => 'Y-01-01P',
- 'month' => 'Y-m-01P',
- 'day' => 'Y-m-dP',
- 'hour' => 'Y-m-d H:00:00P',
- 'minute' => 'Y-m-d H:i:00P',
- 'second' => 'Y-m-d H:i:sP'
+ 'year' => 'Y-01-01',
+ 'month' => 'Y-m-01',
+ 'day' => 'Y-m-d',
+ 'hour' => 'Y-m-d H:00:00',
+ 'minute' => 'Y-m-d H:i:00',
+ 'second' => 'Y-m-d H:i:s'
];
- $flooredDate = date($formats[$unit], $this->timestamp());
- $this->set($flooredDate);
+ $flooredDate = $this->format($formats[$unit]);
+ $this->set($flooredDate, $this->timezone());
return $this;
}
From 2252947e3963b5b0250f753476a4915775d5acc1 Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Mon, 12 Feb 2024 19:41:26 +0000
Subject: [PATCH 050/202] Added timezones to data provider
Cover different timezones in test
---
tests/Toolkit/DateTest.php | 166 +++++++++++++++++++++++++++++++------
1 file changed, 139 insertions(+), 27 deletions(-)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index 72d32813c7..31ea5e951b 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -277,33 +277,145 @@ public function testRound(string $unit, int $size, string $input, string $expect
public static function roundProvider(): array
{
return [
- '1s: no change' => ['second', 1, '2020-02-29 16:05:15', '2020-02-29 16:05:15'],
- '5s: no change' => ['second', 5, '2020-02-29 16:05:15', '2020-02-29 16:05:15'],
- '5s: floor' => ['second', 5, '2020-02-29 16:05:12', '2020-02-29 16:05:10'],
- '5s: ceil' => ['second', 5, '2020-02-29 16:05:13', '2020-02-29 16:05:15'],
- '5s: carry' => ['second', 5, '2020-02-29 16:59:58', '2020-02-29 17:00:00'],
- '1m: no change' => ['minute', 1, '2020-02-29 16:05:15', '2020-02-29 16:05:00'],
- '1m: ceil sub' => ['minute', 1, '2020-02-29 16:05:55', '2020-02-29 16:06:00'],
- '15m: no change' => ['minute', 1, '2020-02-29 16:07:15', '2020-02-29 16:07:00'],
- '15m: floor' => ['minute', 15, '2020-02-29 16:07:15', '2020-02-29 16:00:00'],
- '15m: ceil' => ['minute', 15, '2020-02-29 16:08:15', '2020-02-29 16:15:00'],
- '15m: ceil sub' => ['minute', 15, '2020-02-29 16:07:31', '2020-02-29 16:15:00'],
- '15m: carry' => ['minute', 15, '2020-02-29 23:53:15', '2020-03-01 00:00:00'],
- '1h: no change' => ['hour', 1, '2020-02-29 16:05:15', '2020-02-29 16:00:00'],
- '1h: ceil sub' => ['hour', 1, '2020-02-29 16:59:15', '2020-02-29 17:00:00'],
- '4h: no change' => ['hour', 4, '2020-02-29 16:05:15', '2020-02-29 16:00:00'],
- '4h: floor' => ['hour', 4, '2020-02-29 17:00:15', '2020-02-29 16:00:00'],
- '4h: ceil' => ['hour', 4, '2020-02-29 15:08:15', '2020-02-29 16:00:00'],
- '4h: ceil sub' => ['hour', 4, '2020-02-29 14:07:31', '2020-02-29 16:00:00'],
- '4h: carry' => ['hour', 4, '2020-02-29 23:53:15', '2020-03-01 00:00:00'],
- '1D: no change' => ['day', 1, '2020-02-29 09:05:15', '2020-02-29 00:00:00'],
- '1D: ceil sub' => ['day', 1, '2020-02-29 16:05:15', '2020-03-01 00:00:00'],
- '1M: no change' => ['month', 1, '2020-02-14 09:05:15', '2020-02-01 00:00:00'],
- '1M: ceil sub' => ['month', 1, '2020-02-29 16:05:15', '2020-03-01 00:00:00'],
- '1Y: no change' => ['year', 1, '2020-02-14 09:05:15', '2020-01-01 00:00:00'],
- '1Y: ceil sub' => ['year', 1, '2020-09-29 16:05:15', '2021-01-01 00:00:00'],
-
- 'kirby/issues/3642' => ['minute', 5, '2021-08-18 10:59:00', '2021-08-18 11:00:00'],
+ '1s: no change UTC' => ['second', 1, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:05:15'],
+ '5s: no change UTC' => ['second', 5, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:05:15'],
+ '5s: floor UTC' => ['second', 5, '2020-02-29 16:05:12', 'UTC', '2020-02-29 16:05:10'],
+ '5s: ceil UTC' => ['second', 5, '2020-02-29 16:05:13', 'UTC', '2020-02-29 16:05:15'],
+ '5s: carry UTC' => ['second', 5, '2020-02-29 16:59:58', 'UTC', '2020-02-29 17:00:00'],
+ '1m: no change UTC' => ['minute', 1, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:05:00'],
+ '1m: ceil sub UTC' => ['minute', 1, '2020-02-29 16:05:55', 'UTC', '2020-02-29 16:06:00'],
+ '15m: no change UTC' => ['minute', 1, '2020-02-29 16:07:15', 'UTC', '2020-02-29 16:07:00'],
+ '15m: floor UTC' => ['minute', 15, '2020-02-29 16:07:15', 'UTC', '2020-02-29 16:00:00'],
+ '15m: ceil UTC' => ['minute', 15, '2020-02-29 16:08:15', 'UTC', '2020-02-29 16:15:00'],
+ '15m: ceil sub UTC' => ['minute', 15, '2020-02-29 16:07:31', 'UTC', '2020-02-29 16:15:00'],
+ '15m: carry UTC' => ['minute', 15, '2020-02-29 23:53:15', 'UTC', '2020-03-01 00:00:00'],
+ '1h: no change UTC' => ['hour', 1, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:00:00'],
+ '1h: ceil sub UTC' => ['hour', 1, '2020-02-29 16:59:15', 'UTC', '2020-02-29 17:00:00'],
+ '4h: no change UTC' => ['hour', 4, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:00:00'],
+ '4h: floor UTC' => ['hour', 4, '2020-02-29 17:00:15', 'UTC', '2020-02-29 16:00:00'],
+ '4h: ceil UTC' => ['hour', 4, '2020-02-29 15:08:15', 'UTC', '2020-02-29 16:00:00'],
+ '4h: ceil sub UTC' => ['hour', 4, '2020-02-29 14:07:31', 'UTC', '2020-02-29 16:00:00'],
+ '4h: carry UTC' => ['hour', 4, '2020-02-29 23:53:15', 'UTC', '2020-03-01 00:00:00'],
+ '1D: no change UTC' => ['day', 1, '2020-02-29 09:05:15', 'UTC', '2020-02-29 00:00:00'],
+ '1D: ceil sub UTC' => ['day', 1, '2020-02-29 16:05:15', 'UTC', '2020-03-01 00:00:00'],
+ '1M: no change UTC' => ['month', 1, '2020-02-14 09:05:15', 'UTC', '2020-02-01 00:00:00'],
+ '1M: ceil sub UTC' => ['month', 1, '2020-02-29 16:05:15', 'UTC', '2020-03-01 00:00:00'],
+ '1Y: no change UTC' => ['year', 1, '2020-02-14 09:05:15', 'UTC', '2020-01-01 00:00:00'],
+ '1Y: ceil sub UTC' => ['year', 1, '2020-09-29 16:05:15', 'UTC', '2021-01-01 00:00:00'],
+
+ 'kirby/issues/3642 UTC' => ['minute', 5, '2021-08-18 10:59:00', 'UTC', '2021-08-18 11:00:00'],
+
+ '1s: no change Europe/London' => ['second', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:05:15'],
+ '5s: no change Europe/London' => ['second', 5, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:05:15'],
+ '5s: floor Europe/London' => ['second', 5, '2020-02-29 16:05:12', 'Europe/London', '2020-02-29 16:05:10'],
+ '5s: ceil Europe/London' => ['second', 5, '2020-02-29 16:05:13', 'Europe/London', '2020-02-29 16:05:15'],
+ '5s: carry Europe/London' => ['second', 5, '2020-02-29 16:59:58', 'Europe/London', '2020-02-29 17:00:00'],
+ '1m: no change Europe/London' => ['minute', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:05:00'],
+ '1m: ceil sub Europe/London' => ['minute', 1, '2020-02-29 16:05:55', 'Europe/London', '2020-02-29 16:06:00'],
+ '15m: no change Europe/London' => ['minute', 1, '2020-02-29 16:07:15', 'Europe/London', '2020-02-29 16:07:00'],
+ '15m: floor Europe/London' => ['minute', 15, '2020-02-29 16:07:15', 'Europe/London', '2020-02-29 16:00:00'],
+ '15m: ceil Europe/London' => ['minute', 15, '2020-02-29 16:08:15', 'Europe/London', '2020-02-29 16:15:00'],
+ '15m: ceil sub Europe/London' => ['minute', 15, '2020-02-29 16:07:31', 'Europe/London', '2020-02-29 16:15:00'],
+ '15m: carry Europe/London' => ['minute', 15, '2020-02-29 23:53:15', 'Europe/London', '2020-03-01 00:00:00'],
+ '1h: no change Europe/London' => ['hour', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:00:00'],
+ '1h: ceil sub Europe/London' => ['hour', 1, '2020-02-29 16:59:15', 'Europe/London', '2020-02-29 17:00:00'],
+ '4h: no change Europe/London' => ['hour', 4, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:00:00'],
+ '4h: floor Europe/London' => ['hour', 4, '2020-02-29 17:00:15', 'Europe/London', '2020-02-29 16:00:00'],
+ '4h: ceil Europe/London' => ['hour', 4, '2020-02-29 15:08:15', 'Europe/London', '2020-02-29 16:00:00'],
+ '4h: ceil sub Europe/London' => ['hour', 4, '2020-02-29 14:07:31', 'Europe/London', '2020-02-29 16:00:00'],
+ '4h: carry Europe/London' => ['hour', 4, '2020-02-29 23:53:15', 'Europe/London', '2020-03-01 00:00:00'],
+ '1D: no change Europe/London' => ['day', 1, '2020-02-29 09:05:15', 'Europe/London', '2020-02-29 00:00:00'],
+ '1D: ceil sub Europe/London' => ['day', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-03-01 00:00:00'],
+ '1M: no change Europe/London' => ['month', 1, '2020-02-14 09:05:15', 'Europe/London', '2020-02-01 00:00:00'],
+ '1M: ceil sub Europe/London' => ['month', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-03-01 00:00:00'],
+ '1Y: no change Europe/London' => ['year', 1, '2020-02-14 09:05:15', 'Europe/London', '2020-01-01 00:00:00'],
+ '1Y: ceil sub Europe/London' => ['year', 1, '2020-09-29 16:05:15', 'Europe/London', '2021-01-01 00:00:00'],
+
+ 'kirby/issues/3642 Europe/London' => ['minute', 5, '2021-08-18 10:59:00', 'Europe/London', '2021-08-18 11:00:00'],
+
+ '1s: no change Europe/Berlin' => ['second', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:05:15'],
+ '5s: no change Europe/Berlin' => ['second', 5, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:05:15'],
+ '5s: floor Europe/Berlin' => ['second', 5, '2020-02-29 16:05:12', 'Europe/Berlin', '2020-02-29 16:05:10'],
+ '5s: ceil Europe/Berlin' => ['second', 5, '2020-02-29 16:05:13', 'Europe/Berlin', '2020-02-29 16:05:15'],
+ '5s: carry Europe/Berlin' => ['second', 5, '2020-02-29 16:59:58', 'Europe/Berlin', '2020-02-29 17:00:00'],
+ '1m: no change Europe/Berlin' => ['minute', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:05:00'],
+ '1m: ceil sub Europe/Berlin' => ['minute', 1, '2020-02-29 16:05:55', 'Europe/Berlin', '2020-02-29 16:06:00'],
+ '15m: no change Europe/Berlin' => ['minute', 1, '2020-02-29 16:07:15', 'Europe/Berlin', '2020-02-29 16:07:00'],
+ '15m: floor Europe/Berlin' => ['minute', 15, '2020-02-29 16:07:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
+ '15m: ceil Europe/Berlin' => ['minute', 15, '2020-02-29 16:08:15', 'Europe/Berlin', '2020-02-29 16:15:00'],
+ '15m: ceil sub Europe/Berlin' => ['minute', 15, '2020-02-29 16:07:31', 'Europe/Berlin', '2020-02-29 16:15:00'],
+ '15m: carry Europe/Berlin' => ['minute', 15, '2020-02-29 23:53:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
+ '1h: no change Europe/Berlin' => ['hour', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
+ '1h: ceil sub Europe/Berlin' => ['hour', 1, '2020-02-29 16:59:15', 'Europe/Berlin', '2020-02-29 17:00:00'],
+ '4h: no change Europe/Berlin' => ['hour', 4, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
+ '4h: floor Europe/Berlin' => ['hour', 4, '2020-02-29 17:00:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
+ '4h: ceil Europe/Berlin' => ['hour', 4, '2020-02-29 15:08:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
+ '4h: ceil sub Europe/Berlin' => ['hour', 4, '2020-02-29 14:07:31', 'Europe/Berlin', '2020-02-29 16:00:00'],
+ '4h: carry Europe/Berlin' => ['hour', 4, '2020-02-29 23:53:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
+ '1D: no change Europe/Berlin' => ['day', 1, '2020-02-29 09:05:15', 'Europe/Berlin', '2020-02-29 00:00:00'],
+ '1D: ceil sub Europe/Berlin' => ['day', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
+ '1M: no change Europe/Berlin' => ['month', 1, '2020-02-14 09:05:15', 'Europe/Berlin', '2020-02-01 00:00:00'],
+ '1M: ceil sub Europe/Berlin' => ['month', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
+ '1Y: no change Europe/Berlin' => ['year', 1, '2020-02-14 09:05:15', 'Europe/Berlin', '2020-01-01 00:00:00'],
+ '1Y: ceil sub Europe/Berlin' => ['year', 1, '2020-09-29 16:05:15', 'Europe/Berlin', '2021-01-01 00:00:00'],
+
+ 'kirby/issues/3642 Europe/Berlin' => ['minute', 5, '2021-08-18 10:59:00', 'Europe/Berlin', '2021-08-18 11:00:00'],
+
+ '1s: no change America/New_York' => ['second', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:05:15'],
+ '5s: no change America/New_York' => ['second', 5, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:05:15'],
+ '5s: floor America/New_York' => ['second', 5, '2020-02-29 16:05:12', 'America/New_York', '2020-02-29 16:05:10'],
+ '5s: ceil America/New_York' => ['second', 5, '2020-02-29 16:05:13', 'America/New_York', '2020-02-29 16:05:15'],
+ '5s: carry America/New_York' => ['second', 5, '2020-02-29 16:59:58', 'America/New_York', '2020-02-29 17:00:00'],
+ '1m: no change America/New_York' => ['minute', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:05:00'],
+ '1m: ceil sub America/New_York' => ['minute', 1, '2020-02-29 16:05:55', 'America/New_York', '2020-02-29 16:06:00'],
+ '15m: no change America/New_York' => ['minute', 1, '2020-02-29 16:07:15', 'America/New_York', '2020-02-29 16:07:00'],
+ '15m: floor America/New_York' => ['minute', 15, '2020-02-29 16:07:15', 'America/New_York', '2020-02-29 16:00:00'],
+ '15m: ceil America/New_York' => ['minute', 15, '2020-02-29 16:08:15', 'America/New_York', '2020-02-29 16:15:00'],
+ '15m: ceil sub America/New_York' => ['minute', 15, '2020-02-29 16:07:31', 'America/New_York', '2020-02-29 16:15:00'],
+ '15m: carry America/New_York' => ['minute', 15, '2020-02-29 23:53:15', 'America/New_York', '2020-03-01 00:00:00'],
+ '1h: no change America/New_York' => ['hour', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:00:00'],
+ '1h: ceil sub America/New_York' => ['hour', 1, '2020-02-29 16:59:15', 'America/New_York', '2020-02-29 17:00:00'],
+ '4h: no change America/New_York' => ['hour', 4, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:00:00'],
+ '4h: floor America/New_York' => ['hour', 4, '2020-02-29 17:00:15', 'America/New_York', '2020-02-29 16:00:00'],
+ '4h: ceil America/New_York' => ['hour', 4, '2020-02-29 15:08:15', 'America/New_York', '2020-02-29 16:00:00'],
+ '4h: ceil sub America/New_York' => ['hour', 4, '2020-02-29 14:07:31', 'America/New_York', '2020-02-29 16:00:00'],
+ '4h: carry America/New_York' => ['hour', 4, '2020-02-29 23:53:15', 'America/New_York', '2020-03-01 00:00:00'],
+ '1D: no change America/New_York' => ['day', 1, '2020-02-29 09:05:15', 'America/New_York', '2020-02-29 00:00:00'],
+ '1D: ceil sub America/New_York' => ['day', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-03-01 00:00:00'],
+ '1M: no change America/New_York' => ['month', 1, '2020-02-14 09:05:15', 'America/New_York', '2020-02-01 00:00:00'],
+ '1M: ceil sub America/New_York' => ['month', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-03-01 00:00:00'],
+ '1Y: no change America/New_York' => ['year', 1, '2020-02-14 09:05:15', 'America/New_York', '2020-01-01 00:00:00'],
+ '1Y: ceil sub America/New_York' => ['year', 1, '2020-09-29 16:05:15', 'America/New_York', '2021-01-01 00:00:00'],
+
+ 'kirby/issues/3642 America/New_York' => ['minute', 5, '2021-08-18 10:59:00', 'America/New_York', '2021-08-18 11:00:00'],
+
+ '1s: no change Asia/Tokyo' => ['second', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:05:15'],
+ '5s: no change Asia/Tokyo' => ['second', 5, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:05:15'],
+ '5s: floor Asia/Tokyo' => ['second', 5, '2020-02-29 16:05:12', 'Asia/Tokyo', '2020-02-29 16:05:10'],
+ '5s: ceil Asia/Tokyo' => ['second', 5, '2020-02-29 16:05:13', 'Asia/Tokyo', '2020-02-29 16:05:15'],
+ '5s: carry Asia/Tokyo' => ['second', 5, '2020-02-29 16:59:58', 'Asia/Tokyo', '2020-02-29 17:00:00'],
+ '1m: no change Asia/Tokyo' => ['minute', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:05:00'],
+ '1m: ceil sub Asia/Tokyo' => ['minute', 1, '2020-02-29 16:05:55', 'Asia/Tokyo', '2020-02-29 16:06:00'],
+ '15m: no change Asia/Tokyo' => ['minute', 1, '2020-02-29 16:07:15', 'Asia/Tokyo', '2020-02-29 16:07:00'],
+ '15m: floor Asia/Tokyo' => ['minute', 15, '2020-02-29 16:07:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
+ '15m: ceil Asia/Tokyo' => ['minute', 15, '2020-02-29 16:08:15', 'Asia/Tokyo', '2020-02-29 16:15:00'],
+ '15m: ceil sub Asia/Tokyo' => ['minute', 15, '2020-02-29 16:07:31', 'Asia/Tokyo', '2020-02-29 16:15:00'],
+ '15m: carry Asia/Tokyo' => ['minute', 15, '2020-02-29 23:53:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
+ '1h: no change Asia/Tokyo' => ['hour', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
+ '1h: ceil sub Asia/Tokyo' => ['hour', 1, '2020-02-29 16:59:15', 'Asia/Tokyo', '2020-02-29 17:00:00'],
+ '4h: no change Asia/Tokyo' => ['hour', 4, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
+ '4h: floor Asia/Tokyo' => ['hour', 4, '2020-02-29 17:00:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
+ '4h: ceil Asia/Tokyo' => ['hour', 4, '2020-02-29 15:08:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
+ '4h: ceil sub Asia/Tokyo' => ['hour', 4, '2020-02-29 14:07:31', 'Asia/Tokyo', '2020-02-29 16:00:00'],
+ '4h: carry Asia/Tokyo' => ['hour', 4, '2020-02-29 23:53:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
+ '1D: no change Asia/Tokyo' => ['day', 1, '2020-02-29 09:05:15', 'Asia/Tokyo', '2020-02-29 00:00:00'],
+ '1D: ceil sub Asia/Tokyo' => ['day', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
+ '1M: no change Asia/Tokyo' => ['month', 1, '2020-02-14 09:05:15', 'Asia/Tokyo', '2020-02-01 00:00:00'],
+ '1M: ceil sub Asia/Tokyo' => ['month', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
+ '1Y: no change Asia/Tokyo' => ['year', 1, '2020-02-14 09:05:15', 'Asia/Tokyo', '2020-01-01 00:00:00'],
+ '1Y: ceil sub Asia/Tokyo' => ['year', 1, '2020-09-29 16:05:15', 'Asia/Tokyo', '2021-01-01 00:00:00'],
+
+ 'kirby/issues/3642 Asia/Tokyo' => ['minute', 5, '2021-08-18 10:59:00', 'Asia/Tokyo', '2021-08-18 11:00:00'],
];
}
From dbe04610f414b17550a8b472dca173dabe92d2ea Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Mon, 12 Feb 2024 20:04:18 +0000
Subject: [PATCH 051/202] Update DateTest.php
---
tests/Toolkit/DateTest.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index 31ea5e951b..4f4e6e1c31 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -267,13 +267,13 @@ public function testOptional()
* @covers ::round
* @dataProvider roundProvider
*/
- public function testRound(string $unit, int $size, string $input, string $expected)
+ public function testRound(string $unit, int $size, string $input, string $timezone, string $expected)
{
- $date = new Date($input);
+ $date = new Date($input, new DateTimeZone($timezone));
$this->assertSame($date, $date->round($unit, $size));
$this->assertSame($expected, $date->format('Y-m-d H:i:s'));
}
-
+
public static function roundProvider(): array
{
return [
From f8c472003ec6f0407b38d51058eb678368c72b92 Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Mon, 12 Feb 2024 20:15:41 +0000
Subject: [PATCH 052/202] Fix coding style
---
tests/Toolkit/DateTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index 4f4e6e1c31..23c20f5fb5 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -273,7 +273,7 @@ public function testRound(string $unit, int $size, string $input, string $timezo
$this->assertSame($date, $date->round($unit, $size));
$this->assertSame($expected, $date->format('Y-m-d H:i:s'));
}
-
+
public static function roundProvider(): array
{
return [
From f9a03bf93631596e97e94eab7b32a0daad7cf056 Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Mon, 12 Feb 2024 20:22:41 +0000
Subject: [PATCH 053/202] Added missing use for DateTimeZone
---
tests/Toolkit/DateTest.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index 23c20f5fb5..3e9995cb66 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -2,6 +2,7 @@
namespace Kirby\Toolkit;
+use DateTimeZone;
use IntlDateFormatter;
use Kirby\Cms\App;
use Kirby\Exception\InvalidArgumentException;
From c4674f2dbbe8236a9c82ff26ba2a5a9eaa762869 Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Tue, 13 Feb 2024 06:46:22 +0000
Subject: [PATCH 054/202] Tidied up test case
---
tests/Toolkit/DateTest.php | 189 ++++++++++---------------------------
1 file changed, 48 insertions(+), 141 deletions(-)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index 3e9995cb66..b787a19b1e 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -268,7 +268,7 @@ public function testOptional()
* @covers ::round
* @dataProvider roundProvider
*/
- public function testRound(string $unit, int $size, string $input, string $timezone, string $expected)
+ public function testRound(string $unit, int $size, string $input, string $expected, string $timezone)
{
$date = new Date($input, new DateTimeZone($timezone));
$this->assertSame($date, $date->round($unit, $size));
@@ -277,147 +277,54 @@ public function testRound(string $unit, int $size, string $input, string $timezo
public static function roundProvider(): array
{
- return [
- '1s: no change UTC' => ['second', 1, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:05:15'],
- '5s: no change UTC' => ['second', 5, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:05:15'],
- '5s: floor UTC' => ['second', 5, '2020-02-29 16:05:12', 'UTC', '2020-02-29 16:05:10'],
- '5s: ceil UTC' => ['second', 5, '2020-02-29 16:05:13', 'UTC', '2020-02-29 16:05:15'],
- '5s: carry UTC' => ['second', 5, '2020-02-29 16:59:58', 'UTC', '2020-02-29 17:00:00'],
- '1m: no change UTC' => ['minute', 1, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:05:00'],
- '1m: ceil sub UTC' => ['minute', 1, '2020-02-29 16:05:55', 'UTC', '2020-02-29 16:06:00'],
- '15m: no change UTC' => ['minute', 1, '2020-02-29 16:07:15', 'UTC', '2020-02-29 16:07:00'],
- '15m: floor UTC' => ['minute', 15, '2020-02-29 16:07:15', 'UTC', '2020-02-29 16:00:00'],
- '15m: ceil UTC' => ['minute', 15, '2020-02-29 16:08:15', 'UTC', '2020-02-29 16:15:00'],
- '15m: ceil sub UTC' => ['minute', 15, '2020-02-29 16:07:31', 'UTC', '2020-02-29 16:15:00'],
- '15m: carry UTC' => ['minute', 15, '2020-02-29 23:53:15', 'UTC', '2020-03-01 00:00:00'],
- '1h: no change UTC' => ['hour', 1, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:00:00'],
- '1h: ceil sub UTC' => ['hour', 1, '2020-02-29 16:59:15', 'UTC', '2020-02-29 17:00:00'],
- '4h: no change UTC' => ['hour', 4, '2020-02-29 16:05:15', 'UTC', '2020-02-29 16:00:00'],
- '4h: floor UTC' => ['hour', 4, '2020-02-29 17:00:15', 'UTC', '2020-02-29 16:00:00'],
- '4h: ceil UTC' => ['hour', 4, '2020-02-29 15:08:15', 'UTC', '2020-02-29 16:00:00'],
- '4h: ceil sub UTC' => ['hour', 4, '2020-02-29 14:07:31', 'UTC', '2020-02-29 16:00:00'],
- '4h: carry UTC' => ['hour', 4, '2020-02-29 23:53:15', 'UTC', '2020-03-01 00:00:00'],
- '1D: no change UTC' => ['day', 1, '2020-02-29 09:05:15', 'UTC', '2020-02-29 00:00:00'],
- '1D: ceil sub UTC' => ['day', 1, '2020-02-29 16:05:15', 'UTC', '2020-03-01 00:00:00'],
- '1M: no change UTC' => ['month', 1, '2020-02-14 09:05:15', 'UTC', '2020-02-01 00:00:00'],
- '1M: ceil sub UTC' => ['month', 1, '2020-02-29 16:05:15', 'UTC', '2020-03-01 00:00:00'],
- '1Y: no change UTC' => ['year', 1, '2020-02-14 09:05:15', 'UTC', '2020-01-01 00:00:00'],
- '1Y: ceil sub UTC' => ['year', 1, '2020-09-29 16:05:15', 'UTC', '2021-01-01 00:00:00'],
-
- 'kirby/issues/3642 UTC' => ['minute', 5, '2021-08-18 10:59:00', 'UTC', '2021-08-18 11:00:00'],
-
- '1s: no change Europe/London' => ['second', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:05:15'],
- '5s: no change Europe/London' => ['second', 5, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:05:15'],
- '5s: floor Europe/London' => ['second', 5, '2020-02-29 16:05:12', 'Europe/London', '2020-02-29 16:05:10'],
- '5s: ceil Europe/London' => ['second', 5, '2020-02-29 16:05:13', 'Europe/London', '2020-02-29 16:05:15'],
- '5s: carry Europe/London' => ['second', 5, '2020-02-29 16:59:58', 'Europe/London', '2020-02-29 17:00:00'],
- '1m: no change Europe/London' => ['minute', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:05:00'],
- '1m: ceil sub Europe/London' => ['minute', 1, '2020-02-29 16:05:55', 'Europe/London', '2020-02-29 16:06:00'],
- '15m: no change Europe/London' => ['minute', 1, '2020-02-29 16:07:15', 'Europe/London', '2020-02-29 16:07:00'],
- '15m: floor Europe/London' => ['minute', 15, '2020-02-29 16:07:15', 'Europe/London', '2020-02-29 16:00:00'],
- '15m: ceil Europe/London' => ['minute', 15, '2020-02-29 16:08:15', 'Europe/London', '2020-02-29 16:15:00'],
- '15m: ceil sub Europe/London' => ['minute', 15, '2020-02-29 16:07:31', 'Europe/London', '2020-02-29 16:15:00'],
- '15m: carry Europe/London' => ['minute', 15, '2020-02-29 23:53:15', 'Europe/London', '2020-03-01 00:00:00'],
- '1h: no change Europe/London' => ['hour', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:00:00'],
- '1h: ceil sub Europe/London' => ['hour', 1, '2020-02-29 16:59:15', 'Europe/London', '2020-02-29 17:00:00'],
- '4h: no change Europe/London' => ['hour', 4, '2020-02-29 16:05:15', 'Europe/London', '2020-02-29 16:00:00'],
- '4h: floor Europe/London' => ['hour', 4, '2020-02-29 17:00:15', 'Europe/London', '2020-02-29 16:00:00'],
- '4h: ceil Europe/London' => ['hour', 4, '2020-02-29 15:08:15', 'Europe/London', '2020-02-29 16:00:00'],
- '4h: ceil sub Europe/London' => ['hour', 4, '2020-02-29 14:07:31', 'Europe/London', '2020-02-29 16:00:00'],
- '4h: carry Europe/London' => ['hour', 4, '2020-02-29 23:53:15', 'Europe/London', '2020-03-01 00:00:00'],
- '1D: no change Europe/London' => ['day', 1, '2020-02-29 09:05:15', 'Europe/London', '2020-02-29 00:00:00'],
- '1D: ceil sub Europe/London' => ['day', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-03-01 00:00:00'],
- '1M: no change Europe/London' => ['month', 1, '2020-02-14 09:05:15', 'Europe/London', '2020-02-01 00:00:00'],
- '1M: ceil sub Europe/London' => ['month', 1, '2020-02-29 16:05:15', 'Europe/London', '2020-03-01 00:00:00'],
- '1Y: no change Europe/London' => ['year', 1, '2020-02-14 09:05:15', 'Europe/London', '2020-01-01 00:00:00'],
- '1Y: ceil sub Europe/London' => ['year', 1, '2020-09-29 16:05:15', 'Europe/London', '2021-01-01 00:00:00'],
-
- 'kirby/issues/3642 Europe/London' => ['minute', 5, '2021-08-18 10:59:00', 'Europe/London', '2021-08-18 11:00:00'],
-
- '1s: no change Europe/Berlin' => ['second', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:05:15'],
- '5s: no change Europe/Berlin' => ['second', 5, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:05:15'],
- '5s: floor Europe/Berlin' => ['second', 5, '2020-02-29 16:05:12', 'Europe/Berlin', '2020-02-29 16:05:10'],
- '5s: ceil Europe/Berlin' => ['second', 5, '2020-02-29 16:05:13', 'Europe/Berlin', '2020-02-29 16:05:15'],
- '5s: carry Europe/Berlin' => ['second', 5, '2020-02-29 16:59:58', 'Europe/Berlin', '2020-02-29 17:00:00'],
- '1m: no change Europe/Berlin' => ['minute', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:05:00'],
- '1m: ceil sub Europe/Berlin' => ['minute', 1, '2020-02-29 16:05:55', 'Europe/Berlin', '2020-02-29 16:06:00'],
- '15m: no change Europe/Berlin' => ['minute', 1, '2020-02-29 16:07:15', 'Europe/Berlin', '2020-02-29 16:07:00'],
- '15m: floor Europe/Berlin' => ['minute', 15, '2020-02-29 16:07:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
- '15m: ceil Europe/Berlin' => ['minute', 15, '2020-02-29 16:08:15', 'Europe/Berlin', '2020-02-29 16:15:00'],
- '15m: ceil sub Europe/Berlin' => ['minute', 15, '2020-02-29 16:07:31', 'Europe/Berlin', '2020-02-29 16:15:00'],
- '15m: carry Europe/Berlin' => ['minute', 15, '2020-02-29 23:53:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
- '1h: no change Europe/Berlin' => ['hour', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
- '1h: ceil sub Europe/Berlin' => ['hour', 1, '2020-02-29 16:59:15', 'Europe/Berlin', '2020-02-29 17:00:00'],
- '4h: no change Europe/Berlin' => ['hour', 4, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
- '4h: floor Europe/Berlin' => ['hour', 4, '2020-02-29 17:00:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
- '4h: ceil Europe/Berlin' => ['hour', 4, '2020-02-29 15:08:15', 'Europe/Berlin', '2020-02-29 16:00:00'],
- '4h: ceil sub Europe/Berlin' => ['hour', 4, '2020-02-29 14:07:31', 'Europe/Berlin', '2020-02-29 16:00:00'],
- '4h: carry Europe/Berlin' => ['hour', 4, '2020-02-29 23:53:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
- '1D: no change Europe/Berlin' => ['day', 1, '2020-02-29 09:05:15', 'Europe/Berlin', '2020-02-29 00:00:00'],
- '1D: ceil sub Europe/Berlin' => ['day', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
- '1M: no change Europe/Berlin' => ['month', 1, '2020-02-14 09:05:15', 'Europe/Berlin', '2020-02-01 00:00:00'],
- '1M: ceil sub Europe/Berlin' => ['month', 1, '2020-02-29 16:05:15', 'Europe/Berlin', '2020-03-01 00:00:00'],
- '1Y: no change Europe/Berlin' => ['year', 1, '2020-02-14 09:05:15', 'Europe/Berlin', '2020-01-01 00:00:00'],
- '1Y: ceil sub Europe/Berlin' => ['year', 1, '2020-09-29 16:05:15', 'Europe/Berlin', '2021-01-01 00:00:00'],
-
- 'kirby/issues/3642 Europe/Berlin' => ['minute', 5, '2021-08-18 10:59:00', 'Europe/Berlin', '2021-08-18 11:00:00'],
-
- '1s: no change America/New_York' => ['second', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:05:15'],
- '5s: no change America/New_York' => ['second', 5, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:05:15'],
- '5s: floor America/New_York' => ['second', 5, '2020-02-29 16:05:12', 'America/New_York', '2020-02-29 16:05:10'],
- '5s: ceil America/New_York' => ['second', 5, '2020-02-29 16:05:13', 'America/New_York', '2020-02-29 16:05:15'],
- '5s: carry America/New_York' => ['second', 5, '2020-02-29 16:59:58', 'America/New_York', '2020-02-29 17:00:00'],
- '1m: no change America/New_York' => ['minute', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:05:00'],
- '1m: ceil sub America/New_York' => ['minute', 1, '2020-02-29 16:05:55', 'America/New_York', '2020-02-29 16:06:00'],
- '15m: no change America/New_York' => ['minute', 1, '2020-02-29 16:07:15', 'America/New_York', '2020-02-29 16:07:00'],
- '15m: floor America/New_York' => ['minute', 15, '2020-02-29 16:07:15', 'America/New_York', '2020-02-29 16:00:00'],
- '15m: ceil America/New_York' => ['minute', 15, '2020-02-29 16:08:15', 'America/New_York', '2020-02-29 16:15:00'],
- '15m: ceil sub America/New_York' => ['minute', 15, '2020-02-29 16:07:31', 'America/New_York', '2020-02-29 16:15:00'],
- '15m: carry America/New_York' => ['minute', 15, '2020-02-29 23:53:15', 'America/New_York', '2020-03-01 00:00:00'],
- '1h: no change America/New_York' => ['hour', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:00:00'],
- '1h: ceil sub America/New_York' => ['hour', 1, '2020-02-29 16:59:15', 'America/New_York', '2020-02-29 17:00:00'],
- '4h: no change America/New_York' => ['hour', 4, '2020-02-29 16:05:15', 'America/New_York', '2020-02-29 16:00:00'],
- '4h: floor America/New_York' => ['hour', 4, '2020-02-29 17:00:15', 'America/New_York', '2020-02-29 16:00:00'],
- '4h: ceil America/New_York' => ['hour', 4, '2020-02-29 15:08:15', 'America/New_York', '2020-02-29 16:00:00'],
- '4h: ceil sub America/New_York' => ['hour', 4, '2020-02-29 14:07:31', 'America/New_York', '2020-02-29 16:00:00'],
- '4h: carry America/New_York' => ['hour', 4, '2020-02-29 23:53:15', 'America/New_York', '2020-03-01 00:00:00'],
- '1D: no change America/New_York' => ['day', 1, '2020-02-29 09:05:15', 'America/New_York', '2020-02-29 00:00:00'],
- '1D: ceil sub America/New_York' => ['day', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-03-01 00:00:00'],
- '1M: no change America/New_York' => ['month', 1, '2020-02-14 09:05:15', 'America/New_York', '2020-02-01 00:00:00'],
- '1M: ceil sub America/New_York' => ['month', 1, '2020-02-29 16:05:15', 'America/New_York', '2020-03-01 00:00:00'],
- '1Y: no change America/New_York' => ['year', 1, '2020-02-14 09:05:15', 'America/New_York', '2020-01-01 00:00:00'],
- '1Y: ceil sub America/New_York' => ['year', 1, '2020-09-29 16:05:15', 'America/New_York', '2021-01-01 00:00:00'],
-
- 'kirby/issues/3642 America/New_York' => ['minute', 5, '2021-08-18 10:59:00', 'America/New_York', '2021-08-18 11:00:00'],
-
- '1s: no change Asia/Tokyo' => ['second', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:05:15'],
- '5s: no change Asia/Tokyo' => ['second', 5, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:05:15'],
- '5s: floor Asia/Tokyo' => ['second', 5, '2020-02-29 16:05:12', 'Asia/Tokyo', '2020-02-29 16:05:10'],
- '5s: ceil Asia/Tokyo' => ['second', 5, '2020-02-29 16:05:13', 'Asia/Tokyo', '2020-02-29 16:05:15'],
- '5s: carry Asia/Tokyo' => ['second', 5, '2020-02-29 16:59:58', 'Asia/Tokyo', '2020-02-29 17:00:00'],
- '1m: no change Asia/Tokyo' => ['minute', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:05:00'],
- '1m: ceil sub Asia/Tokyo' => ['minute', 1, '2020-02-29 16:05:55', 'Asia/Tokyo', '2020-02-29 16:06:00'],
- '15m: no change Asia/Tokyo' => ['minute', 1, '2020-02-29 16:07:15', 'Asia/Tokyo', '2020-02-29 16:07:00'],
- '15m: floor Asia/Tokyo' => ['minute', 15, '2020-02-29 16:07:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
- '15m: ceil Asia/Tokyo' => ['minute', 15, '2020-02-29 16:08:15', 'Asia/Tokyo', '2020-02-29 16:15:00'],
- '15m: ceil sub Asia/Tokyo' => ['minute', 15, '2020-02-29 16:07:31', 'Asia/Tokyo', '2020-02-29 16:15:00'],
- '15m: carry Asia/Tokyo' => ['minute', 15, '2020-02-29 23:53:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
- '1h: no change Asia/Tokyo' => ['hour', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
- '1h: ceil sub Asia/Tokyo' => ['hour', 1, '2020-02-29 16:59:15', 'Asia/Tokyo', '2020-02-29 17:00:00'],
- '4h: no change Asia/Tokyo' => ['hour', 4, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
- '4h: floor Asia/Tokyo' => ['hour', 4, '2020-02-29 17:00:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
- '4h: ceil Asia/Tokyo' => ['hour', 4, '2020-02-29 15:08:15', 'Asia/Tokyo', '2020-02-29 16:00:00'],
- '4h: ceil sub Asia/Tokyo' => ['hour', 4, '2020-02-29 14:07:31', 'Asia/Tokyo', '2020-02-29 16:00:00'],
- '4h: carry Asia/Tokyo' => ['hour', 4, '2020-02-29 23:53:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
- '1D: no change Asia/Tokyo' => ['day', 1, '2020-02-29 09:05:15', 'Asia/Tokyo', '2020-02-29 00:00:00'],
- '1D: ceil sub Asia/Tokyo' => ['day', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
- '1M: no change Asia/Tokyo' => ['month', 1, '2020-02-14 09:05:15', 'Asia/Tokyo', '2020-02-01 00:00:00'],
- '1M: ceil sub Asia/Tokyo' => ['month', 1, '2020-02-29 16:05:15', 'Asia/Tokyo', '2020-03-01 00:00:00'],
- '1Y: no change Asia/Tokyo' => ['year', 1, '2020-02-14 09:05:15', 'Asia/Tokyo', '2020-01-01 00:00:00'],
- '1Y: ceil sub Asia/Tokyo' => ['year', 1, '2020-09-29 16:05:15', 'Asia/Tokyo', '2021-01-01 00:00:00'],
-
- 'kirby/issues/3642 Asia/Tokyo' => ['minute', 5, '2021-08-18 10:59:00', 'Asia/Tokyo', '2021-08-18 11:00:00'],
+ $timezones = [
+ 'UTC',
+ 'Europe/London',
+ 'Europe/Berlin',
+ 'America/New_York',
+ 'Asia/Tokyo'
+ ];
+
+ $inputs = [
+ '1s: no change' => ['second', 1, '2020-02-29 16:05:15', '2020-02-29 16:05:15'],
+ '5s: no change' => ['second', 5, '2020-02-29 16:05:15', '2020-02-29 16:05:15'],
+ '5s: floor' => ['second', 5, '2020-02-29 16:05:12', '2020-02-29 16:05:10'],
+ '5s: ceil' => ['second', 5, '2020-02-29 16:05:13', '2020-02-29 16:05:15'],
+ '5s: carry' => ['second', 5, '2020-02-29 16:59:58', '2020-02-29 17:00:00'],
+ '1m: no change' => ['minute', 1, '2020-02-29 16:05:15', '2020-02-29 16:05:00'],
+ '1m: ceil sub' => ['minute', 1, '2020-02-29 16:05:55', '2020-02-29 16:06:00'],
+ '15m: no change' => ['minute', 1, '2020-02-29 16:07:15', '2020-02-29 16:07:00'],
+ '15m: floor' => ['minute', 15, '2020-02-29 16:07:15', '2020-02-29 16:00:00'],
+ '15m: ceil' => ['minute', 15, '2020-02-29 16:08:15', '2020-02-29 16:15:00'],
+ '15m: ceil sub' => ['minute', 15, '2020-02-29 16:07:31', '2020-02-29 16:15:00'],
+ '15m: carry' => ['minute', 15, '2020-02-29 23:53:15', '2020-03-01 00:00:00'],
+ '1h: no change' => ['hour', 1, '2020-02-29 16:05:15', '2020-02-29 16:00:00'],
+ '1h: ceil sub' => ['hour', 1, '2020-02-29 16:59:15', '2020-02-29 17:00:00'],
+ '4h: no change' => ['hour', 4, '2020-02-29 16:05:15', '2020-02-29 16:00:00'],
+ '4h: floor' => ['hour', 4, '2020-02-29 17:00:15', '2020-02-29 16:00:00'],
+ '4h: ceil' => ['hour', 4, '2020-02-29 15:08:15', '2020-02-29 16:00:00'],
+ '4h: ceil sub' => ['hour', 4, '2020-02-29 14:07:31', '2020-02-29 16:00:00'],
+ '4h: carry' => ['hour', 4, '2020-02-29 23:53:15', '2020-03-01 00:00:00'],
+ '1D: no change' => ['day', 1, '2020-02-29 09:05:15', '2020-02-29 00:00:00'],
+ '1D: ceil sub' => ['day', 1, '2020-02-29 16:05:15', '2020-03-01 00:00:00'],
+ '1M: no change' => ['month', 1, '2020-02-14 09:05:15', '2020-02-01 00:00:00'],
+ '1M: ceil sub' => ['month', 1, '2020-02-29 16:05:15', '2020-03-01 00:00:00'],
+ '1Y: no change' => ['year', 1, '2020-02-14 09:05:15', '2020-01-01 00:00:00'],
+ '1Y: ceil sub' => ['year', 1, '2020-09-29 16:05:15', '2021-01-01 00:00:00'],
+
+ 'kirby/issues/3642 UTC' => ['minute', 5, '2021-08-18 10:59:00', '2021-08-18 11:00:00']
];
+
+ $data = [];
+
+ foreach ($timezones as $timezone) {
+ foreach ($inputs as $label => $arguments) {
+ $arguments[] = $timezone;
+ $data[$label . ' '. $timezone] = $arguments;
+ }
+ }
+
+ return $data;
}
/**
From 6f1e9cb9dfaaa1cb200c4728c888cc2d8312a26a Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Tue, 13 Feb 2024 06:51:58 +0000
Subject: [PATCH 055/202] Code style fix
---
tests/Toolkit/DateTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index b787a19b1e..fa0c7c5a2b 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -320,7 +320,7 @@ public static function roundProvider(): array
foreach ($timezones as $timezone) {
foreach ($inputs as $label => $arguments) {
$arguments[] = $timezone;
- $data[$label . ' '. $timezone] = $arguments;
+ $data[$label . ' ' . $timezone] = $arguments;
}
}
From f128829df7fe8d92882dacbe95972a1037bb2d3e Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 17 Feb 2024 11:58:14 +0100
Subject: [PATCH 056/202] Upgrade npm dependencies
---
panel/package-lock.json | 215 +++++++++++++++++-----------------------
panel/package.json | 16 +--
2 files changed, 97 insertions(+), 134 deletions(-)
diff --git a/panel/package-lock.json b/panel/package-lock.json
index c9eba93abc..276aaa5637 100644
--- a/panel/package-lock.json
+++ b/panel/package-lock.json
@@ -13,11 +13,11 @@
"portal-vue": "^2.1.7",
"prosemirror-commands": "^1.5.2",
"prosemirror-history": "^1.3.2",
- "prosemirror-inputrules": "^1.3.0",
+ "prosemirror-inputrules": "^1.4.0",
"prosemirror-keymap": "^1.2.2",
"prosemirror-model": "^1.19.4",
"prosemirror-schema-list": "^1.3.0",
- "prosemirror-view": "^1.32.7",
+ "prosemirror-view": "^1.33.1",
"vue": "^2.7.16",
"vuedraggable": "^2.24.3",
"vuelidate": "^0.7.7",
@@ -27,15 +27,15 @@
"@vitejs/plugin-vue2": "^2.3.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
- "eslint-plugin-vue": "^9.20.1",
+ "eslint-plugin-vue": "^9.21.1",
"glob": "^10.3.10",
- "jsdom": "^23.2.0",
- "prettier": "^3.2.4",
+ "jsdom": "^24.0.0",
+ "prettier": "^3.2.5",
"rollup-plugin-external-globals": "^0.9.2",
- "terser": "^5.27.0",
- "vite": "^5.1.0",
+ "terser": "^5.27.1",
+ "vite": "^5.1.3",
"vite-plugin-static-copy": "^1.0.1",
- "vitest": "^1.2.2",
+ "vitest": "^1.3.0",
"vue-docgen-api": "^4.75.1",
"vue-template-compiler": "^2.7.16"
}
@@ -49,17 +49,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/@asamuzakjp/dom-selector": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz",
- "integrity": "sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==",
- "dev": true,
- "dependencies": {
- "bidi-js": "^1.0.3",
- "css-tree": "^2.3.1",
- "is-potential-custom-element-name": "^1.0.1"
- }
- },
"node_modules/@babel/helper-string-parser": {
"version": "7.23.4",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
@@ -924,13 +913,13 @@
}
},
"node_modules/@vitest/expect": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.2.tgz",
- "integrity": "sha512-3jpcdPAD7LwHUUiT2pZTj2U82I2Tcgg2oVPvKxhn6mDI2On6tfvPQTjAI4628GUGDZrCm4Zna9iQHm5cEexOAg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.0.tgz",
+ "integrity": "sha512-7bWt0vBTZj08B+Ikv70AnLRicohYwFgzNjFqo9SxxqHHxSlUJGSXmCRORhOnRMisiUryKMdvsi1n27Bc6jL9DQ==",
"dev": true,
"dependencies": {
- "@vitest/spy": "1.2.2",
- "@vitest/utils": "1.2.2",
+ "@vitest/spy": "1.3.0",
+ "@vitest/utils": "1.3.0",
"chai": "^4.3.10"
},
"funding": {
@@ -938,12 +927,12 @@
}
},
"node_modules/@vitest/runner": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.2.tgz",
- "integrity": "sha512-JctG7QZ4LSDXr5CsUweFgcpEvrcxOV1Gft7uHrvkQ+fsAVylmWQvnaAr/HDp3LAH1fztGMQZugIheTWjaGzYIg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.3.0.tgz",
+ "integrity": "sha512-1Jb15Vo/Oy7mwZ5bXi7zbgszsdIBNjc4IqP8Jpr/8RdBC4nF1CTzIAn2dxYvpF1nGSseeL39lfLQ2uvs5u1Y9A==",
"dev": true,
"dependencies": {
- "@vitest/utils": "1.2.2",
+ "@vitest/utils": "1.3.0",
"p-limit": "^5.0.0",
"pathe": "^1.1.1"
},
@@ -979,9 +968,9 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.2.tgz",
- "integrity": "sha512-SmGY4saEw1+bwE1th6S/cZmPxz/Q4JWsl7LvbQIky2tKE35US4gd0Mjzqfr84/4OD0tikGWaWdMja/nWL5NIPA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.3.0.tgz",
+ "integrity": "sha512-swmktcviVVPYx9U4SEQXLV6AEY51Y6bZ14jA2yo6TgMxQ3h+ZYiO0YhAHGJNp0ohCFbPAis1R9kK0cvN6lDPQA==",
"dev": true,
"dependencies": {
"magic-string": "^0.30.5",
@@ -1011,9 +1000,9 @@
}
},
"node_modules/@vitest/spy": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.2.tgz",
- "integrity": "sha512-k9Gcahssw8d7X3pSLq3e3XEu/0L78mUkCjivUqCQeXJm9clfXR/Td8+AP+VC1O6fKPIDLcHDTAmBOINVuv6+7g==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.0.tgz",
+ "integrity": "sha512-AkCU0ThZunMvblDpPKgjIi025UxR8V7MZ/g/EwmAGpjIujLVV2X6rGYGmxE2D4FJbAy0/ijdROHMWa2M/6JVMw==",
"dev": true,
"dependencies": {
"tinyspy": "^2.2.0"
@@ -1023,9 +1012,9 @@
}
},
"node_modules/@vitest/utils": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.2.tgz",
- "integrity": "sha512-WKITBHLsBHlpjnDQahr+XK6RE7MiAsgrIkr0pGhQ9ygoxBfUeG0lUG5iLlzqjmKSlBv3+j5EGsriBzh+C3Tq9g==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.0.tgz",
+ "integrity": "sha512-/LibEY/fkaXQufi4GDlQZhikQsPO2entBKtfuyIpr1jV4DpaeasqkeHjhdOhU24vSHshcSuEyVlWdzvv2XmYCw==",
"dev": true,
"dependencies": {
"diff-sequences": "^29.6.3",
@@ -1312,15 +1301,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
- "node_modules/bidi-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
- "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
- "dev": true,
- "dependencies": {
- "require-from-string": "^2.0.2"
- }
- },
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -1566,19 +1546,6 @@
"node": ">= 8"
}
},
- "node_modules/css-tree": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
- "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
- "dev": true,
- "dependencies": {
- "mdn-data": "2.0.30",
- "source-map-js": "^1.0.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
- }
- },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -1886,9 +1853,9 @@
}
},
"node_modules/eslint-plugin-vue": {
- "version": "9.20.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.20.1.tgz",
- "integrity": "sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==",
+ "version": "9.21.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz",
+ "integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
@@ -1896,7 +1863,7 @@
"nth-check": "^2.1.1",
"postcss-selector-parser": "^6.0.13",
"semver": "^7.5.4",
- "vue-eslint-parser": "^9.4.0",
+ "vue-eslint-parser": "^9.4.2",
"xml-name-validator": "^4.0.0"
},
"engines": {
@@ -2767,6 +2734,12 @@
"integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==",
"dev": true
},
+ "node_modules/js-tokens": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz",
+ "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==",
+ "dev": true
+ },
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -2780,12 +2753,11 @@
}
},
"node_modules/jsdom": {
- "version": "23.2.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.2.0.tgz",
- "integrity": "sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==",
+ "version": "24.0.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz",
+ "integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==",
"dev": true,
"dependencies": {
- "@asamuzakjp/dom-selector": "^2.0.1",
"cssstyle": "^4.0.1",
"data-urls": "^5.0.0",
"decimal.js": "^10.4.3",
@@ -2794,6 +2766,7 @@
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.7",
"parse5": "^7.1.2",
"rrweb-cssom": "^0.6.0",
"saxes": "^6.0.0",
@@ -3183,12 +3156,6 @@
"sourcemap-codec": "^1.4.8"
}
},
- "node_modules/mdn-data": {
- "version": "2.0.30",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
- "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
- "dev": true
- },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -3365,6 +3332,12 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
+ "node_modules/nwsapi": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
+ "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==",
+ "dev": true
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -3649,9 +3622,9 @@
}
},
"node_modules/prettier": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
- "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+ "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -3720,9 +3693,9 @@
}
},
"node_modules/prosemirror-inputrules": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.3.0.tgz",
- "integrity": "sha512-z1GRP2vhh5CihYMQYsJSa1cOwXb3SYxALXOIfAkX8nZserARtl9LiL+CEl+T+OFIsXc3mJIHKhbsmRzC0HDAXA==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz",
+ "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==",
"dependencies": {
"prosemirror-state": "^1.0.0",
"prosemirror-transform": "^1.0.0"
@@ -3774,9 +3747,9 @@
}
},
"node_modules/prosemirror-view": {
- "version": "1.32.7",
- "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.32.7.tgz",
- "integrity": "sha512-pvxiOoD4shW41X5bYDjRQk3DSG4fMqxh36yPMt7VYgU3dWRmqFzWJM/R6zeo1KtC8nyk717ZbQND3CC9VNeptw==",
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.1.tgz",
+ "integrity": "sha512-62qkYgSJIkwIMMCpuGuPzc52DiK1Iod6TWoIMxP4ja6BTD4yO8kCUL64PZ/WhH/dJ9fW0CDO39FhH1EMyhUFEg==",
"dependencies": {
"prosemirror-model": "^1.16.0",
"prosemirror-state": "^1.0.0",
@@ -3982,15 +3955,6 @@
"node": ">= 4"
}
},
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -4191,9 +4155,9 @@
}
},
"node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -4421,12 +4385,12 @@
}
},
"node_modules/strip-literal": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz",
- "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz",
+ "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==",
"dev": true,
"dependencies": {
- "acorn": "^8.10.0"
+ "js-tokens": "^8.0.2"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
@@ -4451,9 +4415,9 @@
"dev": true
},
"node_modules/terser": {
- "version": "5.27.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
- "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+ "version": "5.27.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.1.tgz",
+ "integrity": "sha512-29wAr6UU/oQpnTw5HoadwjUZnFQXGdOfj0LjZ4sVxzqwHh/QVkvr7m8y9WoR4iN3FRitVduTc6KdjcW38Npsug==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -4496,9 +4460,9 @@
}
},
"node_modules/tinyspy": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz",
- "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
+ "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
"dev": true,
"engines": {
"node": ">=14.0.0"
@@ -4674,9 +4638,9 @@
"dev": true
},
"node_modules/vite": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.0.tgz",
- "integrity": "sha512-STmSFzhY4ljuhz14bg9LkMTk3d98IO6DIArnTY6MeBwiD1Za2StcQtz7fzOUnRCqrHSD5+OS2reg4HOz1eoLnw==",
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.3.tgz",
+ "integrity": "sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==",
"dev": true,
"dependencies": {
"esbuild": "^0.19.3",
@@ -4729,9 +4693,9 @@
}
},
"node_modules/vite-node": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.2.tgz",
- "integrity": "sha512-1as4rDTgVWJO3n1uHmUYqq7nsFgINQ9u+mRcXpjeOMJUmviqNKjcZB7UfRZrlM7MjYXMKpuWp5oGkjaFLnjawg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.3.0.tgz",
+ "integrity": "sha512-D/oiDVBw75XMnjAXne/4feCkCEwcbr2SU1bjAhCcfI5Bq3VoOHji8/wCPAfUkDIeohJ5nSZ39fNxM3dNZ6OBOA==",
"dev": true,
"dependencies": {
"cac": "^6.7.14",
@@ -4783,18 +4747,17 @@
}
},
"node_modules/vitest": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.2.tgz",
- "integrity": "sha512-d5Ouvrnms3GD9USIK36KG8OZ5bEvKEkITFtnGv56HFaSlbItJuYr7hv2Lkn903+AvRAgSixiamozUVfORUekjw==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.3.0.tgz",
+ "integrity": "sha512-V9qb276J1jjSx9xb75T2VoYXdO1UKi+qfflY7V7w93jzX7oA/+RtYE6TcifxksxsZvygSSMwu2Uw6di7yqDMwg==",
"dev": true,
"dependencies": {
- "@vitest/expect": "1.2.2",
- "@vitest/runner": "1.2.2",
- "@vitest/snapshot": "1.2.2",
- "@vitest/spy": "1.2.2",
- "@vitest/utils": "1.2.2",
+ "@vitest/expect": "1.3.0",
+ "@vitest/runner": "1.3.0",
+ "@vitest/snapshot": "1.3.0",
+ "@vitest/spy": "1.3.0",
+ "@vitest/utils": "1.3.0",
"acorn-walk": "^8.3.2",
- "cac": "^6.7.14",
"chai": "^4.3.10",
"debug": "^4.3.4",
"execa": "^8.0.1",
@@ -4803,11 +4766,11 @@
"pathe": "^1.1.1",
"picocolors": "^1.0.0",
"std-env": "^3.5.0",
- "strip-literal": "^1.3.0",
+ "strip-literal": "^2.0.0",
"tinybench": "^2.5.1",
"tinypool": "^0.8.2",
"vite": "^5.0.0",
- "vite-node": "1.2.2",
+ "vite-node": "1.3.0",
"why-is-node-running": "^2.2.2"
},
"bin": {
@@ -4822,8 +4785,8 @@
"peerDependencies": {
"@edge-runtime/vm": "*",
"@types/node": "^18.0.0 || >=20.0.0",
- "@vitest/browser": "^1.0.0",
- "@vitest/ui": "^1.0.0",
+ "@vitest/browser": "1.3.0",
+ "@vitest/ui": "1.3.0",
"happy-dom": "*",
"jsdom": "*"
},
@@ -4934,9 +4897,9 @@
}
},
"node_modules/vue-eslint-parser": {
- "version": "9.4.0",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.0.tgz",
- "integrity": "sha512-7KsNBb6gHFA75BtneJsoK/dbZ281whUIwFYdQxA68QrCrGMXYzUMbPDHGcOQ0OocIVKrWSKWXZ4mL7tonCXoUw==",
+ "version": "9.4.2",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+ "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
"dev": true,
"dependencies": {
"debug": "^4.3.4",
diff --git a/panel/package.json b/panel/package.json
index 5a16c9df82..5fa346237c 100644
--- a/panel/package.json
+++ b/panel/package.json
@@ -18,11 +18,11 @@
"portal-vue": "^2.1.7",
"prosemirror-commands": "^1.5.2",
"prosemirror-history": "^1.3.2",
- "prosemirror-inputrules": "^1.3.0",
+ "prosemirror-inputrules": "^1.4.0",
"prosemirror-keymap": "^1.2.2",
"prosemirror-model": "^1.19.4",
"prosemirror-schema-list": "^1.3.0",
- "prosemirror-view": "^1.32.7",
+ "prosemirror-view": "^1.33.1",
"vue": "^2.7.16",
"vuedraggable": "^2.24.3",
"vuelidate": "^0.7.7",
@@ -32,15 +32,15 @@
"@vitejs/plugin-vue2": "^2.3.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
- "eslint-plugin-vue": "^9.20.1",
+ "eslint-plugin-vue": "^9.21.1",
"glob": "^10.3.10",
- "jsdom": "^23.2.0",
- "prettier": "^3.2.4",
+ "jsdom": "^24.0.0",
+ "prettier": "^3.2.5",
"rollup-plugin-external-globals": "^0.9.2",
- "terser": "^5.27.0",
- "vite": "^5.1.0",
+ "terser": "^5.27.1",
+ "vite": "^5.1.3",
"vite-plugin-static-copy": "^1.0.1",
- "vitest": "^1.2.2",
+ "vitest": "^1.3.0",
"vue-docgen-api": "^4.75.1",
"vue-template-compiler": "^2.7.16"
},
From 08309103cb62ead3efa7cbf664e8cfcfd32e25bb Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 13:48:17 +0100
Subject: [PATCH 057/202] `Colorname` input: unset inherited props
---
.../components/Forms/Input/ColornameInput.vue | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/panel/src/components/Forms/Input/ColornameInput.vue b/panel/src/components/Forms/Input/ColornameInput.vue
index 4bb887fb3c..aabaee7eec 100644
--- a/panel/src/components/Forms/Input/ColornameInput.vue
+++ b/panel/src/components/Forms/Input/ColornameInput.vue
@@ -1,6 +1,8 @@
["hex", "rgb", "hsl"].includes(format)
- },
- spellcheck: {
- default: false,
- type: Boolean
}
}
};
From b8e19af2dfb74344d92fc0bb2e957dd7d7a89b7e Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 14:10:17 +0100
Subject: [PATCH 058/202] `search` input: unset props
---
panel/lab/components/inputs/search/index.vue | 2 +-
panel/src/components/Forms/Input/SearchInput.vue | 13 +++++++------
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/panel/lab/components/inputs/search/index.vue b/panel/lab/components/inputs/search/index.vue
index 86cbd2aec6..179443d56c 100644
--- a/panel/lab/components/inputs/search/index.vue
+++ b/panel/lab/components/inputs/search/index.vue
@@ -1,6 +1,6 @@
-
+
diff --git a/panel/src/components/Forms/Input/SearchInput.vue b/panel/src/components/Forms/Input/SearchInput.vue
index cc5b864bea..554ca98c5a 100644
--- a/panel/src/components/Forms/Input/SearchInput.vue
+++ b/panel/src/components/Forms/Input/SearchInput.vue
@@ -1,6 +1,8 @@
window.panel.$t("search") + " …",
type: String
- },
- spellcheck: {
- default: false
}
}
};
From 53ebd6f8d9da7947d13b7ba7dec1ba964017252a Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 11:44:16 +0100
Subject: [PATCH 059/202] =?UTF-8?q?Fix=20alpha/hue=20input=E2=80=99s=20min?=
=?UTF-8?q?/max?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes #6251
---
panel/src/components/Forms/Input/AlphaInput.vue | 14 ++++++--------
panel/src/components/Forms/Input/HueInput.vue | 14 ++++++--------
2 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/panel/src/components/Forms/Input/AlphaInput.vue b/panel/src/components/Forms/Input/AlphaInput.vue
index 7c63ad8ac3..34b1ce94ad 100644
--- a/panel/src/components/Forms/Input/AlphaInput.vue
+++ b/panel/src/components/Forms/Input/AlphaInput.vue
@@ -1,6 +1,8 @@
@@ -13,14 +15,10 @@ import Input from "./RangeInput.vue";
export const props = {
mixins: [RangeInputProps],
props: {
- max: {
- default: 1,
- type: Number
- },
- min: {
- default: 0,
- type: Number
- },
+ // unset unused/fixed props
+ max: null,
+ min: null,
+
step: {
default: 0.01,
type: Number
diff --git a/panel/src/components/Forms/Input/HueInput.vue b/panel/src/components/Forms/Input/HueInput.vue
index f31bac8282..d414c70764 100644
--- a/panel/src/components/Forms/Input/HueInput.vue
+++ b/panel/src/components/Forms/Input/HueInput.vue
@@ -1,6 +1,8 @@
@@ -13,14 +15,10 @@ import Input from "./RangeInput.vue";
export const props = {
mixins: [RangeInputProps],
props: {
- max: {
- default: 360,
- type: Number
- },
- min: {
- default: 0,
- type: Number
- },
+ // unset unused/fixed props
+ max: null,
+ min: null,
+
step: {
default: 1,
type: Number
From 71a26dae49bb43cdd3fb94361e143e60a6522c89 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 15:08:03 +0100
Subject: [PATCH 060/202] Lab: `$helpers.array` docs
---
panel/lab/internals/helpers/array/index.vue | 125 ++++++++++++++++++
.../{colors => library.colors}/index.vue | 0
.../1_dayjs/index.vue | 0
.../2_format/index.vue | 0
.../3_interpret/index.vue | 0
.../{dayjs => library.dayjs}/4_iso/index.vue | 0
.../5_validate/index.vue | 0
panel/lab/internals/panel/api/index.vue | 9 --
panel/lab/internals/panel/config/index.vue | 9 --
panel/lab/internals/panel/dialog/index.vue | 9 --
panel/lab/internals/panel/drag/index.vue | 9 --
panel/lab/internals/panel/drawer/index.vue | 9 --
panel/lab/internals/panel/dropdown/index.vue | 9 --
panel/lab/internals/panel/events/index.vue | 9 --
panel/lab/internals/panel/language/index.vue | 9 --
.../internals/panel/notification/index.vue | 9 --
panel/lab/internals/panel/panel/index.vue | 9 --
panel/lab/internals/panel/system/index.vue | 9 --
.../lab/internals/panel/translation/index.vue | 9 --
panel/lab/internals/panel/upload/index.vue | 9 --
panel/lab/internals/panel/urls/index.vue | 9 --
panel/lab/internals/panel/user/index.vue | 9 --
panel/lab/internals/panel/view/index.vue | 9 --
panel/src/components/Lab/PlaygroundView.vue | 7 +
panel/src/helpers/array.js | 2 +
25 files changed, 134 insertions(+), 144 deletions(-)
create mode 100644 panel/lab/internals/helpers/array/index.vue
rename panel/lab/internals/{colors => library.colors}/index.vue (100%)
rename panel/lab/internals/{dayjs => library.dayjs}/1_dayjs/index.vue (100%)
rename panel/lab/internals/{dayjs => library.dayjs}/2_format/index.vue (100%)
rename panel/lab/internals/{dayjs => library.dayjs}/3_interpret/index.vue (100%)
rename panel/lab/internals/{dayjs => library.dayjs}/4_iso/index.vue (100%)
rename panel/lab/internals/{dayjs => library.dayjs}/5_validate/index.vue (100%)
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
new file mode 100644
index 0000000000..b7076958dd
--- /dev/null
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -0,0 +1,125 @@
+
+
+
+ Access the following array helpers in your Vue components through
+ this.$helpers.array
+
+
+
+
+
+ Creates an array from an object:
+ this.$helpers.array.fromObject(object)
+
+
+ Input: {{ fromObjectInput }}
+
+ Result: {{ $helper.array.fromObject(fromObjectInput) }}
+
+
+
+
+
+
+
+
+ Filters an array by a provided query:
+
+ this.$helpers.array.search(array, "{{ searchQuery }}", { min: 2,
+ field: "name" })
+
+
+
+ {{ searchInput }}
+
+ {{ searchResult }}
+
+
+
+
+
+
+
+ Sorts an array by one or more fields and directions:
+ this.$helpers.array.sortBy(array, "name desc")
+
+
+ {{ searchInput }}
+ {{
+ $helper.array.sortBy(searchInput, "name desc")
+ }}
+
+
+
+
+
+
+
+ Splits an array into groups by a delimiter entry:
+ this.$helpers.array.split(array, "-")
+
+
+ {{ splitInput }}
+ {{ $helper.array.split(splitInput, "-") }}
+
+
+
+
+
+
+
+ Wraps a value in an array (ensures the value will be an array):
+ this.$helpers.array.wrap(value)
+
+ "aaa", ["aaa"]
+
+
+ {{ $helper.array.wrap("aaa") }},
+ {{ $helper.array.wrap(["aaa"]) }}
+
+
+
+
+
+
+
+
diff --git a/panel/lab/internals/colors/index.vue b/panel/lab/internals/library.colors/index.vue
similarity index 100%
rename from panel/lab/internals/colors/index.vue
rename to panel/lab/internals/library.colors/index.vue
diff --git a/panel/lab/internals/dayjs/1_dayjs/index.vue b/panel/lab/internals/library.dayjs/1_dayjs/index.vue
similarity index 100%
rename from panel/lab/internals/dayjs/1_dayjs/index.vue
rename to panel/lab/internals/library.dayjs/1_dayjs/index.vue
diff --git a/panel/lab/internals/dayjs/2_format/index.vue b/panel/lab/internals/library.dayjs/2_format/index.vue
similarity index 100%
rename from panel/lab/internals/dayjs/2_format/index.vue
rename to panel/lab/internals/library.dayjs/2_format/index.vue
diff --git a/panel/lab/internals/dayjs/3_interpret/index.vue b/panel/lab/internals/library.dayjs/3_interpret/index.vue
similarity index 100%
rename from panel/lab/internals/dayjs/3_interpret/index.vue
rename to panel/lab/internals/library.dayjs/3_interpret/index.vue
diff --git a/panel/lab/internals/dayjs/4_iso/index.vue b/panel/lab/internals/library.dayjs/4_iso/index.vue
similarity index 100%
rename from panel/lab/internals/dayjs/4_iso/index.vue
rename to panel/lab/internals/library.dayjs/4_iso/index.vue
diff --git a/panel/lab/internals/dayjs/5_validate/index.vue b/panel/lab/internals/library.dayjs/5_validate/index.vue
similarity index 100%
rename from panel/lab/internals/dayjs/5_validate/index.vue
rename to panel/lab/internals/library.dayjs/5_validate/index.vue
diff --git a/panel/lab/internals/panel/api/index.vue b/panel/lab/internals/panel/api/index.vue
index 8792c0807b..7814a4226c 100644
--- a/panel/lab/internals/panel/api/index.vue
+++ b/panel/lab/internals/panel/api/index.vue
@@ -44,12 +44,3 @@ export default {
methods: {}
};
-
-
diff --git a/panel/lab/internals/panel/config/index.vue b/panel/lab/internals/panel/config/index.vue
index 37b576d9e0..d8784b5f92 100644
--- a/panel/lab/internals/panel/config/index.vue
+++ b/panel/lab/internals/panel/config/index.vue
@@ -25,12 +25,3 @@
-
-
diff --git a/panel/lab/internals/panel/dialog/index.vue b/panel/lab/internals/panel/dialog/index.vue
index c6856cf59f..1d71d41ade 100644
--- a/panel/lab/internals/panel/dialog/index.vue
+++ b/panel/lab/internals/panel/dialog/index.vue
@@ -104,12 +104,3 @@
-
-
diff --git a/panel/lab/internals/panel/drag/index.vue b/panel/lab/internals/panel/drag/index.vue
index c4d28e2914..08c7a653d9 100644
--- a/panel/lab/internals/panel/drag/index.vue
+++ b/panel/lab/internals/panel/drag/index.vue
@@ -42,12 +42,3 @@
-
-
diff --git a/panel/lab/internals/panel/drawer/index.vue b/panel/lab/internals/panel/drawer/index.vue
index c773f890a3..1897ca7c62 100644
--- a/panel/lab/internals/panel/drawer/index.vue
+++ b/panel/lab/internals/panel/drawer/index.vue
@@ -118,12 +118,3 @@
-
-
diff --git a/panel/lab/internals/panel/dropdown/index.vue b/panel/lab/internals/panel/dropdown/index.vue
index 3b6f06e36a..abff35b2b9 100644
--- a/panel/lab/internals/panel/dropdown/index.vue
+++ b/panel/lab/internals/panel/dropdown/index.vue
@@ -59,12 +59,3 @@
-
-
diff --git a/panel/lab/internals/panel/events/index.vue b/panel/lab/internals/panel/events/index.vue
index 82ebbf6629..d82f13850c 100644
--- a/panel/lab/internals/panel/events/index.vue
+++ b/panel/lab/internals/panel/events/index.vue
@@ -19,12 +19,3 @@
-
-
diff --git a/panel/lab/internals/panel/language/index.vue b/panel/lab/internals/panel/language/index.vue
index 2d8dab59e2..0ed8c30afb 100644
--- a/panel/lab/internals/panel/language/index.vue
+++ b/panel/lab/internals/panel/language/index.vue
@@ -53,12 +53,3 @@
-
-
diff --git a/panel/lab/internals/panel/notification/index.vue b/panel/lab/internals/panel/notification/index.vue
index a220a39b88..2e46b6f1c1 100644
--- a/panel/lab/internals/panel/notification/index.vue
+++ b/panel/lab/internals/panel/notification/index.vue
@@ -198,12 +198,3 @@
-
-
diff --git a/panel/lab/internals/panel/panel/index.vue b/panel/lab/internals/panel/panel/index.vue
index ef839c3543..8c553c9df5 100644
--- a/panel/lab/internals/panel/panel/index.vue
+++ b/panel/lab/internals/panel/panel/index.vue
@@ -316,12 +316,3 @@ export default {
}
};
-
-
diff --git a/panel/lab/internals/panel/system/index.vue b/panel/lab/internals/panel/system/index.vue
index 1687a894ee..416a8083f8 100644
--- a/panel/lab/internals/panel/system/index.vue
+++ b/panel/lab/internals/panel/system/index.vue
@@ -52,12 +52,3 @@
-
-
diff --git a/panel/lab/internals/panel/translation/index.vue b/panel/lab/internals/panel/translation/index.vue
index 2964505801..7d96d176bf 100644
--- a/panel/lab/internals/panel/translation/index.vue
+++ b/panel/lab/internals/panel/translation/index.vue
@@ -39,12 +39,3 @@
-
-
diff --git a/panel/lab/internals/panel/upload/index.vue b/panel/lab/internals/panel/upload/index.vue
index fe88951dc1..70df640d82 100644
--- a/panel/lab/internals/panel/upload/index.vue
+++ b/panel/lab/internals/panel/upload/index.vue
@@ -78,12 +78,3 @@
-
-
diff --git a/panel/lab/internals/panel/urls/index.vue b/panel/lab/internals/panel/urls/index.vue
index b4a3dc2ccf..8bca2fd886 100644
--- a/panel/lab/internals/panel/urls/index.vue
+++ b/panel/lab/internals/panel/urls/index.vue
@@ -20,12 +20,3 @@
-
-
diff --git a/panel/lab/internals/panel/user/index.vue b/panel/lab/internals/panel/user/index.vue
index cd7ef5cf38..38cc037aca 100644
--- a/panel/lab/internals/panel/user/index.vue
+++ b/panel/lab/internals/panel/user/index.vue
@@ -49,12 +49,3 @@
-
-
diff --git a/panel/lab/internals/panel/view/index.vue b/panel/lab/internals/panel/view/index.vue
index d683b7c834..e9b833bf1b 100644
--- a/panel/lab/internals/panel/view/index.vue
+++ b/panel/lab/internals/panel/view/index.vue
@@ -185,12 +185,3 @@
-
-
diff --git a/panel/src/components/Lab/PlaygroundView.vue b/panel/src/components/Lab/PlaygroundView.vue
index e5fe4b7d64..913377d26c 100644
--- a/panel/src/components/Lab/PlaygroundView.vue
+++ b/panel/src/components/Lab/PlaygroundView.vue
@@ -126,6 +126,13 @@ export default {
margin-bottom: 0;
}
+.k-lab-examples h2 {
+ margin-bottom: var(--spacing-6);
+}
+.k-lab-examples * + h2 {
+ margin-top: var(--spacing-12);
+}
+
.k-lab-input-examples .k-lab-example-canvas:has(:invalid) {
outline: 2px solid var(--color-red-500);
outline-offset: -2px;
diff --git a/panel/src/helpers/array.js b/panel/src/helpers/array.js
index 4210b129d7..a54c94de09 100644
--- a/panel/src/helpers/array.js
+++ b/panel/src/helpers/array.js
@@ -2,6 +2,8 @@ import sort from "./sort";
import "./regex";
/**
+ * Creates an array from an object
+ *
* @param {Array|Object} object
* @returns {Array}
*/
From 0373e4ffcb3d03fee8b57b5d37abb1831906c8db Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 12:18:51 +0100
Subject: [PATCH 061/202] Clean up `Dir::inventory()` methods
---
src/Filesystem/Dir.php | 120 +++++++++++++++++++++++------------------
1 file changed, 67 insertions(+), 53 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index c03fe8cccf..5bf086c017 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -220,71 +220,58 @@ public static function inventory(
array|null $contentIgnore = null,
bool $multilang = false
): array {
- $dir = realpath($dir);
-
$inventory = [
'children' => [],
'files' => [],
'template' => 'default',
];
+ $dir = realpath($dir);
+
if ($dir === false) {
return $inventory;
}
- $items = static::read($dir, $contentIgnore);
-
// a temporary store for all content files
$content = [];
- // sort all items naturally to avoid sorting issues later
+ // read and sort all items naturally to avoid sorting issues later
+ $items = static::read($dir, $contentIgnore);
natsort($items);
foreach ($items as $item) {
- // ignore all items with a leading dot
+ // ignore all items with a leading dot or underscore
if (in_array(substr($item, 0, 1), ['.', '_']) === true) {
continue;
}
$root = $dir . '/' . $item;
+ // collect all directories as children
if (is_dir($root) === true) {
- // extract the slug and num of the directory
- if (preg_match('/^([0-9]+)' . static::$numSeparator . '(.*)$/', $item, $match)) {
- $num = (int)$match[1];
- $slug = $match[2];
- } else {
- $num = null;
- $slug = $item;
- }
+ $inventory['children'][] = static::inventoryChild($item, $root);
+ continue;
+ }
- $inventory['children'][] = [
- 'dirname' => $item,
- 'model' => null,
- 'num' => $num,
- 'root' => $root,
- 'slug' => $slug,
- ];
- } else {
- $extension = pathinfo($item, PATHINFO_EXTENSION);
+ $extension = pathinfo($item, PATHINFO_EXTENSION);
- switch ($extension) {
- case 'htm':
- case 'html':
- case 'php':
- // don't track those files
- break;
- case $contentExtension:
- $content[] = pathinfo($item, PATHINFO_FILENAME);
- break;
- default:
- $inventory['files'][$item] = [
- 'filename' => $item,
- 'extension' => $extension,
- 'root' => $root,
- ];
- }
+ // don't track files with these extensions
+ if (in_array($extension, ['htm', 'html', 'php']) === true) {
+ continue;
}
+
+ // collect all content files separately
+ if ($extension === $contentExtension) {
+ $content[] = pathinfo($item, PATHINFO_FILENAME);
+ continue;
+ }
+
+ // collect all other files
+ $inventory['files'][$item] = [
+ 'filename' => $item,
+ 'extension' => $extension,
+ 'root' => $root,
+ ];
}
// remove the language codes from all content filenames
@@ -303,26 +290,48 @@ public static function inventory(
}
/**
- * Take all content files,
- * remove those who are meta files and
- * detect the main content file
+ * Collect information for a child for the inventory
*/
- protected static function inventoryContent(array $inventory, array $content): array
- {
- // filter meta files from the content file
+ protected static function inventoryChild(
+ string $item,
+ string $root
+ ): array {
+ // extract the slug and num of the directory
+ if (preg_match('/^([0-9]+)' . static::$numSeparator . '(.*)$/', $item, $match)) {
+ $num = (int)$match[1];
+ $slug = $match[2];
+ }
+
+ return [
+ 'dirname' => $item,
+ 'model' => null,
+ 'num' => $num ?? null,
+ 'root' => $root,
+ 'slug' => $slug ?? $item,
+ ];
+ }
+
+ /**
+ * Take all content files, remove those who are meta files
+ * and detect the main content file
+ */
+ protected static function inventoryContent(
+ array $inventory,
+ array $content
+ ): array {
+ // if no content files are found,apply default template
if (empty($content) === true) {
- $inventory['template'] = 'default';
- return $inventory;
+ return [...$inventory, 'template' => 'default'];
}
- foreach ($content as $contentName) {
- // could be a meta file. i.e. cover.jpg
- if (isset($inventory['files'][$contentName]) === true) {
+ foreach ($content as $name) {
+ // is a meta file corresponding to an actual file, i.e. cover.jpg
+ if (isset($inventory['files'][$name]) === true) {
continue;
}
// it's most likely the template
- $inventory['template'] = $contentName;
+ $inventory['template'] = $name;
}
return $inventory;
@@ -337,17 +346,22 @@ protected static function inventoryModels(
string $contentExtension,
bool $multilang = false
): array {
+ $models = array_keys(Page::$models);
+
// inject models
if (
empty($inventory['children']) === false &&
- empty(Page::$models) === false
+ empty($models) === false
) {
if ($multilang === true) {
$contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
}
+ // for each child, try to find a model
foreach ($inventory['children'] as $key => $child) {
- foreach (Page::$models as $modelName => $modelClass) {
+ // look if a content file can be found
+ // for any of the available models
+ foreach ($models as $modelName) {
if (file_exists($child['root'] . '/' . $modelName . '.' . $contentExtension) === true) {
$inventory['children'][$key]['model'] = $modelName;
break;
From 787a5e1a8d4d45b54b628c66bbb4824e34352c69 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 12:23:23 +0100
Subject: [PATCH 062/202] Add more unit tests for `Dir::inventory()`
---
tests/Filesystem/DirTest.php | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/Filesystem/DirTest.php b/tests/Filesystem/DirTest.php
index 25a75e2572..0b142e6962 100644
--- a/tests/Filesystem/DirTest.php
+++ b/tests/Filesystem/DirTest.php
@@ -280,7 +280,9 @@ public function testInventory()
'2_project-b',
'cover.jpg',
'cover.jpg.txt',
- 'projects.txt'
+ 'projects.txt',
+ '_ignore.txt',
+ '.invisible'
]);
$this->assertSame('project-a', $inventory['children'][0]['slug']);
@@ -291,6 +293,8 @@ public function testInventory()
$this->assertSame('cover.jpg', $inventory['files']['cover.jpg']['filename']);
$this->assertSame('jpg', $inventory['files']['cover.jpg']['extension']);
+ $this->assertArrayNotHasKey('_ignore.txt', $inventory['files']);
+ $this->assertArrayNotHasKey('.invisible', $inventory['files']);
$this->assertSame('projects', $inventory['template']);
}
From 2270836ff6316d092a9c179280608456f126b87d Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 12:30:16 +0100
Subject: [PATCH 063/202] =?UTF-8?q?`Dir::=20inventoryContent`=E2=86=92=20`?=
=?UTF-8?q?Dir::inventoryTemplate`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Filesystem/Dir.php | 55 ++++++++++++++++--------------------
tests/Filesystem/DirTest.php | 5 ++++
2 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index 5bf086c017..8e0f5a2772 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -283,10 +283,10 @@ public static function inventory(
$content = array_unique($content);
}
- $inventory = static::inventoryContent($inventory, $content);
- $inventory = static::inventoryModels($inventory, $contentExtension, $multilang);
-
- return $inventory;
+ return [
+ ...static::inventoryModels($inventory, $contentExtension, $multilang),
+ 'template' => static::inventoryTemplate($content, $inventory['files'])
+ ];
}
/**
@@ -311,32 +311,6 @@ protected static function inventoryChild(
];
}
- /**
- * Take all content files, remove those who are meta files
- * and detect the main content file
- */
- protected static function inventoryContent(
- array $inventory,
- array $content
- ): array {
- // if no content files are found,apply default template
- if (empty($content) === true) {
- return [...$inventory, 'template' => 'default'];
- }
-
- foreach ($content as $name) {
- // is a meta file corresponding to an actual file, i.e. cover.jpg
- if (isset($inventory['files'][$name]) === true) {
- continue;
- }
-
- // it's most likely the template
- $inventory['template'] = $name;
- }
-
- return $inventory;
- }
-
/**
* Go through all inventory children
* and inject a model for each
@@ -373,6 +347,27 @@ protected static function inventoryModels(
return $inventory;
}
+ /**
+ * Determines the main template for the inventory
+ * from all collected content files, ignory file meta files
+ */
+ protected static function inventoryTemplate(
+ array $content,
+ array $files,
+ ): string {
+ foreach ($content as $name) {
+ // is a meta file corresponding to an actual file, i.e. cover.jpg
+ if (isset($files[$name]) === true) {
+ continue;
+ }
+
+ // it's most likely the template
+ $template = $name;
+ }
+
+ return $template ?? 'default';
+ }
+
/**
* Create a (symbolic) link to a directory
*/
diff --git a/tests/Filesystem/DirTest.php b/tests/Filesystem/DirTest.php
index 0b142e6962..a8015fd57d 100644
--- a/tests/Filesystem/DirTest.php
+++ b/tests/Filesystem/DirTest.php
@@ -375,6 +375,7 @@ public function testInventoryFileSorting()
/**
* @covers ::inventory
+ * @covers ::inventoryTemplate
*/
public function testInventoryMissingTemplate()
{
@@ -389,6 +390,7 @@ public function testInventoryMissingTemplate()
/**
* @covers ::inventory
+ * @covers ::inventoryTemplate
*/
public function testInventoryTemplateWithDotInFilename()
{
@@ -404,6 +406,7 @@ public function testInventoryTemplateWithDotInFilename()
/**
* @covers ::inventory
+ * @covers ::inventoryTemplate
*/
public function testInventoryExtension()
{
@@ -419,6 +422,7 @@ public function testInventoryExtension()
/**
* @covers ::inventory
+ * @covers ::inventoryTemplate
*/
public function testInventoryIgnore()
{
@@ -433,6 +437,7 @@ public function testInventoryIgnore()
/**
* @covers ::inventory
+ * @covers ::inventoryTemplate
*/
public function testInventoryMultilang()
{
From af4af8daba4e05f5814d43506d22cb9ef020b438 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 12:52:12 +0100
Subject: [PATCH 064/202] Revert less performant code change
---
src/Filesystem/Dir.php | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index 8e0f5a2772..f3b051a9cd 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -320,12 +320,10 @@ protected static function inventoryModels(
string $contentExtension,
bool $multilang = false
): array {
- $models = array_keys(Page::$models);
-
// inject models
if (
empty($inventory['children']) === false &&
- empty($models) === false
+ empty(Page::$models) === false
) {
if ($multilang === true) {
$contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
@@ -335,7 +333,7 @@ protected static function inventoryModels(
foreach ($inventory['children'] as $key => $child) {
// look if a content file can be found
// for any of the available models
- foreach ($models as $modelName) {
+ foreach (Page::$models as $modelName => $modelClass) {
if (file_exists($child['root'] . '/' . $modelName . '.' . $contentExtension) === true) {
$inventory['children'][$key]['model'] = $modelName;
break;
From 894e5b646253c51c8d02d6588ad729ba0a1f6341 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 13:21:40 +0100
Subject: [PATCH 065/202] Add performance testing
---
composer.json | 2 +-
performance/Filesystem/DirBench.php | 72 +++++++++++++++++++
.../fixtures/inventory/models/a/a.txt | 0
.../fixtures/inventory/models/b/b.txt | 0
.../fixtures/inventory/models/b/d/d.txt | 0
.../fixtures/inventory/models/c/c.txt | 0
.../fixtures/inventory/models/e/e.txt | 0
.../fixtures/inventory/models/f/f.txt | 0
.../fixtures/inventory/models/g/g.txt | 0
.../fixtures/inventory/models/h/h.txt | 0
.../fixtures/inventory/models/i/i.txt | 0
.../fixtures/inventory/models/j/j.txt | 0
.../fixtures/inventory/models/k/k.txt | 0
.../fixtures/inventory/models/l/l.txt | 0
.../fixtures/inventory/models/m/m.txt | 0
.../fixtures/inventory/models/n/n.txt | 0
.../fixtures/inventory/models/o/o.txt | 0
.../fixtures/inventory/models/p/p.txt | 0
.../fixtures/inventory/models/q/q.txt | 0
.../fixtures/inventory/models/r/r.txt | 0
.../fixtures/inventory/models/s/s.txt | 0
.../fixtures/inventory/models/t/t.txt | 0
.../fixtures/inventory/models/u/u.txt | 0
.../fixtures/inventory/models/v/v.txt | 0
.../fixtures/inventory/models/w/w.txt | 0
.../fixtures/inventory/models/x/x.txt | 0
.../fixtures/inventory/models/y/y.txt | 0
.../fixtures/inventory/models/z/z.txt | 0
performance/bootstrap.php | 3 +
29 files changed, 76 insertions(+), 1 deletion(-)
create mode 100644 performance/Filesystem/DirBench.php
create mode 100644 performance/Filesystem/fixtures/inventory/models/a/a.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/b/b.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/b/d/d.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/c/c.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/e/e.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/f/f.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/g/g.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/h/h.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/i/i.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/j/j.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/k/k.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/l/l.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/m/m.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/n/n.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/o/o.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/p/p.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/q/q.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/r/r.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/s/s.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/t/t.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/u/u.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/v/v.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/w/w.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/x/x.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/y/y.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/z/z.txt
create mode 100644 performance/bootstrap.php
diff --git a/composer.json b/composer.json
index e8293c5f77..8f7d5f9619 100644
--- a/composer.json
+++ b/composer.json
@@ -90,7 +90,6 @@
]
},
"scripts": {
- "post-update-cmd": "curl -o cacert.pem https://curl.se/ca/cacert.pem",
"analyze": [
"@analyze:composer",
"@analyze:psalm",
@@ -108,6 +107,7 @@
"@test"
],
"fix": "php-cs-fixer fix",
+ "post-update-cmd": "curl -o cacert.pem https://curl.se/ca/cacert.pem",
"test": "phpunit",
"test:coverage": "XDEBUG_MODE=coverage phpunit --coverage-html=tests/coverage",
"zip": "composer archive --format=zip --file=dist"
diff --git a/performance/Filesystem/DirBench.php b/performance/Filesystem/DirBench.php
new file mode 100644
index 0000000000..03f37aaf9f
--- /dev/null
+++ b/performance/Filesystem/DirBench.php
@@ -0,0 +1,72 @@
+ 'A'
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+
+ public function benchInventoryTwoModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B'
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+
+ public function benchInventoryManyModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J',
+ 'k' => 'K',
+ 'l' => 'L',
+ 'm' => 'M',
+ 'n' => 'N',
+ 'o' => 'O',
+ 'p' => 'P',
+ 'q' => 'Q',
+ 'r' => 'R',
+ 's' => 'S',
+ 't' => 'T',
+ 'u' => 'U',
+ 'v' => 'V',
+ 'w' => 'W',
+ 'x' => 'X',
+ 'y' => 'Y',
+ 'z' => 'Z'
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+}
diff --git a/performance/Filesystem/fixtures/inventory/models/a/a.txt b/performance/Filesystem/fixtures/inventory/models/a/a.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/b/b.txt b/performance/Filesystem/fixtures/inventory/models/b/b.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/b/d/d.txt b/performance/Filesystem/fixtures/inventory/models/b/d/d.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/c/c.txt b/performance/Filesystem/fixtures/inventory/models/c/c.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/e/e.txt b/performance/Filesystem/fixtures/inventory/models/e/e.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/f/f.txt b/performance/Filesystem/fixtures/inventory/models/f/f.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/g/g.txt b/performance/Filesystem/fixtures/inventory/models/g/g.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/h/h.txt b/performance/Filesystem/fixtures/inventory/models/h/h.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/i/i.txt b/performance/Filesystem/fixtures/inventory/models/i/i.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/j/j.txt b/performance/Filesystem/fixtures/inventory/models/j/j.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/k/k.txt b/performance/Filesystem/fixtures/inventory/models/k/k.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/l/l.txt b/performance/Filesystem/fixtures/inventory/models/l/l.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/m/m.txt b/performance/Filesystem/fixtures/inventory/models/m/m.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/n/n.txt b/performance/Filesystem/fixtures/inventory/models/n/n.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/o/o.txt b/performance/Filesystem/fixtures/inventory/models/o/o.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/p/p.txt b/performance/Filesystem/fixtures/inventory/models/p/p.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/q/q.txt b/performance/Filesystem/fixtures/inventory/models/q/q.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/r/r.txt b/performance/Filesystem/fixtures/inventory/models/r/r.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/s/s.txt b/performance/Filesystem/fixtures/inventory/models/s/s.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/t/t.txt b/performance/Filesystem/fixtures/inventory/models/t/t.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/u/u.txt b/performance/Filesystem/fixtures/inventory/models/u/u.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/v/v.txt b/performance/Filesystem/fixtures/inventory/models/v/v.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/w/w.txt b/performance/Filesystem/fixtures/inventory/models/w/w.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/x/x.txt b/performance/Filesystem/fixtures/inventory/models/x/x.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/y/y.txt b/performance/Filesystem/fixtures/inventory/models/y/y.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/z/z.txt b/performance/Filesystem/fixtures/inventory/models/z/z.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/bootstrap.php b/performance/bootstrap.php
new file mode 100644
index 0000000000..6c8c4f51b9
--- /dev/null
+++ b/performance/bootstrap.php
@@ -0,0 +1,3 @@
+
Date: Sun, 21 Jan 2024 13:30:24 +0100
Subject: [PATCH 066/202] =?UTF-8?q?Merge=20`Dir::inventoryModels`=20?=
=?UTF-8?q?=E2=86=92=20=20`::inventoryChild`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Filesystem/Dir.php | 78 ++++++++++++++++++------------------------
1 file changed, 34 insertions(+), 44 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index f3b051a9cd..da5e3d2b8c 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -249,7 +249,12 @@ public static function inventory(
// collect all directories as children
if (is_dir($root) === true) {
- $inventory['children'][] = static::inventoryChild($item, $root);
+ $inventory['children'][] = static::inventoryChild(
+ $item,
+ $root,
+ $contentExtension,
+ $multilang
+ );
continue;
}
@@ -262,7 +267,14 @@ public static function inventory(
// collect all content files separately
if ($extension === $contentExtension) {
- $content[] = pathinfo($item, PATHINFO_FILENAME);
+ $filename = pathinfo($item, PATHINFO_FILENAME);
+
+ // remove the language codes from all content filenames
+ if ($multilang === true) {
+ $filename = pathinfo($filename, PATHINFO_FILENAME);
+ }
+
+ $content[] = $filename;
continue;
}
@@ -274,17 +286,10 @@ public static function inventory(
];
}
- // remove the language codes from all content filenames
- if ($multilang === true) {
- foreach ($content as $key => $filename) {
- $content[$key] = pathinfo($filename, PATHINFO_FILENAME);
- }
-
- $content = array_unique($content);
- }
+ $content = array_unique($content);
return [
- ...static::inventoryModels($inventory, $contentExtension, $multilang),
+ ...$inventory,
'template' => static::inventoryTemplate($content, $inventory['files'])
];
}
@@ -294,7 +299,9 @@ public static function inventory(
*/
protected static function inventoryChild(
string $item,
- string $root
+ string $root,
+ string $contentExtension = 'txt',
+ bool $multilang = false
): array {
// extract the slug and num of the directory
if (preg_match('/^([0-9]+)' . static::$numSeparator . '(.*)$/', $item, $match)) {
@@ -302,47 +309,30 @@ protected static function inventoryChild(
$slug = $match[2];
}
- return [
- 'dirname' => $item,
- 'model' => null,
- 'num' => $num ?? null,
- 'root' => $root,
- 'slug' => $slug ?? $item,
- ];
- }
-
- /**
- * Go through all inventory children
- * and inject a model for each
- */
- protected static function inventoryModels(
- array $inventory,
- string $contentExtension,
- bool $multilang = false
- ): array {
+ // determine the model
// inject models
- if (
- empty($inventory['children']) === false &&
- empty(Page::$models) === false
- ) {
+ if (empty(Page::$models) === false) {
if ($multilang === true) {
$contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
}
- // for each child, try to find a model
- foreach ($inventory['children'] as $key => $child) {
- // look if a content file can be found
- // for any of the available models
- foreach (Page::$models as $modelName => $modelClass) {
- if (file_exists($child['root'] . '/' . $modelName . '.' . $contentExtension) === true) {
- $inventory['children'][$key]['model'] = $modelName;
- break;
- }
+ // look if a content file can be found
+ // for any of the available models
+ foreach (Page::$models as $modelName => $modelClass) {
+ if (file_exists($root . '/' . $modelName . '.' . $contentExtension) === true) {
+ $model = $modelName;
+ break;
}
}
}
- return $inventory;
+ return [
+ 'dirname' => $item,
+ 'model' => $model ?? null,
+ 'num' => $num ?? null,
+ 'root' => $root,
+ 'slug' => $slug ?? $item,
+ ];
}
/**
From feed115fef61ce2beb1e688950a3ecdac6fe8548 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 13:37:01 +0100
Subject: [PATCH 067/202] Add some comments
---
src/Filesystem/Dir.php | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index da5e3d2b8c..53c52536bf 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -239,6 +239,7 @@ public static function inventory(
$items = static::read($dir, $contentIgnore);
natsort($items);
+ // loop through all directory items and collect all relevant information
foreach ($items as $item) {
// ignore all items with a leading dot or underscore
if (in_array(substr($item, 0, 1), ['.', '_']) === true) {
@@ -265,7 +266,8 @@ public static function inventory(
continue;
}
- // collect all content files separately
+ // collect all content files separately,
+ // not as inventory entries
if ($extension === $contentExtension) {
$filename = pathinfo($item, PATHINFO_FILENAME);
@@ -310,16 +312,16 @@ protected static function inventoryChild(
}
// determine the model
- // inject models
if (empty(Page::$models) === false) {
if ($multilang === true) {
- $contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
+ $code = App::instance()->defaultLanguage()->code();
+ $contentExtension = $code . '.' . $contentExtension;
}
// look if a content file can be found
// for any of the available models
foreach (Page::$models as $modelName => $modelClass) {
- if (file_exists($root . '/' . $modelName . '.' . $contentExtension) === true) {
+ if (file_exists($root . '/' . $modelName . '.' . $contentExtension)) {
$model = $modelName;
break;
}
@@ -350,6 +352,7 @@ protected static function inventoryTemplate(
}
// it's most likely the template
+ // (will overwrite and use the last match for historic reasons)
$template = $name;
}
From 50d9b0f464f0ebc100067d6566733f024d2f5939 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 13:41:10 +0100
Subject: [PATCH 068/202] Extract num and slug without regex
---
src/Filesystem/Dir.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index 53c52536bf..17337b6352 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -306,9 +306,9 @@ protected static function inventoryChild(
bool $multilang = false
): array {
// extract the slug and num of the directory
- if (preg_match('/^([0-9]+)' . static::$numSeparator . '(.*)$/', $item, $match)) {
- $num = (int)$match[1];
- $slug = $match[2];
+ if ($separator = strpos($item, static::$numSeparator)) {
+ $num = (int)substr($item, 0, $separator);
+ $slug = substr($item, $separator + 1);
}
// determine the model
From 88fbe90af0ce669629415e14e378c77a99d3d58a Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 13:54:11 +0100
Subject: [PATCH 069/202] More extensive performance test setup
---
performance/Filesystem/DirBench.php | 57 +++++++++++++++++++
.../inventory/models/{b/d/d.txt => a.txt} | 0
.../fixtures/inventory/models/a/bar.png | 0
.../fixtures/inventory/models/a/bar.png.txt | 0
.../fixtures/inventory/models/a/foo.jpg | 0
.../fixtures/inventory/models/a/foo.jpg.txt | 0
.../fixtures/inventory/models/b/bar.png | 0
.../fixtures/inventory/models/b/bar.png.txt | 0
.../fixtures/inventory/models/b/foo.jpg | 0
.../fixtures/inventory/models/b/foo.jpg.txt | 0
.../fixtures/inventory/models/bar.png | 0
.../fixtures/inventory/models/bar.png.txt | 0
.../fixtures/inventory/models/c/bar.png | 0
.../fixtures/inventory/models/c/bar.png.txt | 0
.../fixtures/inventory/models/c/foo.jpg | 0
.../fixtures/inventory/models/c/foo.jpg.txt | 0
.../fixtures/inventory/models/d/bar.png | 0
.../fixtures/inventory/models/d/bar.png.txt | 0
.../fixtures/inventory/models/d/d.txt | 0
.../fixtures/inventory/models/d/foo.jpg | 0
.../fixtures/inventory/models/d/foo.jpg.txt | 0
.../fixtures/inventory/models/e/bar.png | 0
.../fixtures/inventory/models/e/bar.png.txt | 0
.../fixtures/inventory/models/e/foo.jpg | 0
.../fixtures/inventory/models/e/foo.jpg.txt | 0
.../fixtures/inventory/models/f/bar.png | 0
.../fixtures/inventory/models/f/bar.png.txt | 0
.../fixtures/inventory/models/f/foo.jpg | 0
.../fixtures/inventory/models/f/foo.jpg.txt | 0
.../fixtures/inventory/models/foo.jpg | 0
.../fixtures/inventory/models/foo.jpg.txt | 0
.../fixtures/inventory/models/g/bar.png | 0
.../fixtures/inventory/models/g/bar.png.txt | 0
.../fixtures/inventory/models/g/foo.jpg | 0
.../fixtures/inventory/models/g/foo.jpg.txt | 0
.../fixtures/inventory/models/h/bar.png | 0
.../fixtures/inventory/models/h/bar.png.txt | 0
.../fixtures/inventory/models/h/foo.jpg | 0
.../fixtures/inventory/models/h/foo.jpg.txt | 0
.../fixtures/inventory/models/i/bar.png | 0
.../fixtures/inventory/models/i/bar.png.txt | 0
.../fixtures/inventory/models/i/foo.jpg | 0
.../fixtures/inventory/models/i/foo.jpg.txt | 0
.../fixtures/inventory/models/j/bar.png | 0
.../fixtures/inventory/models/j/bar.png.txt | 0
.../fixtures/inventory/models/j/foo.jpg | 0
.../fixtures/inventory/models/j/foo.jpg.txt | 0
.../fixtures/inventory/models/k/bar.png | 0
.../fixtures/inventory/models/k/bar.png.txt | 0
.../fixtures/inventory/models/k/foo.jpg | 0
.../fixtures/inventory/models/k/foo.jpg.txt | 0
.../fixtures/inventory/models/l/bar.png | 0
.../fixtures/inventory/models/l/bar.png.txt | 0
.../fixtures/inventory/models/l/foo.jpg | 0
.../fixtures/inventory/models/l/foo.jpg.txt | 0
.../fixtures/inventory/models/m/bar.png | 0
.../fixtures/inventory/models/m/bar.png.txt | 0
.../fixtures/inventory/models/m/foo.jpg | 0
.../fixtures/inventory/models/m/foo.jpg.txt | 0
.../fixtures/inventory/models/n/bar.png | 0
.../fixtures/inventory/models/n/bar.png.txt | 0
.../fixtures/inventory/models/n/foo.jpg | 0
.../fixtures/inventory/models/n/foo.jpg.txt | 0
.../fixtures/inventory/models/o/bar.png | 0
.../fixtures/inventory/models/o/bar.png.txt | 0
.../fixtures/inventory/models/o/foo.jpg | 0
.../fixtures/inventory/models/o/foo.jpg.txt | 0
.../fixtures/inventory/models/p/bar.png | 0
.../fixtures/inventory/models/p/bar.png.txt | 0
.../fixtures/inventory/models/p/foo.jpg | 0
.../fixtures/inventory/models/p/foo.jpg.txt | 0
.../fixtures/inventory/models/q/bar.png | 0
.../fixtures/inventory/models/q/bar.png.txt | 0
.../fixtures/inventory/models/q/foo.jpg | 0
.../fixtures/inventory/models/q/foo.jpg.txt | 0
.../fixtures/inventory/models/r/bar.png | 0
.../fixtures/inventory/models/r/bar.png.txt | 0
.../fixtures/inventory/models/r/foo.jpg | 0
.../fixtures/inventory/models/r/foo.jpg.txt | 0
.../fixtures/inventory/models/s/bar.png | 0
.../fixtures/inventory/models/s/bar.png.txt | 0
.../fixtures/inventory/models/s/foo.jpg | 0
.../fixtures/inventory/models/s/foo.jpg.txt | 0
.../fixtures/inventory/models/t/bar.png | 0
.../fixtures/inventory/models/t/bar.png.txt | 0
.../fixtures/inventory/models/t/foo.jpg | 0
.../fixtures/inventory/models/t/foo.jpg.txt | 0
.../fixtures/inventory/models/u/bar.png | 0
.../fixtures/inventory/models/u/bar.png.txt | 0
.../fixtures/inventory/models/u/foo.jpg | 0
.../fixtures/inventory/models/u/foo.jpg.txt | 0
.../fixtures/inventory/models/v/bar.png | 0
.../fixtures/inventory/models/v/bar.png.txt | 0
.../fixtures/inventory/models/v/foo.jpg | 0
.../fixtures/inventory/models/v/foo.jpg.txt | 0
.../fixtures/inventory/models/w/bar.png | 0
.../fixtures/inventory/models/w/bar.png.txt | 0
.../fixtures/inventory/models/w/foo.jpg | 0
.../fixtures/inventory/models/w/foo.jpg.txt | 0
.../fixtures/inventory/models/x/bar.png | 0
.../fixtures/inventory/models/x/bar.png.txt | 0
.../fixtures/inventory/models/x/foo.jpg | 0
.../fixtures/inventory/models/x/foo.jpg.txt | 0
.../fixtures/inventory/models/y/bar.png | 0
.../fixtures/inventory/models/y/bar.png.txt | 0
.../fixtures/inventory/models/y/foo.jpg | 0
.../fixtures/inventory/models/y/foo.jpg.txt | 0
.../fixtures/inventory/models/z/bar.png | 0
.../fixtures/inventory/models/z/bar.png.txt | 0
.../fixtures/inventory/models/z/foo.jpg | 0
.../fixtures/inventory/models/z/foo.jpg.txt | 0
111 files changed, 57 insertions(+)
rename performance/Filesystem/fixtures/inventory/models/{b/d/d.txt => a.txt} (100%)
create mode 100644 performance/Filesystem/fixtures/inventory/models/a/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/a/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/a/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/a/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/b/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/b/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/b/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/b/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/c/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/c/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/c/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/c/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/d/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/d/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/d/d.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/d/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/d/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/e/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/e/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/e/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/e/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/f/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/f/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/f/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/f/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/g/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/g/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/g/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/g/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/h/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/h/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/h/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/h/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/i/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/i/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/i/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/i/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/j/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/j/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/j/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/j/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/k/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/k/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/k/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/k/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/l/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/l/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/l/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/l/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/m/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/m/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/m/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/m/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/n/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/n/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/n/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/n/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/o/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/o/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/o/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/o/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/p/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/p/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/p/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/p/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/q/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/q/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/q/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/q/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/r/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/r/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/r/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/r/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/s/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/s/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/s/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/s/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/t/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/t/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/t/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/t/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/u/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/u/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/u/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/u/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/v/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/v/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/v/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/v/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/w/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/w/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/w/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/w/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/x/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/x/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/x/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/x/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/y/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/y/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/y/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/y/foo.jpg.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/z/bar.png
create mode 100644 performance/Filesystem/fixtures/inventory/models/z/bar.png.txt
create mode 100644 performance/Filesystem/fixtures/inventory/models/z/foo.jpg
create mode 100644 performance/Filesystem/fixtures/inventory/models/z/foo.jpg.txt
diff --git a/performance/Filesystem/DirBench.php b/performance/Filesystem/DirBench.php
index 03f37aaf9f..1fc92dbb2a 100644
--- a/performance/Filesystem/DirBench.php
+++ b/performance/Filesystem/DirBench.php
@@ -34,6 +34,63 @@ public function benchInventoryTwoModels()
Page::$models = [];
}
+ public function benchInventoryThreeModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C'
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+
+ public function benchInventoryFourModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D'
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+
+ public function benchInventoryFiveModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E'
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+
+ public function benchInventorySixModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E',
+ ];
+
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ Page::$models = [];
+ }
+
public function benchInventoryManyModels()
{
Page::$models = [
diff --git a/performance/Filesystem/fixtures/inventory/models/b/d/d.txt b/performance/Filesystem/fixtures/inventory/models/a.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/b/d/d.txt
rename to performance/Filesystem/fixtures/inventory/models/a.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/a/bar.png b/performance/Filesystem/fixtures/inventory/models/a/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/a/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/a/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/a/foo.jpg b/performance/Filesystem/fixtures/inventory/models/a/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/a/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/a/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/b/bar.png b/performance/Filesystem/fixtures/inventory/models/b/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/b/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/b/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/b/foo.jpg b/performance/Filesystem/fixtures/inventory/models/b/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/b/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/b/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/bar.png b/performance/Filesystem/fixtures/inventory/models/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/c/bar.png b/performance/Filesystem/fixtures/inventory/models/c/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/c/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/c/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/c/foo.jpg b/performance/Filesystem/fixtures/inventory/models/c/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/c/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/c/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/d/bar.png b/performance/Filesystem/fixtures/inventory/models/d/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/d/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/d/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/d/d.txt b/performance/Filesystem/fixtures/inventory/models/d/d.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/d/foo.jpg b/performance/Filesystem/fixtures/inventory/models/d/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/d/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/d/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/e/bar.png b/performance/Filesystem/fixtures/inventory/models/e/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/e/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/e/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/e/foo.jpg b/performance/Filesystem/fixtures/inventory/models/e/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/e/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/e/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/f/bar.png b/performance/Filesystem/fixtures/inventory/models/f/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/f/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/f/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/f/foo.jpg b/performance/Filesystem/fixtures/inventory/models/f/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/f/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/f/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/foo.jpg b/performance/Filesystem/fixtures/inventory/models/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/g/bar.png b/performance/Filesystem/fixtures/inventory/models/g/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/g/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/g/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/g/foo.jpg b/performance/Filesystem/fixtures/inventory/models/g/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/g/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/g/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/h/bar.png b/performance/Filesystem/fixtures/inventory/models/h/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/h/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/h/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/h/foo.jpg b/performance/Filesystem/fixtures/inventory/models/h/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/h/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/h/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/i/bar.png b/performance/Filesystem/fixtures/inventory/models/i/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/i/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/i/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/i/foo.jpg b/performance/Filesystem/fixtures/inventory/models/i/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/i/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/i/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/j/bar.png b/performance/Filesystem/fixtures/inventory/models/j/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/j/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/j/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/j/foo.jpg b/performance/Filesystem/fixtures/inventory/models/j/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/j/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/j/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/k/bar.png b/performance/Filesystem/fixtures/inventory/models/k/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/k/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/k/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/k/foo.jpg b/performance/Filesystem/fixtures/inventory/models/k/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/k/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/k/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/l/bar.png b/performance/Filesystem/fixtures/inventory/models/l/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/l/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/l/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/l/foo.jpg b/performance/Filesystem/fixtures/inventory/models/l/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/l/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/l/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/m/bar.png b/performance/Filesystem/fixtures/inventory/models/m/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/m/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/m/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/m/foo.jpg b/performance/Filesystem/fixtures/inventory/models/m/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/m/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/m/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/n/bar.png b/performance/Filesystem/fixtures/inventory/models/n/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/n/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/n/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/n/foo.jpg b/performance/Filesystem/fixtures/inventory/models/n/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/n/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/n/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/o/bar.png b/performance/Filesystem/fixtures/inventory/models/o/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/o/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/o/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/o/foo.jpg b/performance/Filesystem/fixtures/inventory/models/o/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/o/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/o/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/p/bar.png b/performance/Filesystem/fixtures/inventory/models/p/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/p/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/p/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/p/foo.jpg b/performance/Filesystem/fixtures/inventory/models/p/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/p/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/p/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/q/bar.png b/performance/Filesystem/fixtures/inventory/models/q/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/q/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/q/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/q/foo.jpg b/performance/Filesystem/fixtures/inventory/models/q/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/q/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/q/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/r/bar.png b/performance/Filesystem/fixtures/inventory/models/r/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/r/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/r/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/r/foo.jpg b/performance/Filesystem/fixtures/inventory/models/r/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/r/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/r/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/s/bar.png b/performance/Filesystem/fixtures/inventory/models/s/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/s/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/s/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/s/foo.jpg b/performance/Filesystem/fixtures/inventory/models/s/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/s/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/s/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/t/bar.png b/performance/Filesystem/fixtures/inventory/models/t/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/t/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/t/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/t/foo.jpg b/performance/Filesystem/fixtures/inventory/models/t/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/t/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/t/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/u/bar.png b/performance/Filesystem/fixtures/inventory/models/u/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/u/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/u/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/u/foo.jpg b/performance/Filesystem/fixtures/inventory/models/u/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/u/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/u/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/v/bar.png b/performance/Filesystem/fixtures/inventory/models/v/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/v/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/v/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/v/foo.jpg b/performance/Filesystem/fixtures/inventory/models/v/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/v/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/v/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/w/bar.png b/performance/Filesystem/fixtures/inventory/models/w/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/w/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/w/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/w/foo.jpg b/performance/Filesystem/fixtures/inventory/models/w/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/w/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/w/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/x/bar.png b/performance/Filesystem/fixtures/inventory/models/x/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/x/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/x/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/x/foo.jpg b/performance/Filesystem/fixtures/inventory/models/x/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/x/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/x/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/y/bar.png b/performance/Filesystem/fixtures/inventory/models/y/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/y/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/y/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/y/foo.jpg b/performance/Filesystem/fixtures/inventory/models/y/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/y/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/y/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/z/bar.png b/performance/Filesystem/fixtures/inventory/models/z/bar.png
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/z/bar.png.txt b/performance/Filesystem/fixtures/inventory/models/z/bar.png.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/z/foo.jpg b/performance/Filesystem/fixtures/inventory/models/z/foo.jpg
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/performance/Filesystem/fixtures/inventory/models/z/foo.jpg.txt b/performance/Filesystem/fixtures/inventory/models/z/foo.jpg.txt
new file mode 100644
index 0000000000..e69de29bb2
From e8c63078465073b9ca101a8a86a00fec8ab1482b Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 13:54:54 +0100
Subject: [PATCH 070/202] Exclude phpbench files from export
From db6252971d8c67b087f8f4656537a6346f95e990 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 14:03:37 +0100
Subject: [PATCH 071/202] Tweak DirBench cases
---
performance/Filesystem/DirBench.php | 41 ++++++++++++++++-------------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/performance/Filesystem/DirBench.php b/performance/Filesystem/DirBench.php
index 1fc92dbb2a..6b74132e74 100644
--- a/performance/Filesystem/DirBench.php
+++ b/performance/Filesystem/DirBench.php
@@ -34,26 +34,14 @@ public function benchInventoryTwoModels()
Page::$models = [];
}
- public function benchInventoryThreeModels()
- {
- Page::$models = [
- 'a' => 'A',
- 'b' => 'B',
- 'c' => 'C'
- ];
-
- Dir::inventory(__DIR__ . '/fixtures/inventory/models');
-
- Page::$models = [];
- }
-
- public function benchInventoryFourModels()
+ public function benchInventoryFiveModels()
{
Page::$models = [
'a' => 'A',
'b' => 'B',
'c' => 'C',
- 'd' => 'D'
+ 'd' => 'D',
+ 'e' => 'E'
];
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
@@ -61,14 +49,19 @@ public function benchInventoryFourModels()
Page::$models = [];
}
- public function benchInventoryFiveModels()
+ public function benchInventory10Models()
{
Page::$models = [
'a' => 'A',
'b' => 'B',
'c' => 'C',
'd' => 'D',
- 'e' => 'E'
+ 'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J'
];
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
@@ -76,7 +69,7 @@ public function benchInventoryFiveModels()
Page::$models = [];
}
- public function benchInventorySixModels()
+ public function benchInventory15Models()
{
Page::$models = [
'a' => 'A',
@@ -84,6 +77,16 @@ public function benchInventorySixModels()
'c' => 'C',
'd' => 'D',
'e' => 'E',
+ 'f' => 'F',
+ 'g' => 'G',
+ 'h' => 'H',
+ 'i' => 'I',
+ 'j' => 'J',
+ 'k' => 'K',
+ 'l' => 'L',
+ 'm' => 'M',
+ 'n' => 'N',
+ 'o' => 'O'
];
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
@@ -91,7 +94,7 @@ public function benchInventorySixModels()
Page::$models = [];
}
- public function benchInventoryManyModels()
+ public function benchInventory26Models()
{
Page::$models = [
'a' => 'A',
From 4df5c3c4c40e33d98481942d1d82a544f3fe20ed Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 14:21:51 +0100
Subject: [PATCH 072/202] Deactivate some DirBench cases
---
performance/Filesystem/DirBench.php | 134 ++++++++++++++--------------
1 file changed, 67 insertions(+), 67 deletions(-)
diff --git a/performance/Filesystem/DirBench.php b/performance/Filesystem/DirBench.php
index 6b74132e74..2216258e14 100644
--- a/performance/Filesystem/DirBench.php
+++ b/performance/Filesystem/DirBench.php
@@ -11,16 +11,16 @@ public function benchInventoryNoModels()
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
}
- public function benchInventoryOneModels()
- {
- Page::$models = [
- 'a' => 'A'
- ];
+ // public function benchInventoryOneModels()
+ // {
+ // Page::$models = [
+ // 'a' => 'A'
+ // ];
- Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+ // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
- Page::$models = [];
- }
+ // Page::$models = [];
+ // }
public function benchInventoryTwoModels()
{
@@ -34,65 +34,65 @@ public function benchInventoryTwoModels()
Page::$models = [];
}
- public function benchInventoryFiveModels()
- {
- Page::$models = [
- 'a' => 'A',
- 'b' => 'B',
- 'c' => 'C',
- 'd' => 'D',
- 'e' => 'E'
- ];
-
- Dir::inventory(__DIR__ . '/fixtures/inventory/models');
-
- Page::$models = [];
- }
-
- public function benchInventory10Models()
- {
- Page::$models = [
- 'a' => 'A',
- 'b' => 'B',
- 'c' => 'C',
- 'd' => 'D',
- 'e' => 'E',
- 'f' => 'F',
- 'g' => 'G',
- 'h' => 'H',
- 'i' => 'I',
- 'j' => 'J'
- ];
-
- Dir::inventory(__DIR__ . '/fixtures/inventory/models');
-
- Page::$models = [];
- }
-
- public function benchInventory15Models()
- {
- Page::$models = [
- 'a' => 'A',
- 'b' => 'B',
- 'c' => 'C',
- 'd' => 'D',
- 'e' => 'E',
- 'f' => 'F',
- 'g' => 'G',
- 'h' => 'H',
- 'i' => 'I',
- 'j' => 'J',
- 'k' => 'K',
- 'l' => 'L',
- 'm' => 'M',
- 'n' => 'N',
- 'o' => 'O'
- ];
-
- Dir::inventory(__DIR__ . '/fixtures/inventory/models');
-
- Page::$models = [];
- }
+ // public function benchInventoryFiveModels()
+ // {
+ // Page::$models = [
+ // 'a' => 'A',
+ // 'b' => 'B',
+ // 'c' => 'C',
+ // 'd' => 'D',
+ // 'e' => 'E'
+ // ];
+
+ // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ // Page::$models = [];
+ // }
+
+ // public function benchInventory10Models()
+ // {
+ // Page::$models = [
+ // 'a' => 'A',
+ // 'b' => 'B',
+ // 'c' => 'C',
+ // 'd' => 'D',
+ // 'e' => 'E',
+ // 'f' => 'F',
+ // 'g' => 'G',
+ // 'h' => 'H',
+ // 'i' => 'I',
+ // 'j' => 'J'
+ // ];
+
+ // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ // Page::$models = [];
+ // }
+
+ // public function benchInventory15Models()
+ // {
+ // Page::$models = [
+ // 'a' => 'A',
+ // 'b' => 'B',
+ // 'c' => 'C',
+ // 'd' => 'D',
+ // 'e' => 'E',
+ // 'f' => 'F',
+ // 'g' => 'G',
+ // 'h' => 'H',
+ // 'i' => 'I',
+ // 'j' => 'J',
+ // 'k' => 'K',
+ // 'l' => 'L',
+ // 'm' => 'M',
+ // 'n' => 'N',
+ // 'o' => 'O'
+ // ];
+
+ // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+
+ // Page::$models = [];
+ // }
public function benchInventory26Models()
{
From c9a6443a0ec00af2487ef94c0cb30c96d1b24077 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 27 Jan 2024 23:02:32 +0100
Subject: [PATCH 073/202] Fix bench setup after merge conflicts
---
{performance => bench}/Filesystem/DirBench.php | 0
.../Filesystem/fixtures/inventory/models/a.txt | 0
.../Filesystem/fixtures/inventory/models/a/a.txt | 0
.../Filesystem/fixtures/inventory/models/a/bar.png | 0
.../Filesystem/fixtures/inventory/models/a/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/a/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/a/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/b/b.txt | 0
.../Filesystem/fixtures/inventory/models/b/bar.png | 0
.../Filesystem/fixtures/inventory/models/b/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/b/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/b/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/bar.png | 0
.../Filesystem/fixtures/inventory/models/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/c/bar.png | 0
.../Filesystem/fixtures/inventory/models/c/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/c/c.txt | 0
.../Filesystem/fixtures/inventory/models/c/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/c/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/d/bar.png | 0
.../Filesystem/fixtures/inventory/models/d/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/d/d.txt | 0
.../Filesystem/fixtures/inventory/models/d/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/d/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/e/bar.png | 0
.../Filesystem/fixtures/inventory/models/e/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/e/e.txt | 0
.../Filesystem/fixtures/inventory/models/e/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/e/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/f/bar.png | 0
.../Filesystem/fixtures/inventory/models/f/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/f/f.txt | 0
.../Filesystem/fixtures/inventory/models/f/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/f/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/g/bar.png | 0
.../Filesystem/fixtures/inventory/models/g/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/g/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/g/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/g/g.txt | 0
.../Filesystem/fixtures/inventory/models/h/bar.png | 0
.../Filesystem/fixtures/inventory/models/h/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/h/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/h/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/h/h.txt | 0
.../Filesystem/fixtures/inventory/models/i/bar.png | 0
.../Filesystem/fixtures/inventory/models/i/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/i/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/i/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/i/i.txt | 0
.../Filesystem/fixtures/inventory/models/j/bar.png | 0
.../Filesystem/fixtures/inventory/models/j/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/j/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/j/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/j/j.txt | 0
.../Filesystem/fixtures/inventory/models/k/bar.png | 0
.../Filesystem/fixtures/inventory/models/k/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/k/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/k/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/k/k.txt | 0
.../Filesystem/fixtures/inventory/models/l/bar.png | 0
.../Filesystem/fixtures/inventory/models/l/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/l/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/l/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/l/l.txt | 0
.../Filesystem/fixtures/inventory/models/m/bar.png | 0
.../Filesystem/fixtures/inventory/models/m/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/m/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/m/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/m/m.txt | 0
.../Filesystem/fixtures/inventory/models/n/bar.png | 0
.../Filesystem/fixtures/inventory/models/n/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/n/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/n/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/n/n.txt | 0
.../Filesystem/fixtures/inventory/models/o/bar.png | 0
.../Filesystem/fixtures/inventory/models/o/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/o/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/o/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/o/o.txt | 0
.../Filesystem/fixtures/inventory/models/p/bar.png | 0
.../Filesystem/fixtures/inventory/models/p/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/p/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/p/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/p/p.txt | 0
.../Filesystem/fixtures/inventory/models/q/bar.png | 0
.../Filesystem/fixtures/inventory/models/q/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/q/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/q/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/q/q.txt | 0
.../Filesystem/fixtures/inventory/models/r/bar.png | 0
.../Filesystem/fixtures/inventory/models/r/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/r/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/r/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/r/r.txt | 0
.../Filesystem/fixtures/inventory/models/s/bar.png | 0
.../Filesystem/fixtures/inventory/models/s/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/s/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/s/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/s/s.txt | 0
.../Filesystem/fixtures/inventory/models/t/bar.png | 0
.../Filesystem/fixtures/inventory/models/t/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/t/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/t/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/t/t.txt | 0
.../Filesystem/fixtures/inventory/models/u/bar.png | 0
.../Filesystem/fixtures/inventory/models/u/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/u/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/u/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/u/u.txt | 0
.../Filesystem/fixtures/inventory/models/v/bar.png | 0
.../Filesystem/fixtures/inventory/models/v/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/v/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/v/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/v/v.txt | 0
.../Filesystem/fixtures/inventory/models/w/bar.png | 0
.../Filesystem/fixtures/inventory/models/w/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/w/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/w/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/w/w.txt | 0
.../Filesystem/fixtures/inventory/models/x/bar.png | 0
.../Filesystem/fixtures/inventory/models/x/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/x/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/x/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/x/x.txt | 0
.../Filesystem/fixtures/inventory/models/y/bar.png | 0
.../Filesystem/fixtures/inventory/models/y/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/y/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/y/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/y/y.txt | 0
.../Filesystem/fixtures/inventory/models/z/bar.png | 0
.../Filesystem/fixtures/inventory/models/z/bar.png.txt | 0
.../Filesystem/fixtures/inventory/models/z/foo.jpg | 0
.../Filesystem/fixtures/inventory/models/z/foo.jpg.txt | 0
.../Filesystem/fixtures/inventory/models/z/z.txt | 0
performance/bootstrap.php | 3 ---
137 files changed, 3 deletions(-)
rename {performance => bench}/Filesystem/DirBench.php (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/a.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/a/a.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/a/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/a/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/a/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/a/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/b/b.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/b/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/b/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/b/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/b/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/c/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/c/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/c/c.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/c/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/c/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/d/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/d/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/d/d.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/d/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/d/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/e/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/e/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/e/e.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/e/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/e/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/f/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/f/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/f/f.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/f/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/f/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/g/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/g/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/g/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/g/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/g/g.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/h/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/h/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/h/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/h/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/h/h.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/i/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/i/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/i/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/i/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/i/i.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/j/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/j/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/j/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/j/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/j/j.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/k/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/k/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/k/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/k/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/k/k.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/l/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/l/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/l/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/l/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/l/l.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/m/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/m/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/m/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/m/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/m/m.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/n/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/n/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/n/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/n/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/n/n.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/o/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/o/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/o/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/o/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/o/o.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/p/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/p/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/p/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/p/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/p/p.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/q/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/q/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/q/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/q/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/q/q.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/r/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/r/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/r/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/r/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/r/r.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/s/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/s/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/s/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/s/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/s/s.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/t/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/t/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/t/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/t/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/t/t.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/u/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/u/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/u/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/u/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/u/u.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/v/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/v/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/v/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/v/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/v/v.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/w/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/w/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/w/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/w/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/w/w.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/x/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/x/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/x/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/x/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/x/x.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/y/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/y/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/y/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/y/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/y/y.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/z/bar.png (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/z/bar.png.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/z/foo.jpg (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/z/foo.jpg.txt (100%)
rename {performance => bench}/Filesystem/fixtures/inventory/models/z/z.txt (100%)
delete mode 100644 performance/bootstrap.php
diff --git a/performance/Filesystem/DirBench.php b/bench/Filesystem/DirBench.php
similarity index 100%
rename from performance/Filesystem/DirBench.php
rename to bench/Filesystem/DirBench.php
diff --git a/performance/Filesystem/fixtures/inventory/models/a.txt b/bench/Filesystem/fixtures/inventory/models/a.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/a.txt
rename to bench/Filesystem/fixtures/inventory/models/a.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/a/a.txt b/bench/Filesystem/fixtures/inventory/models/a/a.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/a/a.txt
rename to bench/Filesystem/fixtures/inventory/models/a/a.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/a/bar.png b/bench/Filesystem/fixtures/inventory/models/a/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/a/bar.png
rename to bench/Filesystem/fixtures/inventory/models/a/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/a/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/a/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/a/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/a/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/a/foo.jpg b/bench/Filesystem/fixtures/inventory/models/a/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/a/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/a/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/a/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/a/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/a/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/a/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/b/b.txt b/bench/Filesystem/fixtures/inventory/models/b/b.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/b/b.txt
rename to bench/Filesystem/fixtures/inventory/models/b/b.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/b/bar.png b/bench/Filesystem/fixtures/inventory/models/b/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/b/bar.png
rename to bench/Filesystem/fixtures/inventory/models/b/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/b/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/b/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/b/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/b/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/b/foo.jpg b/bench/Filesystem/fixtures/inventory/models/b/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/b/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/b/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/b/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/b/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/b/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/b/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/bar.png b/bench/Filesystem/fixtures/inventory/models/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/bar.png
rename to bench/Filesystem/fixtures/inventory/models/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/c/bar.png b/bench/Filesystem/fixtures/inventory/models/c/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/c/bar.png
rename to bench/Filesystem/fixtures/inventory/models/c/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/c/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/c/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/c/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/c/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/c/c.txt b/bench/Filesystem/fixtures/inventory/models/c/c.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/c/c.txt
rename to bench/Filesystem/fixtures/inventory/models/c/c.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/c/foo.jpg b/bench/Filesystem/fixtures/inventory/models/c/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/c/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/c/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/c/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/c/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/c/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/c/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/d/bar.png b/bench/Filesystem/fixtures/inventory/models/d/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/d/bar.png
rename to bench/Filesystem/fixtures/inventory/models/d/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/d/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/d/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/d/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/d/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/d/d.txt b/bench/Filesystem/fixtures/inventory/models/d/d.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/d/d.txt
rename to bench/Filesystem/fixtures/inventory/models/d/d.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/d/foo.jpg b/bench/Filesystem/fixtures/inventory/models/d/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/d/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/d/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/d/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/d/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/d/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/d/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/e/bar.png b/bench/Filesystem/fixtures/inventory/models/e/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/e/bar.png
rename to bench/Filesystem/fixtures/inventory/models/e/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/e/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/e/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/e/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/e/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/e/e.txt b/bench/Filesystem/fixtures/inventory/models/e/e.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/e/e.txt
rename to bench/Filesystem/fixtures/inventory/models/e/e.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/e/foo.jpg b/bench/Filesystem/fixtures/inventory/models/e/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/e/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/e/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/e/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/e/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/e/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/e/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/f/bar.png b/bench/Filesystem/fixtures/inventory/models/f/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/f/bar.png
rename to bench/Filesystem/fixtures/inventory/models/f/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/f/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/f/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/f/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/f/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/f/f.txt b/bench/Filesystem/fixtures/inventory/models/f/f.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/f/f.txt
rename to bench/Filesystem/fixtures/inventory/models/f/f.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/f/foo.jpg b/bench/Filesystem/fixtures/inventory/models/f/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/f/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/f/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/f/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/f/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/f/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/f/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/foo.jpg b/bench/Filesystem/fixtures/inventory/models/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/g/bar.png b/bench/Filesystem/fixtures/inventory/models/g/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/g/bar.png
rename to bench/Filesystem/fixtures/inventory/models/g/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/g/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/g/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/g/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/g/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/g/foo.jpg b/bench/Filesystem/fixtures/inventory/models/g/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/g/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/g/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/g/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/g/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/g/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/g/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/g/g.txt b/bench/Filesystem/fixtures/inventory/models/g/g.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/g/g.txt
rename to bench/Filesystem/fixtures/inventory/models/g/g.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/h/bar.png b/bench/Filesystem/fixtures/inventory/models/h/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/h/bar.png
rename to bench/Filesystem/fixtures/inventory/models/h/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/h/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/h/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/h/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/h/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/h/foo.jpg b/bench/Filesystem/fixtures/inventory/models/h/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/h/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/h/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/h/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/h/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/h/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/h/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/h/h.txt b/bench/Filesystem/fixtures/inventory/models/h/h.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/h/h.txt
rename to bench/Filesystem/fixtures/inventory/models/h/h.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/i/bar.png b/bench/Filesystem/fixtures/inventory/models/i/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/i/bar.png
rename to bench/Filesystem/fixtures/inventory/models/i/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/i/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/i/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/i/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/i/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/i/foo.jpg b/bench/Filesystem/fixtures/inventory/models/i/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/i/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/i/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/i/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/i/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/i/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/i/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/i/i.txt b/bench/Filesystem/fixtures/inventory/models/i/i.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/i/i.txt
rename to bench/Filesystem/fixtures/inventory/models/i/i.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/j/bar.png b/bench/Filesystem/fixtures/inventory/models/j/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/j/bar.png
rename to bench/Filesystem/fixtures/inventory/models/j/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/j/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/j/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/j/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/j/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/j/foo.jpg b/bench/Filesystem/fixtures/inventory/models/j/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/j/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/j/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/j/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/j/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/j/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/j/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/j/j.txt b/bench/Filesystem/fixtures/inventory/models/j/j.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/j/j.txt
rename to bench/Filesystem/fixtures/inventory/models/j/j.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/k/bar.png b/bench/Filesystem/fixtures/inventory/models/k/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/k/bar.png
rename to bench/Filesystem/fixtures/inventory/models/k/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/k/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/k/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/k/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/k/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/k/foo.jpg b/bench/Filesystem/fixtures/inventory/models/k/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/k/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/k/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/k/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/k/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/k/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/k/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/k/k.txt b/bench/Filesystem/fixtures/inventory/models/k/k.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/k/k.txt
rename to bench/Filesystem/fixtures/inventory/models/k/k.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/l/bar.png b/bench/Filesystem/fixtures/inventory/models/l/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/l/bar.png
rename to bench/Filesystem/fixtures/inventory/models/l/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/l/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/l/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/l/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/l/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/l/foo.jpg b/bench/Filesystem/fixtures/inventory/models/l/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/l/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/l/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/l/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/l/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/l/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/l/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/l/l.txt b/bench/Filesystem/fixtures/inventory/models/l/l.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/l/l.txt
rename to bench/Filesystem/fixtures/inventory/models/l/l.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/m/bar.png b/bench/Filesystem/fixtures/inventory/models/m/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/m/bar.png
rename to bench/Filesystem/fixtures/inventory/models/m/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/m/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/m/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/m/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/m/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/m/foo.jpg b/bench/Filesystem/fixtures/inventory/models/m/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/m/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/m/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/m/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/m/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/m/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/m/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/m/m.txt b/bench/Filesystem/fixtures/inventory/models/m/m.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/m/m.txt
rename to bench/Filesystem/fixtures/inventory/models/m/m.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/n/bar.png b/bench/Filesystem/fixtures/inventory/models/n/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/n/bar.png
rename to bench/Filesystem/fixtures/inventory/models/n/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/n/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/n/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/n/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/n/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/n/foo.jpg b/bench/Filesystem/fixtures/inventory/models/n/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/n/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/n/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/n/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/n/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/n/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/n/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/n/n.txt b/bench/Filesystem/fixtures/inventory/models/n/n.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/n/n.txt
rename to bench/Filesystem/fixtures/inventory/models/n/n.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/o/bar.png b/bench/Filesystem/fixtures/inventory/models/o/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/o/bar.png
rename to bench/Filesystem/fixtures/inventory/models/o/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/o/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/o/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/o/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/o/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/o/foo.jpg b/bench/Filesystem/fixtures/inventory/models/o/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/o/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/o/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/o/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/o/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/o/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/o/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/o/o.txt b/bench/Filesystem/fixtures/inventory/models/o/o.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/o/o.txt
rename to bench/Filesystem/fixtures/inventory/models/o/o.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/p/bar.png b/bench/Filesystem/fixtures/inventory/models/p/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/p/bar.png
rename to bench/Filesystem/fixtures/inventory/models/p/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/p/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/p/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/p/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/p/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/p/foo.jpg b/bench/Filesystem/fixtures/inventory/models/p/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/p/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/p/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/p/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/p/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/p/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/p/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/p/p.txt b/bench/Filesystem/fixtures/inventory/models/p/p.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/p/p.txt
rename to bench/Filesystem/fixtures/inventory/models/p/p.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/q/bar.png b/bench/Filesystem/fixtures/inventory/models/q/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/q/bar.png
rename to bench/Filesystem/fixtures/inventory/models/q/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/q/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/q/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/q/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/q/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/q/foo.jpg b/bench/Filesystem/fixtures/inventory/models/q/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/q/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/q/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/q/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/q/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/q/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/q/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/q/q.txt b/bench/Filesystem/fixtures/inventory/models/q/q.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/q/q.txt
rename to bench/Filesystem/fixtures/inventory/models/q/q.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/r/bar.png b/bench/Filesystem/fixtures/inventory/models/r/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/r/bar.png
rename to bench/Filesystem/fixtures/inventory/models/r/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/r/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/r/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/r/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/r/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/r/foo.jpg b/bench/Filesystem/fixtures/inventory/models/r/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/r/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/r/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/r/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/r/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/r/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/r/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/r/r.txt b/bench/Filesystem/fixtures/inventory/models/r/r.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/r/r.txt
rename to bench/Filesystem/fixtures/inventory/models/r/r.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/s/bar.png b/bench/Filesystem/fixtures/inventory/models/s/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/s/bar.png
rename to bench/Filesystem/fixtures/inventory/models/s/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/s/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/s/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/s/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/s/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/s/foo.jpg b/bench/Filesystem/fixtures/inventory/models/s/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/s/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/s/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/s/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/s/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/s/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/s/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/s/s.txt b/bench/Filesystem/fixtures/inventory/models/s/s.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/s/s.txt
rename to bench/Filesystem/fixtures/inventory/models/s/s.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/t/bar.png b/bench/Filesystem/fixtures/inventory/models/t/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/t/bar.png
rename to bench/Filesystem/fixtures/inventory/models/t/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/t/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/t/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/t/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/t/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/t/foo.jpg b/bench/Filesystem/fixtures/inventory/models/t/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/t/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/t/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/t/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/t/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/t/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/t/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/t/t.txt b/bench/Filesystem/fixtures/inventory/models/t/t.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/t/t.txt
rename to bench/Filesystem/fixtures/inventory/models/t/t.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/u/bar.png b/bench/Filesystem/fixtures/inventory/models/u/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/u/bar.png
rename to bench/Filesystem/fixtures/inventory/models/u/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/u/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/u/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/u/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/u/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/u/foo.jpg b/bench/Filesystem/fixtures/inventory/models/u/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/u/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/u/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/u/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/u/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/u/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/u/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/u/u.txt b/bench/Filesystem/fixtures/inventory/models/u/u.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/u/u.txt
rename to bench/Filesystem/fixtures/inventory/models/u/u.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/v/bar.png b/bench/Filesystem/fixtures/inventory/models/v/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/v/bar.png
rename to bench/Filesystem/fixtures/inventory/models/v/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/v/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/v/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/v/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/v/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/v/foo.jpg b/bench/Filesystem/fixtures/inventory/models/v/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/v/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/v/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/v/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/v/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/v/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/v/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/v/v.txt b/bench/Filesystem/fixtures/inventory/models/v/v.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/v/v.txt
rename to bench/Filesystem/fixtures/inventory/models/v/v.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/w/bar.png b/bench/Filesystem/fixtures/inventory/models/w/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/w/bar.png
rename to bench/Filesystem/fixtures/inventory/models/w/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/w/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/w/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/w/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/w/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/w/foo.jpg b/bench/Filesystem/fixtures/inventory/models/w/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/w/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/w/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/w/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/w/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/w/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/w/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/w/w.txt b/bench/Filesystem/fixtures/inventory/models/w/w.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/w/w.txt
rename to bench/Filesystem/fixtures/inventory/models/w/w.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/x/bar.png b/bench/Filesystem/fixtures/inventory/models/x/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/x/bar.png
rename to bench/Filesystem/fixtures/inventory/models/x/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/x/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/x/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/x/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/x/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/x/foo.jpg b/bench/Filesystem/fixtures/inventory/models/x/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/x/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/x/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/x/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/x/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/x/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/x/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/x/x.txt b/bench/Filesystem/fixtures/inventory/models/x/x.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/x/x.txt
rename to bench/Filesystem/fixtures/inventory/models/x/x.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/y/bar.png b/bench/Filesystem/fixtures/inventory/models/y/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/y/bar.png
rename to bench/Filesystem/fixtures/inventory/models/y/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/y/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/y/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/y/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/y/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/y/foo.jpg b/bench/Filesystem/fixtures/inventory/models/y/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/y/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/y/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/y/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/y/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/y/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/y/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/y/y.txt b/bench/Filesystem/fixtures/inventory/models/y/y.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/y/y.txt
rename to bench/Filesystem/fixtures/inventory/models/y/y.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/z/bar.png b/bench/Filesystem/fixtures/inventory/models/z/bar.png
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/z/bar.png
rename to bench/Filesystem/fixtures/inventory/models/z/bar.png
diff --git a/performance/Filesystem/fixtures/inventory/models/z/bar.png.txt b/bench/Filesystem/fixtures/inventory/models/z/bar.png.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/z/bar.png.txt
rename to bench/Filesystem/fixtures/inventory/models/z/bar.png.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/z/foo.jpg b/bench/Filesystem/fixtures/inventory/models/z/foo.jpg
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/z/foo.jpg
rename to bench/Filesystem/fixtures/inventory/models/z/foo.jpg
diff --git a/performance/Filesystem/fixtures/inventory/models/z/foo.jpg.txt b/bench/Filesystem/fixtures/inventory/models/z/foo.jpg.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/z/foo.jpg.txt
rename to bench/Filesystem/fixtures/inventory/models/z/foo.jpg.txt
diff --git a/performance/Filesystem/fixtures/inventory/models/z/z.txt b/bench/Filesystem/fixtures/inventory/models/z/z.txt
similarity index 100%
rename from performance/Filesystem/fixtures/inventory/models/z/z.txt
rename to bench/Filesystem/fixtures/inventory/models/z/z.txt
diff --git a/performance/bootstrap.php b/performance/bootstrap.php
deleted file mode 100644
index 6c8c4f51b9..0000000000
--- a/performance/bootstrap.php
+++ /dev/null
@@ -1,3 +0,0 @@
-
Date: Sat, 27 Jan 2024 23:17:35 +0100
Subject: [PATCH 074/202] Fix composer.json
---
composer.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/composer.json b/composer.json
index 8f7d5f9619..e8293c5f77 100644
--- a/composer.json
+++ b/composer.json
@@ -90,6 +90,7 @@
]
},
"scripts": {
+ "post-update-cmd": "curl -o cacert.pem https://curl.se/ca/cacert.pem",
"analyze": [
"@analyze:composer",
"@analyze:psalm",
@@ -107,7 +108,6 @@
"@test"
],
"fix": "php-cs-fixer fix",
- "post-update-cmd": "curl -o cacert.pem https://curl.se/ca/cacert.pem",
"test": "phpunit",
"test:coverage": "XDEBUG_MODE=coverage phpunit --coverage-html=tests/coverage",
"zip": "composer archive --format=zip --file=dist"
From d0f4c3a26d1c15ca764de4c740591a5b48b8383c Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 27 Jan 2024 23:22:34 +0100
Subject: [PATCH 075/202] Fix cs
---
bench/Filesystem/DirBench.php | 99 ++++++++++-------------------------
1 file changed, 27 insertions(+), 72 deletions(-)
diff --git a/bench/Filesystem/DirBench.php b/bench/Filesystem/DirBench.php
index 2216258e14..47c9ac1ce2 100644
--- a/bench/Filesystem/DirBench.php
+++ b/bench/Filesystem/DirBench.php
@@ -6,24 +6,24 @@
class DirBench
{
- public function benchInventoryNoModels()
- {
+ public function benchInventoryNoModels()
+ {
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
- }
+ }
- // public function benchInventoryOneModels()
- // {
- // Page::$models = [
- // 'a' => 'A'
- // ];
+ public function benchInventoryOneModels()
+ {
+ Page::$models = [
+ 'a' => 'A'
+ ];
- // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
- // Page::$models = [];
- // }
+ Page::$models = [];
+ }
public function benchInventoryTwoModels()
- {
+ {
Page::$models = [
'a' => 'A',
'b' => 'B'
@@ -32,70 +32,25 @@ public function benchInventoryTwoModels()
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
Page::$models = [];
- }
-
- // public function benchInventoryFiveModels()
- // {
- // Page::$models = [
- // 'a' => 'A',
- // 'b' => 'B',
- // 'c' => 'C',
- // 'd' => 'D',
- // 'e' => 'E'
- // ];
-
- // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
-
- // Page::$models = [];
- // }
-
- // public function benchInventory10Models()
- // {
- // Page::$models = [
- // 'a' => 'A',
- // 'b' => 'B',
- // 'c' => 'C',
- // 'd' => 'D',
- // 'e' => 'E',
- // 'f' => 'F',
- // 'g' => 'G',
- // 'h' => 'H',
- // 'i' => 'I',
- // 'j' => 'J'
- // ];
-
- // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+ }
- // Page::$models = [];
- // }
-
- // public function benchInventory15Models()
- // {
- // Page::$models = [
- // 'a' => 'A',
- // 'b' => 'B',
- // 'c' => 'C',
- // 'd' => 'D',
- // 'e' => 'E',
- // 'f' => 'F',
- // 'g' => 'G',
- // 'h' => 'H',
- // 'i' => 'I',
- // 'j' => 'J',
- // 'k' => 'K',
- // 'l' => 'L',
- // 'm' => 'M',
- // 'n' => 'N',
- // 'o' => 'O'
- // ];
+ public function benchInventoryFiveModels()
+ {
+ Page::$models = [
+ 'a' => 'A',
+ 'b' => 'B',
+ 'c' => 'C',
+ 'd' => 'D',
+ 'e' => 'E'
+ ];
- // Dir::inventory(__DIR__ . '/fixtures/inventory/models');
+ Dir::inventory(__DIR__ . '/fixtures/inventory/models');
- // Page::$models = [];
- // }
+ Page::$models = [];
+ }
public function benchInventory26Models()
- {
+ {
Page::$models = [
'a' => 'A',
'b' => 'B',
@@ -128,5 +83,5 @@ public function benchInventory26Models()
Dir::inventory(__DIR__ . '/fixtures/inventory/models');
Page::$models = [];
- }
+ }
}
From 1942bd0b0a6d62ad729a70c62ba814692d9e94fa Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 12:07:12 +0100
Subject: [PATCH 076/202] Upgrade Psalm
---
.github/workflows/backend.yml | 2 +-
etc/psalm-plugins/HelperFunctionUsePlugin.php | 3 ++-
src/Cms/Helpers.php | 3 +++
src/Filesystem/Dir.php | 10 ++++++----
src/Toolkit/A.php | 2 +-
5 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml
index a1b9389137..28752a2590 100644
--- a/.github/workflows/backend.yml
+++ b/.github/workflows/backend.yml
@@ -99,7 +99,7 @@ jobs:
extensions: ${{ env.extensions }}
ini-values: ${{ env.ini }}
coverage: pcov
- tools: phpunit:10.5.5, psalm:5.15.0
+ tools: phpunit:10.5.5, psalm:5.20.0
- name: Setup problem matchers
run: |
diff --git a/etc/psalm-plugins/HelperFunctionUsePlugin.php b/etc/psalm-plugins/HelperFunctionUsePlugin.php
index 03161b315f..3266ee497e 100644
--- a/etc/psalm-plugins/HelperFunctionUsePlugin.php
+++ b/etc/psalm-plugins/HelperFunctionUsePlugin.php
@@ -27,7 +27,8 @@ public static function afterFunctionCallAnalysis(AfterFunctionCallAnalysisEvent
$event->getFunctionId()
);
- // if the function is a Kirby helper, consider this function call an issue
+ // if the function is a Kirby helper,
+ // consider this function call an issue
if ($storage->location->file_path === dirname(__FILE__, 3) . '/config/helpers.php') {
IssueBuffer::accepts(
new HelperFunctionUse(
diff --git a/src/Cms/Helpers.php b/src/Cms/Helpers.php
index bb27d8b969..025dccc202 100644
--- a/src/Cms/Helpers.php
+++ b/src/Cms/Helpers.php
@@ -110,6 +110,9 @@ public static function handleErrors(
) {
$override = null;
+ /**
+ * @psalm-suppress UndefinedVariable
+ */
$handler = set_error_handler(function () use (&$override, &$handler, $condition, $fallback) {
// check if suppress condition is met
$suppress = $condition(...func_get_args());
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index 17337b6352..d93a49f218 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -290,10 +290,12 @@ public static function inventory(
$content = array_unique($content);
- return [
- ...$inventory,
- 'template' => static::inventoryTemplate($content, $inventory['files'])
- ];
+ $inventory['template'] = static::inventoryTemplate(
+ $content,
+ $inventory['files']
+ );
+
+ return $inventory;
}
/**
diff --git a/src/Toolkit/A.php b/src/Toolkit/A.php
index a62d9c2a55..b30b83675f 100644
--- a/src/Toolkit/A.php
+++ b/src/Toolkit/A.php
@@ -255,7 +255,7 @@ public static function first(array $array): mixed
* // result: ['cat' => 'miao', 'dog' => 'wuff'];
*
*
- * @param array $array The source array
+ * @param mixed $array The source array
* @param string|int|array|null $key The key to look for
* @param mixed $default Optional default value, which
* should be returned if no element
From 834a454c5daf238b5f5733b674d9a89696c0765c Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 12:20:02 +0100
Subject: [PATCH 077/202] Fix unit tests
---
tests/Filesystem/DirTest.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/Filesystem/DirTest.php b/tests/Filesystem/DirTest.php
index a8015fd57d..7f6a3d63ac 100644
--- a/tests/Filesystem/DirTest.php
+++ b/tests/Filesystem/DirTest.php
@@ -454,9 +454,9 @@ public function testInventoryMultilang()
/**
* @covers ::inventory
- * @covers ::inventoryModels
+ * @covers ::inventoryChild
*/
- public function testInventoryModels()
+ public function testInventoryChildModels()
{
Page::$models = [
'a' => 'A',
@@ -478,9 +478,9 @@ public function testInventoryModels()
/**
* @covers ::inventory
- * @covers ::inventoryModels
+ * @covers ::inventoryChild
*/
- public function testInventoryMultilangModels()
+ public function testInventoryChildMultilangModels()
{
new App([
'roots' => [
From 4009ceda5b2021cf020ef55575fce416623ee2d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nico=20Hoffmann=20=20=E0=B7=B4?=
Date: Sat, 3 Feb 2024 21:07:16 +0100
Subject: [PATCH 078/202] Update src/Filesystem/Dir.php
Co-authored-by: Bastian Allgeier
---
src/Filesystem/Dir.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index d93a49f218..d83df1edcf 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -323,7 +323,7 @@ protected static function inventoryChild(
// look if a content file can be found
// for any of the available models
foreach (Page::$models as $modelName => $modelClass) {
- if (file_exists($root . '/' . $modelName . '.' . $contentExtension)) {
+ if (file_exists($root . '/' . $modelName . '.' . $contentExtension) === true) {
$model = $modelName;
break;
}
From c903e6b192617645f2ffc9cdc3bf243a392821b0 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 3 Feb 2024 21:13:49 +0100
Subject: [PATCH 079/202] `Dir::inventory()`: get language code only once
---
src/Filesystem/Dir.php | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index d83df1edcf..5c886b7592 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -232,6 +232,9 @@ public static function inventory(
return $inventory;
}
+ // lazily get the default language code
+ $languageCode = App::instance(null, true)?->defaultLanguage()?->code();
+
// a temporary store for all content files
$content = [];
@@ -254,7 +257,7 @@ public static function inventory(
$item,
$root,
$contentExtension,
- $multilang
+ $languageCode
);
continue;
}
@@ -305,7 +308,7 @@ protected static function inventoryChild(
string $item,
string $root,
string $contentExtension = 'txt',
- bool $multilang = false
+ string|null $languageCode = null
): array {
// extract the slug and num of the directory
if ($separator = strpos($item, static::$numSeparator)) {
@@ -315,9 +318,8 @@ protected static function inventoryChild(
// determine the model
if (empty(Page::$models) === false) {
- if ($multilang === true) {
- $code = App::instance()->defaultLanguage()->code();
- $contentExtension = $code . '.' . $contentExtension;
+ if ($languageCode !== null) {
+ $contentExtension = $languageCode . '.' . $contentExtension;
}
// look if a content file can be found
From 9da25e8e5c81e9f8aae2589c177a7921e19b3dc4 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 17 Feb 2024 23:54:05 +0100
Subject: [PATCH 080/202] Revert "`Dir::inventory()`: get language code only
once"
This reverts commit c903e6b192617645f2ffc9cdc3bf243a392821b0.
---
src/Filesystem/Dir.php | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index 5c886b7592..d83df1edcf 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -232,9 +232,6 @@ public static function inventory(
return $inventory;
}
- // lazily get the default language code
- $languageCode = App::instance(null, true)?->defaultLanguage()?->code();
-
// a temporary store for all content files
$content = [];
@@ -257,7 +254,7 @@ public static function inventory(
$item,
$root,
$contentExtension,
- $languageCode
+ $multilang
);
continue;
}
@@ -308,7 +305,7 @@ protected static function inventoryChild(
string $item,
string $root,
string $contentExtension = 'txt',
- string|null $languageCode = null
+ bool $multilang = false
): array {
// extract the slug and num of the directory
if ($separator = strpos($item, static::$numSeparator)) {
@@ -318,8 +315,9 @@ protected static function inventoryChild(
// determine the model
if (empty(Page::$models) === false) {
- if ($languageCode !== null) {
- $contentExtension = $languageCode . '.' . $contentExtension;
+ if ($multilang === true) {
+ $code = App::instance()->defaultLanguage()->code();
+ $contentExtension = $code . '.' . $contentExtension;
}
// look if a content file can be found
From 7c8ecb30beed48469fc2a1ce8489f8943092c3ea Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 14:30:12 +0100
Subject: [PATCH 081/202] Add test for `Toolkit\Controller::arguments()`
---
tests/Toolkit/ControllerTest.php | 33 +++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/tests/Toolkit/ControllerTest.php b/tests/Toolkit/ControllerTest.php
index 0e7cead166..7cf81b5021 100644
--- a/tests/Toolkit/ControllerTest.php
+++ b/tests/Toolkit/ControllerTest.php
@@ -9,15 +9,6 @@ class ControllerTest extends TestCase
{
public const FIXTURES = __DIR__ . '/fixtures';
- /**
- * @covers ::call
- */
- public function testCall()
- {
- $controller = new Controller(fn () => 'test');
- $this->assertSame('test', $controller->call());
- }
-
/**
* @covers ::arguments
*/
@@ -47,7 +38,7 @@ public function testArgumentsOrder()
/**
* @covers ::arguments
*/
- public function testVariadicArguments()
+ public function testArgumentsVariadic()
{
$controller = new Controller(fn ($c, ...$args) => $c . '/' . implode('', $args));
@@ -58,6 +49,26 @@ public function testVariadicArguments()
]));
}
+ /**
+ * @covers ::arguments
+ */
+ public function testArgumentsNoDefaultNull()
+ {
+ $controller = new Controller(fn ($a, $b = 'foo') => ($a === null ? 'null' : $a) . ($b === null ? 'null' : $b));
+
+ $this->assertSame('nullfoo', $controller->call());
+ }
+
+ /**
+ * @covers ::__construct
+ * @covers ::call
+ */
+ public function testCall()
+ {
+ $controller = new Controller(fn () => 'test');
+ $this->assertSame('test', $controller->call());
+ }
+
/**
* @covers ::call
*/
@@ -72,7 +83,7 @@ public function testCallBind()
/**
* @covers ::call
*/
- public function testMissingParameter()
+ public function testCallMissingParameter()
{
$controller = new Controller(fn ($a) => $a);
$this->assertNull($controller->call());
From 54ff1d123bbcfd6e4ba80f37f6bed6c5472c08b6 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 15:35:37 +0100
Subject: [PATCH 082/202] Some unit tests for `Toolkit\Collection`
---
tests/Toolkit/CollectionTest.php | 102 +++++++++++++++++++++++++++++--
1 file changed, 98 insertions(+), 4 deletions(-)
diff --git a/tests/Toolkit/CollectionTest.php b/tests/Toolkit/CollectionTest.php
index df10cb652a..686cb581c6 100644
--- a/tests/Toolkit/CollectionTest.php
+++ b/tests/Toolkit/CollectionTest.php
@@ -51,6 +51,16 @@ public function test__debuginfo()
$this->assertSame(['a', 'b'], $collection->__debugInfo());
}
+ /**
+ * @covers ::__toString
+ */
+ public function test__toString()
+ {
+ $collection = new Collection(['a' => 'A', 'b' => 'B']);
+ $this->assertSame('a b', $collection->__toString());
+ $this->assertSame('a b', (string)$collection);
+ }
+
/**
* @covers ::append
*/
@@ -142,6 +152,30 @@ public function testCount()
$this->assertSame(3, count($this->collection));
}
+ /**
+ * @covers ::data
+ */
+ public function testData()
+ {
+ $collection = new Collection($data = ['a' => 'A', 'b' => 'B']);
+ $this->assertSame($data, $collection->data());
+
+ $collection->data($data = ['c' => 'C', 'd' => 'D']);
+ $this->assertSame($data, $collection->data());
+ }
+
+ /**
+ * @covers ::empty
+ */
+ public function testEmpty()
+ {
+ $collection = new Collection($data = ['a' => 'A', 'b' => 'B']);
+ $this->assertSame($data, $collection->data());
+
+ $collection = $collection->empty();
+ $this->assertSame([], $collection->data());
+ }
+
/**
* @covers ::filter
*/
@@ -237,10 +271,26 @@ public function testGetters()
$this->assertSame('My first element', $this->collection->get('first'));
$this->assertSame('My second element', $this->collection->get('second'));
$this->assertSame('My third element', $this->collection->get('third'));
+
+ $this->assertNull($this->collection->get('fourth'));
+ }
+
+ /**
+ * @covers ::__construct
+ * @covers ::__get
+ * @covers ::get
+ */
+ public function testGettersCaseSensitive()
+ {
+ $collection = new Collection($this->sampleData, true);
+
+ $this->assertSame('My first element', $collection->get('first'));
+ $this->assertNull($collection->get('FIRst'));
}
/**
* @covers ::group
+ * @covers ::groupBy
*/
public function testGroup()
{
@@ -261,15 +311,17 @@ public function testGroup()
'group' => 'client'
];
- $groups = $collection->group(function ($item) {
- return $item['group'];
- });
-
+ $groups = $collection->group(fn ($item) => $item['group']);
$this->assertCount(2, $groups->admin());
$this->assertCount(1, $groups->client());
$firstAdmin = $groups->admin()->first();
$this->assertSame('peter', $firstAdmin['username']);
+
+ // alias
+ $groups = $collection->groupBy(fn ($item) => $item['group']);
+ $this->assertCount(2, $groups->admin());
+ $this->assertCount(1, $groups->client());
}
/**
@@ -567,6 +619,16 @@ public function testLast()
$this->assertSame('My third element', $this->collection->last());
}
+ /**
+ * @covers ::map
+ */
+ public function testMap()
+ {
+ $collection = new Collection(['a' => 1, 'b' => 2]);
+ $collection->map(fn ($item) => $item * 2);
+ $this->assertSame(['a' => 2, 'b' => 4], $collection->data());
+ }
+
/**
* @covers ::next
* @covers ::prev
@@ -871,6 +933,38 @@ public function testToArray()
// non-associative
$collection = new Collection($input = ['a', 'b', 'c']);
$this->assertSame($input, $collection->toArray());
+
+ // with mapping
+ $collection = new Collection(['a' => 1, 'b' => 2]);
+ $this->assertSame(['a' => 2, 'b' => 4], $collection->toArray(fn ($item) => $item * 2));
+ }
+
+ /**
+ * @covers ::toJson
+ */
+ public function testToJson()
+ {
+ // associative
+ $collection = new Collection(['a' => 'value A', 'b' => 'value B']);
+ $this->assertSame('{"a":"value A","b":"value B"}', $collection->toJson());
+
+ // non-associative
+ $collection = new Collection(['a', 'b', 'c']);
+ $this->assertSame('["a","b","c"]', $collection->toJson());
+ }
+
+ /**
+ * @covers ::toString
+ */
+ public function testToString()
+ {
+ // associative
+ $collection = new Collection(['a' => 'value A', 'b' => 'value B']);
+ $this->assertSame('a b', $collection->toString());
+
+ // non-associative
+ $collection = new Collection(['a', 'b', 'c']);
+ $this->assertSame('0 1 2', $collection->toString());
}
/**
From c988b5d7ae668d8306104c008593ad4e0339d590 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 15:54:24 +0100
Subject: [PATCH 083/202] Add more `Toolkit\Date` unit tests
---
tests/Toolkit/DateTest.php | 73 ++++++++++++++++++++++++++++++++++++++
tests/Toolkit/ObjTest.php | 1 +
2 files changed, 74 insertions(+)
diff --git a/tests/Toolkit/DateTest.php b/tests/Toolkit/DateTest.php
index 72d32813c7..101573b400 100644
--- a/tests/Toolkit/DateTest.php
+++ b/tests/Toolkit/DateTest.php
@@ -53,6 +53,36 @@ public function test__toString()
$this->assertSame('2021-12-12 12:12:12+00:00', (string)$date);
}
+ /**
+ * @covers ::ceil
+ */
+ public function testCeil()
+ {
+ $date = new Date('2021-12-12 12:12:12');
+
+ $date->ceil('second');
+ $this->assertSame('2021-12-12 12:12:13', $date->format('Y-m-d H:i:s'));
+
+ $date->ceil('minute');
+ $this->assertSame('2021-12-12 12:13:00', $date->format('Y-m-d H:i:s'));
+
+ $date->ceil('hour');
+ $this->assertSame('2021-12-12 13:00:00', $date->format('Y-m-d H:i:s'));
+
+ $date->ceil('day');
+ $this->assertSame('2021-12-13 00:00:00', $date->format('Y-m-d H:i:s'));
+
+ $date->ceil('month');
+ $this->assertSame('2022-01-01 00:00:00', $date->format('Y-m-d H:i:s'));
+
+ $date->ceil('year');
+ $this->assertSame('2023-01-01 00:00:00', $date->format('Y-m-d H:i:s'));
+
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid rounding unit');
+ $date->ceil('foo');
+ }
+
/**
* @covers ::compare
*/
@@ -77,6 +107,36 @@ public function testDay()
$this->assertSame('2021-12-13', $date->format('Y-m-d'));
}
+ /**
+ * @covers ::floor
+ */
+ public function testFloor()
+ {
+ $date = new Date('2021-12-12 12:12:12');
+
+ $date->floor('second');
+ $this->assertSame('2021-12-12 12:12:12', $date->format('Y-m-d H:i:s'));
+
+ $date->floor('minute');
+ $this->assertSame('2021-12-12 12:12:00', $date->format('Y-m-d H:i:s'));
+
+ $date->floor('hour');
+ $this->assertSame('2021-12-12 12:00:00', $date->format('Y-m-d H:i:s'));
+
+ $date->floor('day');
+ $this->assertSame('2021-12-12 00:00:00', $date->format('Y-m-d H:i:s'));
+
+ $date->floor('month');
+ $this->assertSame('2021-12-01 00:00:00', $date->format('Y-m-d H:i:s'));
+
+ $date->floor('year');
+ $this->assertSame('2021-01-01 00:00:00', $date->format('Y-m-d H:i:s'));
+
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('Invalid rounding unit');
+ $date->floor('foo');
+ }
+
/**
* @covers ::hour
*/
@@ -241,6 +301,19 @@ public function testMonth()
$this->assertSame('2021-11-12', $date->format('Y-m-d'));
}
+ /**
+ * @covers ::nearest
+ */
+ public function testNearest()
+ {
+ $date = new Date('2021-12-12');
+ $a = new Date('2021-12-11');
+ $b = new Date('2021-12-15');
+ $c = new Date('2021-11-11');
+
+ $this->assertSame($a, $date->nearest($a, $b, $c));
+ }
+
/**
* @covers ::now
*/
diff --git a/tests/Toolkit/ObjTest.php b/tests/Toolkit/ObjTest.php
index 01c7cc5ff2..351d59ee50 100644
--- a/tests/Toolkit/ObjTest.php
+++ b/tests/Toolkit/ObjTest.php
@@ -10,6 +10,7 @@
class ObjTest extends TestCase
{
/**
+ * covers ::__construct
* @covers ::__call
*/
public function test__call()
From 8eee97dc91dc0b8b715bd983969e239cd61289ca Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 15:57:42 +0100
Subject: [PATCH 084/202] Fix `Toolkit\Dom` coverage annotations
---
src/Toolkit/Dom.php | 10 ++++------
tests/Toolkit/DomTest.php | 4 ++++
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/Toolkit/Dom.php b/src/Toolkit/Dom.php
index 2b858f048d..4b42d7af77 100644
--- a/src/Toolkit/Dom.php
+++ b/src/Toolkit/Dom.php
@@ -710,7 +710,7 @@ protected static function normalizeSanitizeOptions(array $options): array
return $options;
}
- $options = array_merge([
+ return [
'allowedAttrPrefixes' => [],
'allowedAttrs' => true,
'allowedDataUris' => true,
@@ -724,11 +724,9 @@ protected static function normalizeSanitizeOptions(array $options): array
'doctypeCallback' => null,
'elementCallback' => null,
'urlAttrs' => ['href', 'src', 'xlink:href'],
- ], $options);
-
- $options['_normalized'] = true;
-
- return $options;
+ ...$options,
+ '_normalized' => true
+ ];
}
/**
diff --git a/tests/Toolkit/DomTest.php b/tests/Toolkit/DomTest.php
index 839d62a02c..80fe487a7c 100644
--- a/tests/Toolkit/DomTest.php
+++ b/tests/Toolkit/DomTest.php
@@ -631,6 +631,7 @@ public static function isAllowedAttrProvider(): array
/**
* @dataProvider isAllowedAttrProvider
* @covers ::isAllowedAttr
+ * @covers ::normalizeSanitizeOptions
*/
public function testIsAllowedAttr(string $tag, string $attr, $allowedAttrs, $allowedAttrPrefixes, $allowedTags, $expected)
{
@@ -790,6 +791,7 @@ public static function isAllowedGlobalAttrProvider(): array
/**
* @dataProvider isAllowedGlobalAttrProvider
* @covers ::isAllowedGlobalAttr
+ * @covers ::normalizeSanitizeOptions
*/
public function testIsAllowedGlobalAttr(string $name, $allowedAttrs, $allowedAttrPrefixes, $expected)
{
@@ -941,6 +943,7 @@ public static function isAllowedUrlProvider(): array
/**
* @dataProvider isAllowedUrlProvider
* @covers ::isAllowedUrl
+ * @covers ::normalizeSanitizeOptions
*/
public function testIsAllowedUrl(string $url, $expected, array $options = [])
{
@@ -1253,6 +1256,7 @@ public static function listContainsNameProvider(): array
/**
* @dataProvider listContainsNameProvider
* @covers ::listContainsName
+ * @covers ::normalizeSanitizeOptions
*/
public function testListContainsName(array $list, array $node, $allowedNamespaces, string|null $compare, $expected)
{
From 4f8ddea74b4592281bb2b2e3dec2641ab8052bb5 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 16:06:47 +0100
Subject: [PATCH 085/202] Add coverage annotations to `Toolkit\Component`
---
tests/Toolkit/ComponentTest.php | 91 ++++++++++++++++++++++++++++++---
1 file changed, 85 insertions(+), 6 deletions(-)
diff --git a/tests/Toolkit/ComponentTest.php b/tests/Toolkit/ComponentTest.php
index 31106e2f18..565382a45e 100644
--- a/tests/Toolkit/ComponentTest.php
+++ b/tests/Toolkit/ComponentTest.php
@@ -5,6 +5,9 @@
use Kirby\Exception\Exception;
use Kirby\Exception\InvalidArgumentException;
+/**
+ * @coversDefaultClass \Kirby\Toolkit\Component
+ */
class ComponentTest extends TestCase
{
public function tearDown(): void
@@ -13,14 +16,17 @@ public function tearDown(): void
Component::$mixins = [];
}
+ /**
+ * @covers ::__construct
+ * @covers ::__call
+ * @covers ::applyProps
+ */
public function testProp()
{
Component::$types = [
'test' => [
'props' => [
- 'prop' => function ($prop) {
- return $prop;
- }
+ 'prop' => fn ($prop) => $prop
]
]
];
@@ -31,14 +37,15 @@ public function testProp()
$this->assertSame('prop value', $component->prop);
}
+ /**
+ * @covers ::applyProps
+ */
public function testPropWithDefaultValue()
{
Component::$types = [
'test' => [
'props' => [
- 'prop' => function ($prop = 'default value') {
- return $prop;
- }
+ 'prop' => fn ($prop = 'default value') => $prop
]
]
];
@@ -49,6 +56,9 @@ public function testPropWithDefaultValue()
$this->assertSame('default value', $component->prop);
}
+ /**
+ * @covers ::applyProps
+ */
public function testPropWithFixedValue()
{
Component::$types = [
@@ -65,6 +75,9 @@ public function testPropWithFixedValue()
$this->assertSame('test', $component->prop);
}
+ /**
+ * @covers ::__construct
+ */
public function testAttrs()
{
Component::$types = [
@@ -77,6 +90,11 @@ public function testAttrs()
$this->assertSame('bar', $component->foo);
}
+ /**
+ * @covers ::__construct
+ * @covers ::__call
+ * @covers ::applyComputed
+ */
public function testComputed()
{
Component::$types = [
@@ -93,6 +111,11 @@ public function testComputed()
$this->assertSame('computed prop', $component->prop);
}
+ /**
+ * @covers ::__construct
+ * @covers ::__call
+ * @covers ::applyComputed
+ */
public function testComputedFromProp()
{
Component::$types = [
@@ -111,6 +134,10 @@ public function testComputedFromProp()
$this->assertSame('computed: prop value', $component->prop());
}
+ /**
+ * @covers ::__construct
+ * @covers ::__call
+ */
public function testMethod()
{
Component::$types = [
@@ -126,6 +153,10 @@ public function testMethod()
$this->assertSame('hello world', $component->say());
}
+ /**
+ * @covers ::__construct
+ * @covers ::__call
+ */
public function testPropsInMethods()
{
Component::$types = [
@@ -144,6 +175,10 @@ public function testPropsInMethods()
$this->assertSame('hello world', $component->say());
}
+ /**
+ * @covers ::__construct
+ * @covers ::__call
+ */
public function testComputedPropsInMethods()
{
Component::$types = [
@@ -165,6 +200,10 @@ public function testComputedPropsInMethods()
$this->assertSame('HELLO WORLD', $component->say());
}
+ /**
+ * @covers ::toArray
+ * @covers ::__debugInfo
+ */
public function testToArray()
{
Component::$types = [
@@ -188,6 +227,10 @@ public function testToArray()
$this->assertSame($expected, $component->__debugInfo());
}
+ /**
+ * @covers ::toArray
+ * @covers ::__debugInfo
+ */
public function testCustomToArray()
{
Component::$types = [
@@ -203,6 +246,9 @@ public function testCustomToArray()
$this->assertSame(['foo' => 'bar'], $component->toArray());
}
+ /**
+ * @covers ::__construct
+ */
public function testInvalidType()
{
$this->expectException(InvalidArgumentException::class);
@@ -211,6 +257,9 @@ public function testInvalidType()
new Component('test');
}
+ /**
+ * @covers ::load
+ */
public function testLoadInvalidFile()
{
Component::$types = ['foo' => 'bar'];
@@ -220,6 +269,10 @@ public function testLoadInvalidFile()
Component::load('foo');
}
+ /**
+ * @covers ::__construct
+ * @covers ::setup
+ */
public function testMixins()
{
Component::$mixins = [
@@ -244,4 +297,30 @@ public function testMixins()
$this->assertSame('HELLO WORLD', $component->message());
$this->assertSame('HELLO WORLD', $component->message);
}
+
+ /**
+ * @covers ::__get
+ */
+ public function testGetInvalidProp()
+ {
+ Component::$types = [
+ 'test' => []
+ ];
+
+ $component = new Component('test');
+ $this->assertNull($component->foo);
+ }
+
+ /**
+ * @covers ::defaults
+ */
+ public function testDefaults()
+ {
+ Component::$types = [
+ 'test' => []
+ ];
+
+ $component = new Component('test');
+ $this->assertSame([], $component->defaults());
+ }
}
From ad9f9aa4f6f915626b3bc2d86a62bf133be565c1 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 18:57:05 +0100
Subject: [PATCH 086/202] Improve `Text` package unit tests and coverage
---
src/Text/KirbyTag.php | 2 +-
tests/Text/FileKirbyTagTest.php | 170 +++++++
tests/Text/ImageKirbyTagTest.php | 256 ++++++++++
tests/Text/KirbyTagTest.php | 188 +++++++-
tests/Text/KirbyTagsTest.php | 772 +------------------------------
tests/Text/LinkKirbyTagTest.php | 245 ++++++++++
tests/Text/MarkdownTest.php | 11 +
tests/Text/VideoKirbyTagTest.php | 256 ++++++++++
tests/Text/fixtures/inline.html | 6 +
tests/Text/fixtures/inline.md | 6 +
10 files changed, 1121 insertions(+), 791 deletions(-)
create mode 100644 tests/Text/FileKirbyTagTest.php
create mode 100644 tests/Text/ImageKirbyTagTest.php
create mode 100644 tests/Text/LinkKirbyTagTest.php
create mode 100644 tests/Text/VideoKirbyTagTest.php
create mode 100644 tests/Text/fixtures/inline.html
create mode 100644 tests/Text/fixtures/inline.md
diff --git a/src/Text/KirbyTag.php b/src/Text/KirbyTag.php
index 1d9736860d..bf62924bf6 100644
--- a/src/Text/KirbyTag.php
+++ b/src/Text/KirbyTag.php
@@ -219,7 +219,7 @@ public static function parse(
*/
public function parent(): ModelWithContent|null
{
- return $this->data['parent'];
+ return $this->data['parent'] ?? null;
}
public function render(): string
diff --git a/tests/Text/FileKirbyTagTest.php b/tests/Text/FileKirbyTagTest.php
new file mode 100644
index 0000000000..3054d81bda
--- /dev/null
+++ b/tests/Text/FileKirbyTagTest.php
@@ -0,0 +1,170 @@
+app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ]
+ ]);
+
+ Dir::make(static::TMP);
+ }
+
+ public function tearDown(): void
+ {
+ Dir::remove(static::TMP);
+ }
+
+ public function testFile()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(file: a.jpg)'
+ ],
+ 'files' => [
+ [
+ 'filename' => 'a.jpg',
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $file = $page->file('a.jpg');
+
+ $expected = 'a.jpg
';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testFileWithUUID()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(file: file://file-a)',
+ 'uuid' => 'page-uuid' // this is just to make sure that the test doesn't try to create a content file for this page with a generated UUID
+ ],
+ 'files' => [
+ [
+ 'filename' => 'a.jpg',
+ 'content' => ['uuid' => 'file-a']
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $file = $page->file('a.jpg');
+
+ $expected = 'a.jpg
';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testFileDoesNotExist()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(file: a.jpg) (file: b.jpg text: b)'
+ ]
+ ],
+
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+
+ $this->assertSame('a.jpg b
', $page->text()->kt()->value());
+ }
+
+ public function testFileWithDisabledDownloadOption()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(file: a.jpg download: false)'
+ ],
+ 'files' => [
+ [
+ 'filename' => 'a.jpg',
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $file = $page->file('a.jpg');
+
+ $expected = 'a.jpg
';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testFileWithinFile()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'a.jpg',
+ 'content' => [
+ 'caption' => '(file: b.jpg)'
+ ]
+ ],
+ [
+ 'filename' => 'b.jpg'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $a = $kirby->file('a/a.jpg');
+ $b = $kirby->file('a/b.jpg');
+ $expected = 'b.jpg
';
+
+ $this->assertSame($expected, $a->caption()->kt()->value());
+ }
+}
diff --git a/tests/Text/ImageKirbyTagTest.php b/tests/Text/ImageKirbyTagTest.php
new file mode 100644
index 0000000000..e4fbde3270
--- /dev/null
+++ b/tests/Text/ImageKirbyTagTest.php
@@ -0,0 +1,256 @@
+app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ]
+ ]);
+
+ Dir::make(static::TMP);
+ }
+
+ public function tearDown(): void
+ {
+ Dir::remove(static::TMP);
+ }
+
+ public function testWithoutFigure()
+ {
+ $kirby = $this->app->clone([
+ 'options' => [
+ 'kirbytext' => [
+ 'image' => [
+ 'figure' => false
+ ]
+ ]
+ ]
+ ]);
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $kirby->kirbytext('(image: https://test.com/something.jpg)'));
+ }
+
+ public function testWithCaption()
+ {
+ $kirby = $this->app->clone();
+ $expected = 'This is an awesome image and this a link ';
+
+ $this->assertSame($expected, $kirby->kirbytext('(image: myimage.jpg caption: This is an *awesome* image and this a link )'));
+ }
+
+ public function testWithSrcset()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(image: image.jpg srcset: 200, 300)'
+ ],
+ 'files' => [
+ [
+ 'filename' => 'image.jpg',
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $image = $page->file('image.jpg');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testWithSrcsetFromThumbsOption()
+ {
+ $kirby = $this->app->clone([
+ 'options' => [
+ 'thumbs' => [
+ 'srcsets' => [
+ 'album' => [
+ '800w' => ['width' => 800],
+ '1024w' => ['width' => 1024]
+ ]
+ ]
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(image: image.jpg srcset: album)'
+ ],
+ 'files' => [
+ [
+ 'filename' => 'image.jpg',
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $image = $page->file('image.jpg');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testWithSrcsetFromDefaults()
+ {
+ $kirby = $this->app->clone([
+ 'options' => [
+ 'kirbytext' => [
+ 'image' => [
+ 'srcset' => [200, 300]
+ ]
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(image: image.jpg)'
+ ],
+ 'files' => [
+ [
+ 'filename' => 'image.jpg',
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $image = $page->file('image.jpg');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testWithFileLink()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(image: image.jpg link: document.pdf)'
+ ],
+ 'files' => [
+ [
+ 'filename' => 'image.jpg',
+ ],
+ [
+ 'filename' => 'document.pdf',
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $image = $page->file('image.jpg');
+ $doc = $page->file('document.pdf');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testWithFileUUID()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => [
+ 'text' => '(image: file://image-uuid)',
+ 'uuid' => 'page-uuid' // this is just to make sure that the test doesn't try to create a content file for this page with a generated UUID
+ ],
+ 'files' => [
+ [
+ 'filename' => 'image.jpg',
+ 'content' => ['uuid' => 'image-uuid']
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('a');
+ $image = $page->file('image.jpg');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testWithParent()
+ {
+ $app = new App([
+ 'roots' => [
+ 'index' => '/dev/null',
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'a.jpg'
+ ],
+ [
+ 'filename' => 'b.jpg'
+ ],
+ [
+ 'filename' => 'c.jpg'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $app->page('a');
+ $image = $page->image('b.jpg');
+ $expected = ' ';
+
+ $this->assertSame($expected, $app->kirbytag('image', 'b.jpg', [], [
+ 'parent' => $page,
+ ]));
+ }
+}
diff --git a/tests/Text/KirbyTagTest.php b/tests/Text/KirbyTagTest.php
index 466410bed8..45d6d1a7e0 100644
--- a/tests/Text/KirbyTagTest.php
+++ b/tests/Text/KirbyTagTest.php
@@ -12,6 +12,8 @@
*/
class KirbyTagTest extends TestCase
{
+ public const TMP = KIRBY_TMP_DIR . '/Text.KirbyTag';
+
public function setUp(): void
{
KirbyTag::$types = [
@@ -161,6 +163,148 @@ public function testFactory()
$this->assertSame('test: test value-attrA-attrB', $result);
}
+ /**
+ * @covers ::file
+ */
+ public function testFile()
+ {
+ $app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'a.jpg'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $app->page('a');
+ $file = $page->file('a.jpg');
+ $tag = new KirbyTag('image', 'foo');
+ $this->assertSame($file, $tag->file('a/a.jpg'));
+ }
+
+ /**
+ * @covers ::file
+ */
+ public function testFileInParent()
+ {
+ $app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'a.jpg'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $app->page('a');
+ $file = $page->file('a.jpg');
+ $tag = new KirbyTag('image', 'foo', [], [
+ 'parent' => $page,
+ ]);
+ $this->assertSame($file, $tag->file('a.jpg'));
+ }
+
+ /**
+ * @covers ::file
+ */
+ public function testFileInFileParent()
+ {
+ $app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'a.jpg'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $app->page('a');
+ $file = $page->file('a.jpg');
+ $tag = new KirbyTag('image', 'foo', [], [
+ 'parent' => $file,
+ ]);
+ $this->assertSame($file, $tag->file('a.jpg'));
+ }
+
+ /**
+ * @covers ::file
+ */
+ public function testFileFromUuid()
+ {
+ $app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'a.jpg',
+ 'content' => ['uuid' => 'image-uuid']
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $app->page('a');
+ $file = $page->file('a.jpg');
+ $tag = new KirbyTag('image', 'foo');
+ $this->assertSame($file, $tag->file('file://image-uuid'));
+
+ // with parent
+ $tag = new KirbyTag('image', 'foo', [], [
+ 'parent' => $page,
+ ]);
+ $this->assertSame($file, $tag->file('file://image-uuid'));
+ }
+
+ /**
+ * @covers ::kirby
+ */
+ public function testKirby()
+ {
+ $app = new App([
+ 'roots' => [
+ 'index' => '/dev/null',
+ ]
+ ]);
+
+ $tag = new KirbyTag('image', 'b.jpg');
+ $this->assertSame($app, $tag->kirby());
+ }
+
/**
* @covers ::option
*/
@@ -188,7 +332,10 @@ public function testOption()
$this->assertSame('optionC', $tag->option('c', 'optionC'));
}
- public function testWithParent()
+ /**
+ * @covers ::parent
+ */
+ public function testParent()
{
$app = new App([
'roots' => [
@@ -201,12 +348,6 @@ public function testWithParent()
'files' => [
[
'filename' => 'a.jpg'
- ],
- [
- 'filename' => 'b.jpg'
- ],
- [
- 'filename' => 'c.jpg'
]
]
]
@@ -214,25 +355,12 @@ public function testWithParent()
]
]);
- $page = $app->page('a');
- $image = $page->image('b.jpg');
- $expected = ' ';
-
- $this->assertSame($expected, $app->kirbytag('image', 'b.jpg', [], [
+ $page = $app->page('a');
+ $tag = new KirbyTag('image', 'b.jpg', [], [
'parent' => $page,
- ]));
- }
+ ]);
- /**
- * @covers ::parse
- * @dataProvider parseProvider
- */
- public function testParse(string $string, array $data, array $options, array $expected)
- {
- $tag = KirbyTag::parse($string, $data, $options);
- foreach ($expected as $key => $value) {
- $this->assertSame($value, $tag->$key);
- }
+ $this->assertSame($page, $tag->parent());
}
public static function parseProvider(): array
@@ -386,6 +514,18 @@ public static function parseProvider(): array
];
}
+ /**
+ * @covers ::parse
+ * @dataProvider parseProvider
+ */
+ public function testParse(string $string, array $data, array $options, array $expected)
+ {
+ $tag = KirbyTag::parse($string, $data, $options);
+ foreach ($expected as $key => $value) {
+ $this->assertSame($value, $tag->$key);
+ }
+ }
+
/**
* @covers ::render
*/
diff --git a/tests/Text/KirbyTagsTest.php b/tests/Text/KirbyTagsTest.php
index 4bcc91f025..51fbd39e92 100644
--- a/tests/Text/KirbyTagsTest.php
+++ b/tests/Text/KirbyTagsTest.php
@@ -5,7 +5,6 @@
use Exception;
use Kirby\Cms\App;
use Kirby\Exception\InvalidArgumentException;
-use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\Dir;
use Kirby\Filesystem\F;
use Kirby\TestCase;
@@ -234,549 +233,14 @@ public function testWithMarkdownExtra($kirbytext, $expected)
$this->assertSame($expected, $kirby->kirbytext($kirbytext));
}
- public function testImageWithoutFigure()
- {
- $kirby = $this->app->clone([
- 'options' => [
- 'kirbytext' => [
- 'image' => [
- 'figure' => false
- ]
- ]
- ]
- ]);
-
- $expected = ' ';
-
- $this->assertSame($expected, $kirby->kirbytext('(image: https://test.com/something.jpg)'));
- }
-
- public function testImageWithCaption()
- {
- $kirby = $this->app->clone();
- $expected = 'This is an awesome image and this a link ';
-
- $this->assertSame($expected, $kirby->kirbytext('(image: myimage.jpg caption: This is an *awesome* image and this a link )'));
- }
-
- public function testImageWithSrcset()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(image: image.jpg srcset: 200, 300)'
- ],
- 'files' => [
- [
- 'filename' => 'image.jpg',
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $image = $page->file('image.jpg');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testImageWithSrcsetFromThumbsOption()
- {
- $kirby = $this->app->clone([
- 'options' => [
- 'thumbs' => [
- 'srcsets' => [
- 'album' => [
- '800w' => ['width' => 800],
- '1024w' => ['width' => 1024]
- ]
- ]
- ]
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(image: image.jpg srcset: album)'
- ],
- 'files' => [
- [
- 'filename' => 'image.jpg',
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $image = $page->file('image.jpg');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testImageWithSrcsetFromDefaults()
- {
- $kirby = $this->app->clone([
- 'options' => [
- 'kirbytext' => [
- 'image' => [
- 'srcset' => [200, 300]
- ]
- ]
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(image: image.jpg)'
- ],
- 'files' => [
- [
- 'filename' => 'image.jpg',
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $image = $page->file('image.jpg');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testImageWithFileLink()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(image: image.jpg link: document.pdf)'
- ],
- 'files' => [
- [
- 'filename' => 'image.jpg',
- ],
- [
- 'filename' => 'document.pdf',
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $image = $page->file('image.jpg');
- $doc = $page->file('document.pdf');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testImageWithFileUUID()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(image: file://image-uuid)',
- 'uuid' => 'page-uuid' // this is just to make sure that the test doesn't try to create a content file for this page with a generated UUID
- ],
- 'files' => [
- [
- 'filename' => 'image.jpg',
- 'content' => ['uuid' => 'image-uuid']
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $image = $page->file('image.jpg');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testFile()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(file: a.jpg)'
- ],
- 'files' => [
- [
- 'filename' => 'a.jpg',
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $file = $page->file('a.jpg');
-
- $expected = 'a.jpg
';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testFileWithUUID()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(file: file://file-a)',
- 'uuid' => 'page-uuid' // this is just to make sure that the test doesn't try to create a content file for this page with a generated UUID
- ],
- 'files' => [
- [
- 'filename' => 'a.jpg',
- 'content' => ['uuid' => 'file-a']
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $file = $page->file('a.jpg');
-
- $expected = 'a.jpg
';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testFileDoesNotExist()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(file: a.jpg) (file: b.jpg text: b)'
- ]
- ],
-
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
-
- $this->assertSame('a.jpg b
', $page->text()->kt()->value());
- }
-
- public function testFileWithDisabledDownloadOption()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => [
- 'text' => '(file: a.jpg download: false)'
- ],
- 'files' => [
- [
- 'filename' => 'a.jpg',
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('a');
- $file = $page->file('a.jpg');
-
- $expected = 'a.jpg
';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testFileWithinFile()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'files' => [
- [
- 'filename' => 'a.jpg',
- 'content' => [
- 'caption' => '(file: b.jpg)'
- ]
- ],
- [
- 'filename' => 'b.jpg'
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $a = $kirby->file('a/a.jpg');
- $b = $kirby->file('a/b.jpg');
- $expected = 'b.jpg
';
-
- $this->assertSame($expected, $a->caption()->kt()->value());
- }
-
- public function testLinkWithLangAttribute()
- {
- $app = $this->app->clone([
- 'urls' => [
- 'index' => 'https://getkirby.com'
- ],
- 'languages' => [
- 'en' => [
- 'code' => 'en'
- ],
- 'de' => [
- 'code' => 'de'
- ]
- ],
- 'site' => [
- 'children' => [
- ['slug' => 'a']
- ]
- ]
- ]);
-
- $this->assertSame('getkirby.com/en/a ', $app->kirbytags('(link: a lang: en)'));
- $this->assertSame('getkirby.com/de/a ', $app->kirbytags('(link: a lang: de)'));
- }
-
- public function testLinkWithHash()
- {
- $app = $this->app->clone([
- 'urls' => [
- 'index' => 'https://getkirby.com'
- ],
- 'languages' => [
- 'en' => [
- 'code' => 'en'
- ],
- 'de' => [
- 'code' => 'de'
- ]
- ],
- 'site' => [
- 'children' => [
- ['slug' => 'a']
- ]
- ]
- ]);
-
- $this->assertSame('getkirby.com/en/a ', $app->kirbytags('(link: a)'));
- $this->assertSame('getkirby.com/de/a ', $app->kirbytags('(link: a lang: de)'));
- $this->assertSame('getkirby.com/en/a ', $app->kirbytags('(link: a#anchor lang: en)'));
- $this->assertSame('getkirby.com/de/a ', $app->kirbytags('(link: a#anchor lang: de)'));
- }
-
- public function testLinkWithUuid()
- {
- $app = $this->app->clone([
- 'urls' => [
- 'index' => 'https://getkirby.com'
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => ['uuid' => 'page-uuid'],
- 'files' => [
- [
- 'filename' => 'foo.jpg',
- 'content' => ['uuid' => 'file-uuid'],
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $result = $app->kirbytags('(link: page://page-uuid)');
- $this->assertSame('getkirby.com/a ', $result);
-
- $result = $app->kirbytags('(link: page://not-exists)');
- $this->assertSame('getkirby.com/error ', $result);
-
- $result = $app->kirbytags('(link: file://file-uuid text: file)');
- $this->assertSame('file ', $result);
-
- $result = $app->kirbytags('(link: file://not-exists text: file)');
- $this->assertSame('file ', $result);
- }
-
- public function testLinkWithUuidDebug()
- {
- $app = $this->app->clone([
- 'urls' => [
- 'index' => 'https://getkirby.com'
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => ['uuid' => 'page-uuid'],
- 'files' => [
- [
- 'filename' => 'foo.jpg',
- 'content' => ['uuid' => 'file-uuid'],
- ]
- ]
- ]
- ]
- ],
- 'options' => [
- 'debug' => true
- ]
- ]);
-
- $this->expectException(NotFoundException::class);
- $this->expectExceptionMessage('The linked page cannot be found');
-
- $app->kirbytags('(link: page://not-exists)');
- }
-
- public function testLinkWithUuidDebugText()
- {
- $app = $this->app->clone([
- 'urls' => [
- 'index' => 'https://getkirby.com'
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'content' => ['uuid' => 'page-uuid'],
- 'files' => [
- [
- 'filename' => 'foo.jpg',
- 'content' => ['uuid' => 'file-uuid'],
- ]
- ]
- ]
- ]
- ],
- 'options' => [
- 'debug' => true
- ]
- ]);
-
- $this->expectException(NotFoundException::class);
- $this->expectExceptionMessage('The linked page cannot be found for the link text "click here"');
-
- $app->kirbytags('(link: page://not-exists text: click here)');
- }
-
- public function testLinkWithUuidAndLang()
- {
- $app = $this->app->clone([
- 'urls' => [
- 'index' => 'https://getkirby.com'
- ],
- 'languages' => [
- [
- 'code' => 'en',
- 'name' => 'English',
- 'default' => true,
- 'locale' => 'en_US',
- 'url' => '/',
- ],
- [
- 'code' => 'de',
- 'name' => 'Deutsch',
- 'locale' => 'de_DE',
- 'url' => '/de',
- ],
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'a',
- 'files' => [
- [
- 'filename' => 'foo.jpg',
- 'translations' => [
- [
- 'code' => 'en',
- 'content' => ['uuid' => 'file-uuid']
- ],
- [
- 'code' => 'de',
- 'content' => []
- ]
- ]
- ]
- ],
- 'translations' => [
- [
- 'code' => 'en',
- 'content' => ['uuid' => 'page-uuid']
- ],
- [
- 'code' => 'de',
- 'content' => ['slug' => 'ae']
- ]
- ]
- ]
- ]
- ]
- ]);
-
- $result = $app->kirbytags('(link: page://page-uuid lang: de)');
- $this->assertSame('getkirby.com/de/ae ', $result);
-
- $result = $app->kirbytags('(link: file://file-uuid text: file lang: de)');
- $this->assertSame('file ', $result);
- }
-
+ /**
+ * @coversNothing
+ */
public function testHooks()
{
$app = $this->app->clone([
'hooks' => [
- 'kirbytags:before' => function ($text, $data, $options) {
- return 'before';
- },
+ 'kirbytags:before' => fn ($text, $data, $options) => 'before'
]
]);
@@ -784,238 +248,13 @@ public function testHooks()
$app = $app->clone([
'hooks' => [
- 'kirbytags:after' => function ($text, $data, $options) {
- return 'after';
- },
+ 'kirbytags:after' => fn ($text, $data, $options) => 'after'
]
]);
$this->assertSame('after', $app->kirbytags('test'));
}
- public function testVideoLocal()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: sample.mp4)'
- ],
- 'files' => [
- ['filename' => 'sample.mp4']
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
- $image = $page->file('sample.mp4');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testVideoInlineAttrs()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: sample.mp4
- autoplay: true
- caption: Lorem ipsum
- controls: false
- class: video-class
- height: 350
- loop: true
- muted: true
- playsinline: true
- poster: sample.jpg
- preload: auto
- style: border: none
- width: 500)'
- ],
- 'files' => [
- ['filename' => 'sample.mp4'],
- ['filename' => 'sample.jpg']
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
-
- $image = $page->file('sample.jpg');
- $video = $page->file('sample.mp4');
-
- $expected = 'Lorem ipsum ';
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testVideoPredefinedAttrs()
- {
- $kirby = $this->app->clone([
- 'options' => [
- 'kirbytext' => [
- 'video' => [
- 'autoplay' => true,
- 'caption' => 'Lorem ipsum',
- 'controls' => false,
- 'class' => 'video-class',
- 'height' => 350,
- 'loop' => true,
- 'muted' => true,
- 'playsinline' => true,
- 'poster' => 'sample.jpg',
- 'preload' => 'auto',
- 'style' => 'border: none',
- 'width' => 500
- ]
- ]
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: sample.mp4)'
- ],
- 'files' => [
- ['filename' => 'sample.mp4'],
- ['filename' => 'sample.jpg']
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
-
- $image = $page->file('sample.jpg');
- $video = $page->file('sample.mp4');
-
- $expected = 'Lorem ipsum ';
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testVideoAutoplayRelatedAttrs()
- {
- $kirby = new App([
- 'roots' => [
- 'index' => '/dev/null',
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: sample.mp4 autoplay: true)'
- ],
- 'files' => [
- ['filename' => 'sample.mp4']
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
- $video = $page->file('sample.mp4');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testVideoAutoplayAttrsOverride()
- {
- $kirby = new App([
- 'roots' => [
- 'index' => '/dev/null',
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: sample.mp4 autoplay: true muted: false playsinline: false)'
- ],
- 'files' => [
- ['filename' => 'sample.mp4']
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
- $image = $page->file('sample.mp4');
-
- $expected = ' ';
-
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testVideoOptions()
- {
- $kirby = $this->app->clone([
- 'options' => [
- 'kirbytext' => [
- 'video' => [
- 'options' => [
- 'youtube' => [
- 'controls' => 0
- ]
- ]
- ]
- ]
- ],
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: https://www.youtube.com/watch?v=VhP7ZzZysQg)'
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
-
- $expected = 'VIDEO ';
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
- public function testVideoRemote()
- {
- $kirby = $this->app->clone([
- 'site' => [
- 'children' => [
- [
- 'slug' => 'test',
- 'content' => [
- 'text' => '(video: https://getkirby.com/sample.mp4)'
- ]
- ]
- ]
- ]
- ]);
-
- $page = $kirby->page('test');
-
- $expected = ' ';
- $this->assertSame($expected, $page->text()->kt()->value());
- }
-
public static function globalOptionsProvider(): array
{
return [
@@ -1039,6 +278,7 @@ public static function globalOptionsProvider(): array
}
/**
+ * @coversNothing
* @dataProvider globalOptionsProvider
*/
public function testGlobalOptions($kirbytext, $expected)
diff --git a/tests/Text/LinkKirbyTagTest.php b/tests/Text/LinkKirbyTagTest.php
new file mode 100644
index 0000000000..47a937c070
--- /dev/null
+++ b/tests/Text/LinkKirbyTagTest.php
@@ -0,0 +1,245 @@
+app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ]
+ ]);
+
+ Dir::make(static::TMP);
+ }
+
+ public function tearDown(): void
+ {
+ Dir::remove(static::TMP);
+ }
+
+ public function testWithLangAttribute()
+ {
+ $app = $this->app->clone([
+ 'urls' => [
+ 'index' => 'https://getkirby.com'
+ ],
+ 'languages' => [
+ 'en' => [
+ 'code' => 'en'
+ ],
+ 'de' => [
+ 'code' => 'de'
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ ['slug' => 'a']
+ ]
+ ]
+ ]);
+
+ $this->assertSame('getkirby.com/en/a ', $app->kirbytags('(link: a lang: en)'));
+ $this->assertSame('getkirby.com/de/a ', $app->kirbytags('(link: a lang: de)'));
+ }
+
+ public function testWithHash()
+ {
+ $app = $this->app->clone([
+ 'urls' => [
+ 'index' => 'https://getkirby.com'
+ ],
+ 'languages' => [
+ 'en' => [
+ 'code' => 'en'
+ ],
+ 'de' => [
+ 'code' => 'de'
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ ['slug' => 'a']
+ ]
+ ]
+ ]);
+
+ $this->assertSame('getkirby.com/en/a ', $app->kirbytags('(link: a)'));
+ $this->assertSame('getkirby.com/de/a ', $app->kirbytags('(link: a lang: de)'));
+ $this->assertSame('getkirby.com/en/a ', $app->kirbytags('(link: a#anchor lang: en)'));
+ $this->assertSame('getkirby.com/de/a ', $app->kirbytags('(link: a#anchor lang: de)'));
+ }
+
+ public function testWithUuid()
+ {
+ $app = $this->app->clone([
+ 'urls' => [
+ 'index' => 'https://getkirby.com'
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => ['uuid' => 'page-uuid'],
+ 'files' => [
+ [
+ 'filename' => 'foo.jpg',
+ 'content' => ['uuid' => 'file-uuid'],
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $result = $app->kirbytags('(link: page://page-uuid)');
+ $this->assertSame('getkirby.com/a ', $result);
+
+ $result = $app->kirbytags('(link: page://not-exists)');
+ $this->assertSame('getkirby.com/error ', $result);
+
+ $result = $app->kirbytags('(link: file://file-uuid text: file)');
+ $this->assertSame('file ', $result);
+
+ $result = $app->kirbytags('(link: file://not-exists text: file)');
+ $this->assertSame('file ', $result);
+ }
+
+ public function testWithUuidDebug()
+ {
+ $app = $this->app->clone([
+ 'urls' => [
+ 'index' => 'https://getkirby.com'
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => ['uuid' => 'page-uuid'],
+ 'files' => [
+ [
+ 'filename' => 'foo.jpg',
+ 'content' => ['uuid' => 'file-uuid'],
+ ]
+ ]
+ ]
+ ]
+ ],
+ 'options' => [
+ 'debug' => true
+ ]
+ ]);
+
+ $this->expectException(NotFoundException::class);
+ $this->expectExceptionMessage('The linked page cannot be found');
+
+ $app->kirbytags('(link: page://not-exists)');
+ }
+
+ public function testWithUuidDebugText()
+ {
+ $app = $this->app->clone([
+ 'urls' => [
+ 'index' => 'https://getkirby.com'
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'content' => ['uuid' => 'page-uuid'],
+ 'files' => [
+ [
+ 'filename' => 'foo.jpg',
+ 'content' => ['uuid' => 'file-uuid'],
+ ]
+ ]
+ ]
+ ]
+ ],
+ 'options' => [
+ 'debug' => true
+ ]
+ ]);
+
+ $this->expectException(NotFoundException::class);
+ $this->expectExceptionMessage('The linked page cannot be found for the link text "click here"');
+
+ $app->kirbytags('(link: page://not-exists text: click here)');
+ }
+
+ public function testWithUuidAndLang()
+ {
+ $app = $this->app->clone([
+ 'urls' => [
+ 'index' => 'https://getkirby.com'
+ ],
+ 'languages' => [
+ [
+ 'code' => 'en',
+ 'name' => 'English',
+ 'default' => true,
+ 'locale' => 'en_US',
+ 'url' => '/',
+ ],
+ [
+ 'code' => 'de',
+ 'name' => 'Deutsch',
+ 'locale' => 'de_DE',
+ 'url' => '/de',
+ ],
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'a',
+ 'files' => [
+ [
+ 'filename' => 'foo.jpg',
+ 'translations' => [
+ [
+ 'code' => 'en',
+ 'content' => ['uuid' => 'file-uuid']
+ ],
+ [
+ 'code' => 'de',
+ 'content' => []
+ ]
+ ]
+ ]
+ ],
+ 'translations' => [
+ [
+ 'code' => 'en',
+ 'content' => ['uuid' => 'page-uuid']
+ ],
+ [
+ 'code' => 'de',
+ 'content' => ['slug' => 'ae']
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $result = $app->kirbytags('(link: page://page-uuid lang: de)');
+ $this->assertSame('getkirby.com/de/ae ', $result);
+
+ $result = $app->kirbytags('(link: file://file-uuid text: file lang: de)');
+ $this->assertSame('file ', $result);
+ }
+}
diff --git a/tests/Text/MarkdownTest.php b/tests/Text/MarkdownTest.php
index 9e28eca59f..3f14038285 100644
--- a/tests/Text/MarkdownTest.php
+++ b/tests/Text/MarkdownTest.php
@@ -73,6 +73,17 @@ public function testParse()
$this->assertSame($html, $markdown->parse($md));
}
+ /**
+ * @covers ::parse
+ */
+ public function testParseInline()
+ {
+ $markdown = new Markdown();
+ $md = file_get_contents(static::FIXTURES . '/inline.md');
+ $html = file_get_contents(static::FIXTURES . '/inline.html');
+ $this->assertSame($html, $markdown->parse($md, true));
+ }
+
/**
* @covers ::parse
*/
diff --git a/tests/Text/VideoKirbyTagTest.php b/tests/Text/VideoKirbyTagTest.php
new file mode 100644
index 0000000000..b83648327d
--- /dev/null
+++ b/tests/Text/VideoKirbyTagTest.php
@@ -0,0 +1,256 @@
+app = new App([
+ 'roots' => [
+ 'index' => static::TMP
+ ]
+ ]);
+
+ Dir::make(static::TMP);
+ }
+
+ public function tearDown(): void
+ {
+ Dir::remove(static::TMP);
+ }
+
+ public function testLocal()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: sample.mp4)'
+ ],
+ 'files' => [
+ ['filename' => 'sample.mp4']
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+ $image = $page->file('sample.mp4');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testInlineAttrs()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: sample.mp4
+ autoplay: true
+ caption: Lorem ipsum
+ controls: false
+ class: video-class
+ height: 350
+ loop: true
+ muted: true
+ playsinline: true
+ poster: sample.jpg
+ preload: auto
+ style: border: none
+ width: 500)'
+ ],
+ 'files' => [
+ ['filename' => 'sample.mp4'],
+ ['filename' => 'sample.jpg']
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+
+ $image = $page->file('sample.jpg');
+ $video = $page->file('sample.mp4');
+
+ $expected = 'Lorem ipsum ';
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testPredefinedAttrs()
+ {
+ $kirby = $this->app->clone([
+ 'options' => [
+ 'kirbytext' => [
+ 'video' => [
+ 'autoplay' => true,
+ 'caption' => 'Lorem ipsum',
+ 'controls' => false,
+ 'class' => 'video-class',
+ 'height' => 350,
+ 'loop' => true,
+ 'muted' => true,
+ 'playsinline' => true,
+ 'poster' => 'sample.jpg',
+ 'preload' => 'auto',
+ 'style' => 'border: none',
+ 'width' => 500
+ ]
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: sample.mp4)'
+ ],
+ 'files' => [
+ ['filename' => 'sample.mp4'],
+ ['filename' => 'sample.jpg']
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+
+ $image = $page->file('sample.jpg');
+ $video = $page->file('sample.mp4');
+
+ $expected = 'Lorem ipsum ';
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testAutoplayRelatedAttrs()
+ {
+ $kirby = new App([
+ 'roots' => [
+ 'index' => '/dev/null',
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: sample.mp4 autoplay: true)'
+ ],
+ 'files' => [
+ ['filename' => 'sample.mp4']
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+ $video = $page->file('sample.mp4');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testAutoplayAttrsOverride()
+ {
+ $kirby = new App([
+ 'roots' => [
+ 'index' => '/dev/null',
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: sample.mp4 autoplay: true muted: false playsinline: false)'
+ ],
+ 'files' => [
+ ['filename' => 'sample.mp4']
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+ $image = $page->file('sample.mp4');
+
+ $expected = ' ';
+
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testOptions()
+ {
+ $kirby = $this->app->clone([
+ 'options' => [
+ 'kirbytext' => [
+ 'video' => [
+ 'options' => [
+ 'youtube' => [
+ 'controls' => 0
+ ]
+ ]
+ ]
+ ]
+ ],
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: https://www.youtube.com/watch?v=VhP7ZzZysQg)'
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+
+ $expected = 'VIDEO ';
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+
+ public function testRemote()
+ {
+ $kirby = $this->app->clone([
+ 'site' => [
+ 'children' => [
+ [
+ 'slug' => 'test',
+ 'content' => [
+ 'text' => '(video: https://getkirby.com/sample.mp4)'
+ ]
+ ]
+ ]
+ ]
+ ]);
+
+ $page = $kirby->page('test');
+
+ $expected = ' ';
+ $this->assertSame($expected, $page->text()->kt()->value());
+ }
+}
diff --git a/tests/Text/fixtures/inline.html b/tests/Text/fixtures/inline.html
new file mode 100644
index 0000000000..40232c1c05
--- /dev/null
+++ b/tests/Text/fixtures/inline.html
@@ -0,0 +1,6 @@
+italic
+
+bold
+
+This is some text
+and some more text 👀.
\ No newline at end of file
diff --git a/tests/Text/fixtures/inline.md b/tests/Text/fixtures/inline.md
new file mode 100644
index 0000000000..c23b51db04
--- /dev/null
+++ b/tests/Text/fixtures/inline.md
@@ -0,0 +1,6 @@
+*italic*
+
+**bold**
+
+This is some text
+and some more text 👀.
\ No newline at end of file
From 68b1859551010fbf806a1f4b40b473cd00d4ba63 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 19:10:34 +0100
Subject: [PATCH 087/202] Improve `Query` package unit tests and coverage
---
tests/Query/ArgumentTest.php | 5 ++--
tests/Query/ArgumentsTest.php | 6 +++--
tests/Query/ExpressionTest.php | 5 ++--
tests/Query/QueryDefaultFunctionsTest.php | 2 +-
tests/Query/QueryTest.php | 14 +++++++++--
tests/Query/SegmentTest.php | 29 +++++++++++++++++++++--
tests/Query/SegmentsTest.php | 6 +++--
7 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/tests/Query/ArgumentTest.php b/tests/Query/ArgumentTest.php
index 9fa03c00a2..5154981a7b 100644
--- a/tests/Query/ArgumentTest.php
+++ b/tests/Query/ArgumentTest.php
@@ -3,11 +3,12 @@
namespace Kirby\Query;
use Closure;
+use Kirby\TestCase;
/**
- * @coversDefaultClass Kirby\Query\Argument
+ * @coversDefaultClass \Kirby\Query\Argument
*/
-class ArgumentTest extends \Kirby\TestCase
+class ArgumentTest extends TestCase
{
/**
* @covers ::__construct
diff --git a/tests/Query/ArgumentsTest.php b/tests/Query/ArgumentsTest.php
index cc97313d75..552a5cefe4 100644
--- a/tests/Query/ArgumentsTest.php
+++ b/tests/Query/ArgumentsTest.php
@@ -2,10 +2,12 @@
namespace Kirby\Query;
+use Kirby\TestCase;
+
/**
- * @coversDefaultClass Kirby\Query\Arguments
+ * @coversDefaultClass \Kirby\Query\Arguments
*/
-class ArgumentsTest extends \Kirby\TestCase
+class ArgumentsTest extends TestCase
{
/**
* @covers ::factory
diff --git a/tests/Query/ExpressionTest.php b/tests/Query/ExpressionTest.php
index 50c67cdcb2..0f9f4b060f 100644
--- a/tests/Query/ExpressionTest.php
+++ b/tests/Query/ExpressionTest.php
@@ -3,11 +3,12 @@
namespace Kirby\Query;
use Kirby\Exception\LogicException;
+use Kirby\TestCase;
/**
- * @coversDefaultClass Kirby\Query\Expression
+ * @coversDefaultClass \Kirby\Query\Expression
*/
-class ExpressionTest extends \Kirby\TestCase
+class ExpressionTest extends TestCase
{
/**
* @covers ::__construct
diff --git a/tests/Query/QueryDefaultFunctionsTest.php b/tests/Query/QueryDefaultFunctionsTest.php
index c8ef63499b..83fe1faee8 100644
--- a/tests/Query/QueryDefaultFunctionsTest.php
+++ b/tests/Query/QueryDefaultFunctionsTest.php
@@ -9,7 +9,7 @@
use Kirby\Toolkit\I18n;
/**
- * @coversDefaultClass Kirby\Query\Query
+ * @coversNothing
*/
class QueryDefaultFunctionsTest extends \Kirby\TestCase
{
diff --git a/tests/Query/QueryTest.php b/tests/Query/QueryTest.php
index aacca07aea..6189291f9b 100644
--- a/tests/Query/QueryTest.php
+++ b/tests/Query/QueryTest.php
@@ -3,11 +3,12 @@
namespace Kirby\Query;
use Closure;
+use Kirby\TestCase;
/**
- * @coversDefaultClass Kirby\Query\Query
+ * @coversDefaultClass \Kirby\Query\Query
*/
-class QueryTest extends \Kirby\TestCase
+class QueryTest extends TestCase
{
/**
* @covers ::__construct
@@ -19,6 +20,15 @@ public function testFactory()
$this->assertSame('user.me', $query->query);
}
+ /**
+ * @covers ::intercept
+ */
+ public function testIntercept()
+ {
+ $query = new Query("kirby");
+ $this->assertSame('foo', $query->intercept('foo'));
+ }
+
/**
* @covers ::resolve
*/
diff --git a/tests/Query/SegmentTest.php b/tests/Query/SegmentTest.php
index bde52eef65..7b928544c6 100644
--- a/tests/Query/SegmentTest.php
+++ b/tests/Query/SegmentTest.php
@@ -2,8 +2,10 @@
namespace Kirby\Query;
+use Kirby\Cms\App;
use Kirby\Exception\BadMethodCallException;
use Kirby\Exception\InvalidArgumentException;
+use Kirby\TestCase;
use stdClass;
class MyObj
@@ -33,9 +35,9 @@ public function __get($name)
}
/**
- * @coversDefaultClass Kirby\Query\Segment
+ * @coversDefaultClass \Kirby\Query\Segment
*/
-class SegmentTest extends \Kirby\TestCase
+class SegmentTest extends TestCase
{
public static function scalarProvider(): array
{
@@ -74,6 +76,7 @@ public function testErrorWithObject()
/**
* @covers ::factory
+ * @covers ::__construct
*/
public function testFactory()
{
@@ -116,6 +119,7 @@ public function testResolveFirstWithDataObject()
$this->assertSame('bar', $segment->resolve(null, $obj));
}
+
/**
* @covers ::resolve
* @covers ::resolveArray
@@ -127,6 +131,17 @@ public function testResolveArray()
$this->assertSame($expected, $segment->resolve($data));
}
+ /**
+ * @covers ::resolve
+ * @covers ::resolveArray
+ */
+ public function testResolveArrayClosure()
+ {
+ $segment = Segment::factory('foo', 0);
+ $data = ['foo' => fn () => 'bar'];
+ $this->assertSame('bar', $segment->resolve(null, $data));
+ }
+
/**
* @covers ::resolve
* @covers ::resolveArray
@@ -153,6 +168,16 @@ public function testResolveArrayArgOnNonClosure()
$segment->resolve(['foo' => 'bar']);
}
+ /**
+ * @covers ::resolve
+ * @covers ::resolveArray
+ */
+ public function testResolveArrayFromGlobalEntry()
+ {
+ $segment = Segment::factory('kirby');
+ $this->assertSame(App::instance(), $segment->resolve(null, []));
+ }
+
/**
* @covers ::resolve
* @covers ::resolveObject
diff --git a/tests/Query/SegmentsTest.php b/tests/Query/SegmentsTest.php
index a9ec1f9e81..dc2d7e3b6e 100644
--- a/tests/Query/SegmentsTest.php
+++ b/tests/Query/SegmentsTest.php
@@ -4,15 +4,17 @@
use Kirby\Exception\BadMethodCallException;
use Kirby\Exception\InvalidArgumentException;
+use Kirby\TestCase;
use stdClass;
/**
- * @coversDefaultClass Kirby\Query\Segments
+ * @coversDefaultClass \Kirby\Query\Segments
*/
-class SegmentsTest extends \Kirby\TestCase
+class SegmentsTest extends TestCase
{
/**
* @covers ::factory
+ * @covers ::__construct
*/
public function testFactory()
{
From c8db40f244f216275f723c4fb990fa6ca3479783 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 19:32:38 +0100
Subject: [PATCH 088/202] Unit tests improvements for `Option` package
---
tests/Option/OptionTest.php | 4 ++++
tests/Option/OptionsQueryTest.php | 11 +++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/tests/Option/OptionTest.php b/tests/Option/OptionTest.php
index e729359132..9b47074abf 100644
--- a/tests/Option/OptionTest.php
+++ b/tests/Option/OptionTest.php
@@ -11,22 +11,26 @@ class OptionTest extends TestCase
{
/**
* @covers ::__construct
+ * @covers ::id
*/
public function testConstruct()
{
// string
$option = new Option('test');
$this->assertSame('test', $option->value);
+ $this->assertSame('test', $option->id());
$this->assertSame('test', $option->text->translations['en']);
// int
$option = new Option(1);
$this->assertSame(1, $option->value);
+ $this->assertSame(1, $option->id());
$this->assertSame(1, $option->text->translations['en']);
// float
$option = new Option(1.1);
$this->assertSame(1.1, $option->value);
+ $this->assertSame(1.1, $option->id());
$this->assertSame(1.1, $option->text->translations['en']);
}
diff --git a/tests/Option/OptionsQueryTest.php b/tests/Option/OptionsQueryTest.php
index f10a78d289..8e40b7b97d 100644
--- a/tests/Option/OptionsQueryTest.php
+++ b/tests/Option/OptionsQueryTest.php
@@ -95,6 +95,7 @@ public function testPolyfill()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForArray()
{
@@ -124,8 +125,8 @@ public function testResolveForArray()
// with non-associative array
$options = (new OptionsQuery(
query: 'page.mySimpleArray',
- value: '{{ arrayItem.value }}',
- text: '{{ arrayItem.value }}',
+ value: '{{ item.value }}',
+ text: '{{ item.value }}',
))->render($model);
$this->assertSame('tag1', $options[0]['value']);
@@ -136,6 +137,7 @@ public function testResolveForArray()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForStructure()
{
@@ -171,6 +173,7 @@ public function testResolveForStructure()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForBlock()
{
@@ -198,6 +201,7 @@ public function testResolveForBlock()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForPages()
{
@@ -226,6 +230,7 @@ public function testResolveForPages()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForFile()
{
@@ -250,6 +255,7 @@ public function testResolveForFile()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForUser()
{
@@ -271,6 +277,7 @@ public function testResolveForUser()
/**
* @covers ::resolve
+ * @covers ::itemToDefaults
*/
public function testResolveForOptions()
{
From 7f8a9248d4fedd20b9c1bb650cb7d82e8965c8b6 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 28 Jan 2024 19:34:48 +0100
Subject: [PATCH 089/202] Fix cs
---
tests/Query/QueryTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Query/QueryTest.php b/tests/Query/QueryTest.php
index 6189291f9b..c51d961f48 100644
--- a/tests/Query/QueryTest.php
+++ b/tests/Query/QueryTest.php
@@ -25,7 +25,7 @@ public function testFactory()
*/
public function testIntercept()
{
- $query = new Query("kirby");
+ $query = new Query('kirby');
$this->assertSame('foo', $query->intercept('foo'));
}
From cb6d91a8d7f1a238fdc79ea514b9d5b7c1da540b Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Tue, 30 Jan 2024 19:55:52 +0100
Subject: [PATCH 090/202] Remove `@coversNothing`
---
tests/Query/QueryDefaultFunctionsTest.php | 3 ---
tests/Text/FileKirbyTagTest.php | 3 ---
tests/Text/ImageKirbyTagTest.php | 3 ---
tests/Text/LinkKirbyTagTest.php | 3 ---
tests/Text/VideoKirbyTagTest.php | 3 ---
5 files changed, 15 deletions(-)
diff --git a/tests/Query/QueryDefaultFunctionsTest.php b/tests/Query/QueryDefaultFunctionsTest.php
index 83fe1faee8..09540d87ae 100644
--- a/tests/Query/QueryDefaultFunctionsTest.php
+++ b/tests/Query/QueryDefaultFunctionsTest.php
@@ -8,9 +8,6 @@
use Kirby\Image\QrCode;
use Kirby\Toolkit\I18n;
-/**
- * @coversNothing
- */
class QueryDefaultFunctionsTest extends \Kirby\TestCase
{
public const TMP = KIRBY_TMP_DIR . '/Query.QueryDefaultFunctions';
diff --git a/tests/Text/FileKirbyTagTest.php b/tests/Text/FileKirbyTagTest.php
index 3054d81bda..ffd00b6084 100644
--- a/tests/Text/FileKirbyTagTest.php
+++ b/tests/Text/FileKirbyTagTest.php
@@ -6,9 +6,6 @@
use Kirby\Filesystem\Dir;
use Kirby\TestCase;
-/**
- * @coversNothing
- */
class FileKirbyTagTest extends TestCase
{
public const TMP = KIRBY_TMP_DIR . '/Text.FileKirbyTag';
diff --git a/tests/Text/ImageKirbyTagTest.php b/tests/Text/ImageKirbyTagTest.php
index e4fbde3270..4de5cc68b6 100644
--- a/tests/Text/ImageKirbyTagTest.php
+++ b/tests/Text/ImageKirbyTagTest.php
@@ -6,9 +6,6 @@
use Kirby\Filesystem\Dir;
use Kirby\TestCase;
-/**
- * @coversNothing
- */
class ImageKirbyTagTest extends TestCase
{
public const TMP = KIRBY_TMP_DIR . '/Text.ImageKirbyTag';
diff --git a/tests/Text/LinkKirbyTagTest.php b/tests/Text/LinkKirbyTagTest.php
index 47a937c070..4c653adb20 100644
--- a/tests/Text/LinkKirbyTagTest.php
+++ b/tests/Text/LinkKirbyTagTest.php
@@ -7,9 +7,6 @@
use Kirby\Filesystem\Dir;
use Kirby\TestCase;
-/**
- * @coversNothing
- */
class LinkKirbyTagTest extends TestCase
{
public const TMP = KIRBY_TMP_DIR . '/Text.LinkKirbyTag';
diff --git a/tests/Text/VideoKirbyTagTest.php b/tests/Text/VideoKirbyTagTest.php
index b83648327d..62eb5f2809 100644
--- a/tests/Text/VideoKirbyTagTest.php
+++ b/tests/Text/VideoKirbyTagTest.php
@@ -6,9 +6,6 @@
use Kirby\Filesystem\Dir;
use Kirby\TestCase;
-/**
- * @coversNothing
- */
class VideoKirbyTagTest extends TestCase
{
public const TMP = KIRBY_TMP_DIR . '/Text.VideoKirbyTag';
From e25270f1f5be2ab4c28db59c38b35f4e7a4f3e97 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Tue, 30 Jan 2024 21:37:55 +0100
Subject: [PATCH 091/202] Add missing tests for `Component::applyProps()`
---
tests/Toolkit/ComponentTest.php | 40 +++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tests/Toolkit/ComponentTest.php b/tests/Toolkit/ComponentTest.php
index 565382a45e..a4e78017d7 100644
--- a/tests/Toolkit/ComponentTest.php
+++ b/tests/Toolkit/ComponentTest.php
@@ -2,8 +2,10 @@
namespace Kirby\Toolkit;
+use ArgumentCountError;
use Kirby\Exception\Exception;
use Kirby\Exception\InvalidArgumentException;
+use TypeError;
/**
* @coversDefaultClass \Kirby\Toolkit\Component
@@ -75,6 +77,44 @@ public function testPropWithFixedValue()
$this->assertSame('test', $component->prop);
}
+ /**
+ * @covers ::applyProps
+ */
+ public function testPropWithInvalidValue()
+ {
+ Component::$types = [
+ 'test' => [
+ 'props' => [
+ 'prop' => fn (string $prop) => $prop
+ ]
+ ]
+ ];
+
+ $this->expectException(TypeError::class);
+ $this->expectExceptionMessage('Invalid value for "prop"');
+
+ new Component('test', ['prop' => [1, 2, 3]]);
+ }
+
+ /**
+ * @covers ::applyProps
+ */
+ public function testPropWithMissingValue()
+ {
+ Component::$types = [
+ 'test' => [
+ 'props' => [
+ 'prop' => fn (string $prop) => $prop
+ ]
+ ]
+ ];
+
+ $this->expectException(ArgumentCountError::class);
+ $this->expectExceptionMessage('Please provide a value for "prop"');
+
+ new Component('test');
+ }
+
/**
* @covers ::__construct
*/
From 1fb7ab2fb36dd7a39d6bffabff1b84133057745b Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Tue, 30 Jan 2024 21:46:02 +0100
Subject: [PATCH 092/202] Add missing tests for KirbyTags
---
tests/Text/DateKirbyTagTest.php | 16 ++++++++++++++++
tests/Text/EmailKirbyTagTest.php | 21 +++++++++++++++++++++
2 files changed, 37 insertions(+)
create mode 100644 tests/Text/DateKirbyTagTest.php
create mode 100644 tests/Text/EmailKirbyTagTest.php
diff --git a/tests/Text/DateKirbyTagTest.php b/tests/Text/DateKirbyTagTest.php
new file mode 100644
index 0000000000..5985c0453f
--- /dev/null
+++ b/tests/Text/DateKirbyTagTest.php
@@ -0,0 +1,16 @@
+assertSame(date('d.m.Y'), $app->kirbytags('(date: d.m.Y)'));
+ $this->assertSame(date('Y'), $app->kirbytags('(date: year)'));
+ }
+}
diff --git a/tests/Text/EmailKirbyTagTest.php b/tests/Text/EmailKirbyTagTest.php
new file mode 100644
index 0000000000..82885fd02a
--- /dev/null
+++ b/tests/Text/EmailKirbyTagTest.php
@@ -0,0 +1,21 @@
+kirbytags('(email: mail@company.com?subject=Test class: email)');
+ $expected = '!^(.*?) $!';
+ $this->assertMatchesRegularExpression($expected, $html);
+ preg_match($expected, $html, $matches);
+ $this->assertSame('mail@company.com?subject=Test', Html::decode($matches[1]));
+ $this->assertSame('mail@company.com', Html::decode($matches[2]));
+ }
+}
From c482ccfaf158ac4c155cb3b8dcfec6e2b3f77957 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 19 Feb 2024 13:14:15 +0100
Subject: [PATCH 093/202] Improve styling with k-code and grids
---
panel/lab/internals/helpers/array/index.vue | 139 ++++++++++++++------
1 file changed, 100 insertions(+), 39 deletions(-)
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
index b7076958dd..9274b0e12a 100644
--- a/panel/lab/internals/helpers/array/index.vue
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -11,13 +11,21 @@
Creates an array from an object:
this.$helpers.array.fromObject(object)
-
- Input: {{ fromObjectInput }}
-
- Result: {{ $helper.array.fromObject(fromObjectInput) }}
-
-
+
+
+
+ Input
+ {{ fromObjectInput }}
+
+
+ Result
+ {{
+ $helper.array.fromObject(fromObjectInput)
+ }}
+
+
+
@@ -29,22 +37,27 @@
field: "name" })
-
- {{ searchInput }}
-
- {{ searchResult }}
-
+
+
+
+
+
+
+
+ Input
+ {{ searchInput }}
+
+
+ Result
+ {{ searchResult }}
+
+
+
@@ -53,13 +66,21 @@
Sorts an array by one or more fields and directions:
this.$helpers.array.sortBy(array, "name desc")
-
- {{ searchInput }}
- {{
- $helper.array.sortBy(searchInput, "name desc")
- }}
-
+
+
+
+ Input
+ {{ searchInput }}
+
+
+ Result
+ {{
+ $helper.array.sortBy(searchInput, "name desc")
+ }}
+
+
+
@@ -68,11 +89,21 @@
Splits an array into groups by a delimiter entry:
this.$helpers.array.split(array, "-")
-
- {{ splitInput }}
- {{ $helper.array.split(splitInput, "-") }}
-
+
+
+
+ Input
+ {{ splitInput }}
+
+
+ Result
+ {{
+ $helper.array.split(splitInput, "-")
+ }}
+
+
+
@@ -81,14 +112,29 @@
Wraps a value in an array (ensures the value will be an array):
this.$helpers.array.wrap(value)
- "aaa", ["aaa"]
-
-
- {{ $helper.array.wrap("aaa") }},
- {{ $helper.array.wrap(["aaa"]) }}
-
-
+
+
+
+ Input
+ "aaa"
+
+
+ Result
+ {{ $helper.array.wrap("aaa") }}
+
+
+ Input
+ {{ ["aaa"] }}
+
+
+ Result
+ {{
+ $helper.array.wrap(["aaa"])
+ }}
+
+
+
@@ -97,7 +143,6 @@
export default {
data() {
return {
- searchResult: null,
searchQuery: ""
};
},
@@ -112,6 +157,12 @@ export default {
{ id: 3, name: "Jane Doe" }
];
},
+ searchResult() {
+ return this.$helper.array.search(this.searchInput, this.searchQuery, {
+ min: 0,
+ field: "name"
+ });
+ },
splitInput() {
return [
{ id: 1, name: "John Doe" },
@@ -123,3 +174,13 @@ export default {
}
};
+
+
From f44b276135a0a77571742c474e1060446083d629 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Mon, 19 Feb 2024 14:46:43 +0100
Subject: [PATCH 094/202] Parse individual script blocks and show them in the
code view
---
panel/lab/internals/helpers/array/index.vue | 56 +++++++++++++++++----
src/Panel/Lab/Example.php | 38 +++++++++++---
2 files changed, 77 insertions(+), 17 deletions(-)
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
index 9274b0e12a..8ecf4bde43 100644
--- a/panel/lab/internals/helpers/array/index.vue
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -5,7 +5,7 @@
this.$helpers.array
-
+
Creates an array from an object:
@@ -28,7 +28,7 @@
-
+
Filters an array by a provided query:
@@ -60,7 +60,7 @@
-
+
Sorts an array by one or more fields and directions:
@@ -71,19 +71,19 @@
Input
- {{ searchInput }}
+ {{ sortInput }}
Result
{{
- $helper.array.sortBy(searchInput, "name desc")
+ $helper.array.sortBy(sortInput, "name desc")
}}
-
+
Splits an array into groups by a delimiter entry:
@@ -140,16 +140,24 @@
diff --git a/panel/lab/internals/library.dayjs/3_interpret/index.vue b/panel/lab/internals/library.dayjs/3_interpret/index.vue
index 68532cd1f4..6d8eefb993 100644
--- a/panel/lab/internals/library.dayjs/3_interpret/index.vue
+++ b/panel/lab/internals/library.dayjs/3_interpret/index.vue
@@ -8,41 +8,39 @@
- this.$library.dayjs.interpret("23-09-12", "date"): dayjs|null
+ this.$library.dayjs.interpret("23-09-12", "date"): dayjs|null
-
-
-
-
→
-
-
{{ date ?? "-" }}
-
+
+
+
+
+
+ {{ date ?? "-" }}
+
+
- this.$library.dayjs.interpret("9:12", "time"): dayjs|null
-
-
-
+
this.$library.dayjs.interpret("9:12", "time"): dayjs|null
-
→
-
-
{{ time ?? "-" }}
-
+
+
+
+
+
+ {{ time ?? "-" }}
+
+
@@ -66,13 +64,7 @@ export default {
diff --git a/panel/lab/internals/library.dayjs/4_iso/index.vue b/panel/lab/internals/library.dayjs/4_iso/index.vue
index 8808380b39..816951417e 100644
--- a/panel/lab/internals/library.dayjs/4_iso/index.vue
+++ b/panel/lab/internals/library.dayjs/4_iso/index.vue
@@ -9,123 +9,115 @@
- this.$library.dayjs.iso("2023-09-12", "date"): dayjs
+ this.$library.dayjs.iso("2023-09-12", "date"): dayjs
-
-
-
-
-
-
→
-
-
{{ string ?? "-" }}
-
-
-
-
- myDayjsObject.toIso("date"): string
-
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+ {{ string ?? "-" }}
+
+
+
-
→
+
+ myDayjsObject.toIso("date"): string
- {{ iso ?? "-" }}
-
+
+
+
+
+
+
+
+
+
+ {{ iso ?? "-" }}
From c54717ee014cc430698c996a94a906fbe9766720 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 22 Feb 2024 19:17:56 +0100
Subject: [PATCH 097/202] Lab: tweak helper.array docs
---
panel/lab/internals/helpers/array/index.vue | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
index 8ecf4bde43..0db13ebc02 100644
--- a/panel/lab/internals/helpers/array/index.vue
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -1,9 +1,11 @@
-
- Access the following array helpers in your Vue components through
- this.$helpers.array
-
+
+
+ Access the following array helpers in your Vue components through
+ this.$helpers.array
+
+
From 5499d80fe71aef5c984186315c5f05e0821adba3 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 17 Feb 2024 14:53:17 +0100
Subject: [PATCH 098/202] Frist lab examples for `$helpers.string.` methods
---
panel/lab/internals/helpers/array/index.vue | 12 +-
panel/lab/internals/helpers/string/index.vue | 549 +++++++++++++++++++
panel/src/components/Lab/PlaygroundView.vue | 9 +
panel/src/helpers/string.js | 4 +-
4 files changed, 561 insertions(+), 13 deletions(-)
create mode 100644 panel/lab/internals/helpers/string/index.vue
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
index 0db13ebc02..9d18a498d5 100644
--- a/panel/lab/internals/helpers/array/index.vue
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -1,5 +1,5 @@
-
+
Access the following array helpers in your Vue components through
@@ -210,13 +210,3 @@ export default {
mixins: [fromObject, search, sortBy, split]
};
-
-
diff --git a/panel/lab/internals/helpers/string/index.vue b/panel/lab/internals/helpers/string/index.vue
new file mode 100644
index 0000000000..523a3e940f
--- /dev/null
+++ b/panel/lab/internals/helpers/string/index.vue
@@ -0,0 +1,549 @@
+
+
+
+ Access the following string helpers in your Vue components through
+ this.$helpers.string
+
+
+
+
+
+ Converts camel-case to kebab-case:
+ this.$helpers.string.camelToKebab(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.camelToKebab(camelCase)
+ }}
+
+
+
+
+
+
+
+
+ Escapes HTML in string:
+ this.$helpers.string.escapeHTML(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.escapeHTML(html)
+ }}
+
+
+
+
+
+
+
+
+ Checks if string contains an emoji:
+ this.$helpers.string.hasEmoji(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.string.hasEmoji(emoji) }}
+
+
+
+
+
+
+
+
+ Checks if a string is empty:
+ this.$helpers.string.isEmpty(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.string.isEmpty(empty) }}
+
+
+
+
+
+
+
+
+ Turns first letter lowercase:
+ this.$helpers.string.lcfirst(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.string.lcfirst(lcfirst) }}
+
+
+
+
+
+
+
+
+ Trims the given character(s) at the beginning of the string:
+ this.$helpers.string.ltrim(string, replace)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.string.ltrim(ltrim, '*') }}
+
+
+
+
+
+
+
+
+ Prefixes string with 0 until length is reached:
+ this.$helpers.string.pad(string, length)
+
+
+
+
+
+ Input
+
+
+
+ How many digits?
+
+
+
+ Result
+ {{
+ $helper.string.pad(padString, padCount)
+ }}
+
+
+
+
+
+
+
+
+ Generate random alpha-num string of specified length:
+ this.$helpers.string.random(length)
+
+
+
+
+
+ Length
+
+
+
+ Result
+ {{ random }}
+
+
+
+
+
+
+
+
+ Trims the given character(s) at the end of the string:
+ this.$helpers.string.rtrim(string, replace)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.string.rtrim(rtrim, '*') }}
+
+
+
+
+
+
+
+
+ Convert string to ASCII slug:
+ this.$helpers.string.slug(string, rules, allowed, separator)
+
+
+
+
+
+ rules
(array): Array of custom rules for replacing characters, e.g. [{ "ä": "ae" }]
+
+
+ allowed
(string): Allowed characters, default is a-z0-9
+
+
+ separator
(string): Separator for the slug, default is -
+
+
+
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.slug(slug, [{'ä': 'ae' }])
+ }}
+
+
+
+
+
+
+
+
+ Removes HTML from a string:
+ this.$helpers.string.stripHTML(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.stripHTML(html)
+ }}
+
+
+
+
+
+
+
+
+ Turns first letter uppercase:
+ this.$helpers.string.ucfirst(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.ucfirst(ucfirst)
+ }}
+
+
+
+
+
+
+
+
+ Turns first letter of each word uppercase:
+ this.$helpers.string.ucwords(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.ucwords(ucwords)
+ }}
+
+
+
+
+
+
+
+
+ Turns escaped HTML entities into actual characters again:
+ this.$helpers.string.unescapeHTML(string)
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.string.unescapeHTML(unhtml)
+ }}
+
+
+
+
+
+
+
+
+
diff --git a/panel/src/components/Lab/PlaygroundView.vue b/panel/src/components/Lab/PlaygroundView.vue
index 913377d26c..fc2a849b13 100644
--- a/panel/src/components/Lab/PlaygroundView.vue
+++ b/panel/src/components/Lab/PlaygroundView.vue
@@ -141,4 +141,13 @@ export default {
.k-lab-input-examples-focus .k-lab-example-canvas > .k-button {
margin-top: var(--spacing-6);
}
+
+.k-lab-helpers-examples .k-lab-example .k-text {
+ margin-bottom: var(--spacing-6);
+}
+
+.k-lab-helpers-examples h2 {
+ margin-bottom: var(--spacing-3);
+ font-weight: var(--font-bold);
+}
diff --git a/panel/src/helpers/string.js b/panel/src/helpers/string.js
index 86e6717c94..7891c9cd8d 100644
--- a/panel/src/helpers/string.js
+++ b/panel/src/helpers/string.js
@@ -107,7 +107,7 @@ export function lcfirst(string) {
* @returns {string}
*/
export function ltrim(string = "", replace = "") {
- const expression = new RegExp(`^(${replace})+`, "g");
+ const expression = new RegExp(`^(${RegExp.escape(replace)})+`, "g");
return string.replace(expression, "");
}
@@ -153,7 +153,7 @@ export function random(length) {
* @returns {string}
*/
export function rtrim(string = "", replace = "") {
- const expression = new RegExp(`(${replace})+$`, "g");
+ const expression = new RegExp(`(${RegExp.escape(replace)})+$`, "g");
return string.replace(expression, "");
}
From c9c4db72b55fdd1154a7760db3510a95c6c2bf45 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 22 Feb 2024 18:16:31 +0100
Subject: [PATCH 099/202] Lab docs for remaining string helpers
---
panel/lab/internals/helpers/string/index.vue | 89 +++++++++++++++++---
panel/src/helpers/string.js | 3 +-
2 files changed, 77 insertions(+), 15 deletions(-)
diff --git a/panel/lab/internals/helpers/string/index.vue b/panel/lab/internals/helpers/string/index.vue
index 523a3e940f..12a639354a 100644
--- a/panel/lab/internals/helpers/string/index.vue
+++ b/panel/lab/internals/helpers/string/index.vue
@@ -251,19 +251,17 @@
this.$helpers.string.slug(string, rules, allowed, separator)
-
-
-
- rules
(array): Array of custom rules for replacing characters, e.g. [{ "ä": "ae" }]
-
-
- allowed
(string): Allowed characters, default is a-z0-9
-
-
- separator
(string): Separator for the slug, default is -
-
-
-
+
+
+ rules
(array): Array of custom rules for replacing characters, e.g. [{ "ä": "ae" }]
+
+
+ allowed
(string): Allowed characters, default is a-z0-9
+
+
+ separator
(string): Separator for the slug, default is -
+
+
@@ -340,6 +338,37 @@
+
+
+
+ Replaces template placeholders in string with provided values:
+ this.$helpers.string.template(string, values)
+
+
+
+
+
+ Input
+
+
+ {{
+ templateValues
+ }}
+
+
+ Result
+ {{
+ $helper.string.template(template, templateValues)
+ }}
+
+
+
+
+
@@ -394,6 +423,20 @@
+
+
+
+ Returns a unique ID:
+ this.$helpers.string.uuid()
+
+
+
+ {{
+ $helper.string.uuid()
+ }}
+
+
+
@@ -499,6 +542,25 @@ export const slug = {
};
/** @script-end */
+/** @script: template */
+export const template = {
+ data() {
+ return {
+ template: "This is { foo } and {{ baz }}",
+ }
+ },
+ computed: {
+ templateValues() {
+ return {
+ "foo": "bar",
+ "baz": "qux"
+ }
+ }
+
+ }
+};
+/** @script-end */
+
/** @script: ucfirst */
export const ucfirst = {
data() {
@@ -541,6 +603,7 @@ export default {
random,
rtrim,
slug,
+ template,
ucfirst,
ucwords,
unhtml
diff --git a/panel/src/helpers/string.js b/panel/src/helpers/string.js
index 7891c9cd8d..89ab4b136e 100644
--- a/panel/src/helpers/string.js
+++ b/panel/src/helpers/string.js
@@ -221,8 +221,7 @@ export function stripHTML(string) {
}
/**
- * Replaces template placeholders in string
- * with provided values
+ * Replaces template placeholders in string with provided values
* @param {string} string
* @param {Object} values
* @returns {string}
From 931fd1ceb7768373e06deac91ad10ab252c72512 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 22 Feb 2024 18:20:54 +0100
Subject: [PATCH 100/202] Lab: placeholders for missing helpers
---
panel/lab/internals/helpers/color/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/debounce/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/embed/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/field/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/file/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/focus/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/isComponent/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/isUploadEvent/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/keyboard/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/link/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/object/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/page/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/queue/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/ratio/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/regex/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/sort/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/upload/index.vue | 13 +++++++++++++
panel/lab/internals/helpers/url/index.vue | 13 +++++++++++++
18 files changed, 234 insertions(+)
create mode 100644 panel/lab/internals/helpers/color/index.vue
create mode 100644 panel/lab/internals/helpers/debounce/index.vue
create mode 100644 panel/lab/internals/helpers/embed/index.vue
create mode 100644 panel/lab/internals/helpers/field/index.vue
create mode 100644 panel/lab/internals/helpers/file/index.vue
create mode 100644 panel/lab/internals/helpers/focus/index.vue
create mode 100644 panel/lab/internals/helpers/isComponent/index.vue
create mode 100644 panel/lab/internals/helpers/isUploadEvent/index.vue
create mode 100644 panel/lab/internals/helpers/keyboard/index.vue
create mode 100644 panel/lab/internals/helpers/link/index.vue
create mode 100644 panel/lab/internals/helpers/object/index.vue
create mode 100644 panel/lab/internals/helpers/page/index.vue
create mode 100644 panel/lab/internals/helpers/queue/index.vue
create mode 100644 panel/lab/internals/helpers/ratio/index.vue
create mode 100644 panel/lab/internals/helpers/regex/index.vue
create mode 100644 panel/lab/internals/helpers/sort/index.vue
create mode 100644 panel/lab/internals/helpers/upload/index.vue
create mode 100644 panel/lab/internals/helpers/url/index.vue
diff --git a/panel/lab/internals/helpers/color/index.vue b/panel/lab/internals/helpers/color/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/color/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/debounce/index.vue b/panel/lab/internals/helpers/debounce/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/debounce/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/embed/index.vue b/panel/lab/internals/helpers/embed/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/embed/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/field/index.vue b/panel/lab/internals/helpers/field/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/field/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/file/index.vue b/panel/lab/internals/helpers/file/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/file/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/focus/index.vue b/panel/lab/internals/helpers/focus/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/focus/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/isComponent/index.vue b/panel/lab/internals/helpers/isComponent/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/isComponent/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/isUploadEvent/index.vue b/panel/lab/internals/helpers/isUploadEvent/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/isUploadEvent/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/keyboard/index.vue b/panel/lab/internals/helpers/keyboard/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/keyboard/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/link/index.vue b/panel/lab/internals/helpers/link/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/link/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/object/index.vue b/panel/lab/internals/helpers/object/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/object/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/page/index.vue b/panel/lab/internals/helpers/page/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/page/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/queue/index.vue b/panel/lab/internals/helpers/queue/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/queue/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/ratio/index.vue b/panel/lab/internals/helpers/ratio/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/ratio/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/regex/index.vue b/panel/lab/internals/helpers/regex/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/regex/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/sort/index.vue b/panel/lab/internals/helpers/sort/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/sort/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/upload/index.vue b/panel/lab/internals/helpers/upload/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/upload/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/url/index.vue b/panel/lab/internals/helpers/url/index.vue
new file mode 100644
index 0000000000..8fb2c60a13
--- /dev/null
+++ b/panel/lab/internals/helpers/url/index.vue
@@ -0,0 +1,13 @@
+
+
+
+ These docs are still work in progress and will be added soon
+
+
+
+
+
From cf3e91bc10c7bcb152f6fe579d66c1894a97bdc0 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 22 Feb 2024 18:31:45 +0100
Subject: [PATCH 101/202] Fix `$helper` name
---
panel/lab/internals/helpers/array/index.vue | 22 +++----
panel/lab/internals/helpers/string/index.vue | 66 ++++++++++----------
2 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
index 9d18a498d5..6678c238bd 100644
--- a/panel/lab/internals/helpers/array/index.vue
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -3,15 +3,15 @@
Access the following array helpers in your Vue components through
- this.$helpers.array
+ this.$helper.array
-
+
Creates an array from an object:
- this.$helpers.array.fromObject(object)
+ this.$helper.array.fromObject(object)
@@ -30,12 +30,12 @@
-
+
Filters an array by a provided query:
- this.$helpers.array.search(array, "{{ searchQuery }}", { min: 2,
+ this.$helper.array.search(array, "{{ searchQuery }}", { min: 2,
field: "name" })
@@ -62,11 +62,11 @@
-
+
Sorts an array by one or more fields and directions:
- this.$helpers.array.sortBy(array, "name desc")
+ this.$helper.array.sortBy(array, "name desc")
@@ -85,11 +85,11 @@
-
+
Splits an array into groups by a delimiter entry:
- this.$helpers.array.split(array, "-")
+ this.$helper.array.split(array, "-")
@@ -108,11 +108,11 @@
-
+
Wraps a value in an array (ensures the value will be an array):
- this.$helpers.array.wrap(value)
+ this.$helper.array.wrap(value)
diff --git a/panel/lab/internals/helpers/string/index.vue b/panel/lab/internals/helpers/string/index.vue
index 12a639354a..0027dc37ef 100644
--- a/panel/lab/internals/helpers/string/index.vue
+++ b/panel/lab/internals/helpers/string/index.vue
@@ -2,14 +2,14 @@
Access the following string helpers in your Vue components through
- this.$helpers.string
+ this.$helper.string
-
+
Converts camel-case to kebab-case:
- this.$helpers.string.camelToKebab(string)
+ this.$helper.string.camelToKebab(string)
@@ -32,11 +32,11 @@
-
+
Escapes HTML in string:
- this.$helpers.string.escapeHTML(string)
+ this.$helper.string.escapeHTML(string)
@@ -59,11 +59,11 @@
-
+
Checks if string contains an emoji:
- this.$helpers.string.hasEmoji(string)
+ this.$helper.string.hasEmoji(string)
@@ -84,11 +84,11 @@
-
+
Checks if a string is empty:
- this.$helpers.string.isEmpty(string)
+ this.$helper.string.isEmpty(string)
@@ -109,11 +109,11 @@
-
+
Turns first letter lowercase:
- this.$helpers.string.lcfirst(string)
+ this.$helper.string.lcfirst(string)
@@ -134,11 +134,11 @@
-
+
Trims the given character(s) at the beginning of the string:
- this.$helpers.string.ltrim(string, replace)
+ this.$helper.string.ltrim(string, replace)
@@ -159,11 +159,11 @@
-
+
Prefixes string with 0 until length is reached:
- this.$helpers.string.pad(string, length)
+ this.$helper.string.pad(string, length)
@@ -194,11 +194,11 @@
-
+
Generate random alpha-num string of specified length:
- this.$helpers.string.random(length)
+ this.$helper.string.random(length)
@@ -219,11 +219,11 @@
-
+
Trims the given character(s) at the end of the string:
- this.$helpers.string.rtrim(string, replace)
+ this.$helper.string.rtrim(string, replace)
@@ -244,11 +244,11 @@
-
+
Convert string to ASCII slug:
- this.$helpers.string.slug(string, rules, allowed, separator)
+ this.$helper.string.slug(string, rules, allowed, separator)
-
+
Removes HTML from a string:
- this.$helpers.string.stripHTML(string)
+ this.$helper.string.stripHTML(string)
@@ -311,11 +311,11 @@
-
+
Turns first letter uppercase:
- this.$helpers.string.ucfirst(string)
+ this.$helper.string.ucfirst(string)
@@ -338,11 +338,11 @@
-
+
Replaces template placeholders in string with provided values:
- this.$helpers.string.template(string, values)
+ this.$helper.string.template(string, values)
@@ -369,11 +369,11 @@
-
+
Turns first letter of each word uppercase:
- this.$helpers.string.ucwords(string)
+ this.$helper.string.ucwords(string)
@@ -396,11 +396,11 @@
-
+
Turns escaped HTML entities into actual characters again:
- this.$helpers.string.unescapeHTML(string)
+ this.$helper.string.unescapeHTML(string)
@@ -423,11 +423,11 @@
-
+
Returns a unique ID:
- this.$helpers.string.uuid()
+ this.$helper.string.uuid()
From c4d3c44d387a0cff6f21fdfb472f4026818573aa Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 22 Feb 2024 19:18:39 +0100
Subject: [PATCH 102/202] Tweak helper.string docs
---
panel/lab/internals/helpers/string/index.vue | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/panel/lab/internals/helpers/string/index.vue b/panel/lab/internals/helpers/string/index.vue
index 0027dc37ef..66af00001b 100644
--- a/panel/lab/internals/helpers/string/index.vue
+++ b/panel/lab/internals/helpers/string/index.vue
@@ -1,9 +1,11 @@
-
- Access the following string helpers in your Vue components through
- this.$helper.string
-
+
+
+ Access the following string helpers in your Vue components through
+ this.$helper.string
+
+
From 4d94f7cb86cbf5d5a09befbf25e23293e9f5cd1b Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Fri, 23 Feb 2024 18:11:58 +0100
Subject: [PATCH 103/202] Lab: fix wrapping examples without script
---
src/Panel/Lab/Example.php | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/Panel/Lab/Example.php b/src/Panel/Lab/Example.php
index 9f30bd7a59..7e48ed51c7 100644
--- a/src/Panel/Lab/Example.php
+++ b/src/Panel/Lab/Example.php
@@ -255,13 +255,23 @@ public function vueExamples(string|null $template, string|null $script): array
if (preg_match_all('/^(\t*)\S/m', $code, $indents)) {
// get minimum indent
$indents = array_map(fn ($i) => strlen($i), $indents[1]);
- $indents = min($indents) - 1;
+ $indents = min($indents);
+
+ if (empty($js) === false) {
+ $indents--;
+ }
// strip minimum indent from each line
$code = preg_replace('/^\t{' . $indents . '}/m', '', $code);
}
- $examples[$name] = '' . PHP_EOL . "\t" . trim($code) . PHP_EOL . ' ' . $js;
+ $code = trim($code);
+
+ if (empty($js) === false) {
+ $code = '' . PHP_EOL . "\t" . $code . PHP_EOL . ' ';
+ }
+
+ $examples[$name] = $code . $js;
}
}
From 10b2173453f7c4067d54ad9748c4919437a44512 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nico=20Hoffmann=20=20=E0=B7=B4?=
Date: Fri, 23 Feb 2024 21:47:06 +0100
Subject: [PATCH 104/202] Update src/Filesystem/Dir.php
Co-authored-by: Lukas Bestle
---
src/Filesystem/Dir.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index d83df1edcf..7f93ed13ec 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -341,7 +341,7 @@ protected static function inventoryChild(
/**
* Determines the main template for the inventory
- * from all collected content files, ignory file meta files
+ * from all collected content files, ignore file meta files
*/
protected static function inventoryTemplate(
array $content,
From 0f315488377e28611250211c97859ddc4fa70002 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Fri, 23 Feb 2024 21:50:57 +0100
Subject: [PATCH 105/202] `Dir::inventoryChild()`: use `is_file()`
---
src/Filesystem/Dir.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Filesystem/Dir.php b/src/Filesystem/Dir.php
index 7f93ed13ec..680789bddf 100644
--- a/src/Filesystem/Dir.php
+++ b/src/Filesystem/Dir.php
@@ -323,7 +323,7 @@ protected static function inventoryChild(
// look if a content file can be found
// for any of the available models
foreach (Page::$models as $modelName => $modelClass) {
- if (file_exists($root . '/' . $modelName . '.' . $contentExtension) === true) {
+ if (is_file($root . '/' . $modelName . '.' . $contentExtension) === true) {
$model = $modelName;
break;
}
From d6c8f238bed24771ce8dbbb6d12cba369ee2e34a Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 21 Jan 2024 19:43:00 +0100
Subject: [PATCH 106/202] Clean up `Cms\Blueprint` class
---
src/Cms/Blueprint.php | 83 ++++++++++++++++++++++++-------------------
1 file changed, 46 insertions(+), 37 deletions(-)
diff --git a/src/Cms/Blueprint.php b/src/Cms/Blueprint.php
index c20d7edcf6..7ef2e2c971 100644
--- a/src/Cms/Blueprint.php
+++ b/src/Cms/Blueprint.php
@@ -297,24 +297,20 @@ public static function extend($props): array
];
}
- $extends = $props['extends'] ?? null;
-
- if ($extends === null) {
- return $props;
- }
-
- foreach (A::wrap($extends) as $extend) {
- try {
- $mixin = static::find($extend);
- $mixin = static::extend($mixin);
- $props = A::merge($mixin, $props, A::MERGE_REPLACE);
- } catch (Exception) {
- // keep the props unextended if the snippet wasn't found
+ if ($extends = $props['extends'] ?? null) {
+ foreach (A::wrap($extends) as $extend) {
+ try {
+ $mixin = static::find($extend);
+ $mixin = static::extend($mixin);
+ $props = A::merge($mixin, $props, A::MERGE_REPLACE);
+ } catch (Exception) {
+ // keep the props unextended if the snippet wasn't found
+ }
}
- }
- // remove the extends flag
- unset($props['extends']);
+ // remove the extends flag
+ unset($props['extends']);
+ }
return $props;
}
@@ -391,6 +387,7 @@ public static function find(string $name): array
if (is_string($file) === true && F::exists($file) === true) {
return static::$loaded[$name] = Data::read($file);
}
+
if (is_array($file) === true) {
return static::$loaded[$name] = $file;
}
@@ -465,7 +462,10 @@ protected function normalizeColumns(string $tabName, array $columns): array
continue;
}
- $columnProps = $this->convertFieldsToSections($tabName . '-col-' . $columnKey, $columnProps);
+ $columnProps = $this->convertFieldsToSections(
+ $tabName . '-col-' . $columnKey,
+ $columnProps
+ );
// inject getting started info, if the sections are empty
if (empty($columnProps['sections']) === true) {
@@ -478,10 +478,14 @@ protected function normalizeColumns(string $tabName, array $columns): array
];
}
- $columns[$columnKey] = array_merge($columnProps, [
+ $columns[$columnKey] = [
+ ...$columnProps,
'width' => $columnProps['width'] ?? '1/1',
- 'sections' => $this->normalizeSections($tabName, $columnProps['sections'] ?? [])
- ]);
+ 'sections' => $this->normalizeSections(
+ $tabName,
+ $columnProps['sections'] ?? []
+ )
+ ];
}
return $columns;
@@ -501,10 +505,9 @@ public static function helpList(array $items): string
/**
* Normalize field props for a single field
*
- * @param array|string $props
* @throws \Kirby\Exception\InvalidArgumentException If the filed name is missing or the field type is invalid
*/
- public static function fieldProps($props): array
+ public static function fieldProps(array|string $props): array
{
$props = static::extend($props);
@@ -543,12 +546,13 @@ public static function fieldProps($props): array
}
// add some useful defaults
- return array_merge($props, [
+ return [
+ ...$props,
'label' => $props['label'] ?? ucfirst($name),
'name' => $name,
'type' => $type,
'width' => $props['width'] ?? '1/1',
- ]);
+ ];
}
/**
@@ -607,11 +611,16 @@ public static function fieldsProps($fields): array
// resolve field groups
if ($fieldProps['type'] === 'group') {
- if (empty($fieldProps['fields']) === false && is_array($fieldProps['fields']) === true) {
+ if (
+ empty($fieldProps['fields']) === false &&
+ is_array($fieldProps['fields']) === true
+ ) {
$index = array_search($fieldName, array_keys($fields));
- $before = array_slice($fields, 0, $index);
- $after = array_slice($fields, $index + 1);
- $fields = array_merge($before, $fieldProps['fields'] ?? [], $after);
+ $fields = [
+ ...array_slice($fields, 0, $index),
+ ...$fieldProps['fields'] ?? [],
+ ...array_slice($fields, $index + 1)
+ ];
} else {
unset($fields[$fieldName]);
}
@@ -626,11 +635,9 @@ public static function fieldsProps($fields): array
/**
* Normalizes blueprint options. This must be used in the
* constructor of an extended class, if you want to make use of it.
- *
- * @param array|true|false|null|string $options
*/
protected function normalizeOptions(
- $options,
+ array|string|bool|null $options,
array $defaults,
array $aliases = []
): array {
@@ -656,7 +663,7 @@ protected function normalizeOptions(
}
}
- return array_merge($defaults, $options);
+ return [...$defaults, ...$options];
}
/**
@@ -681,10 +688,11 @@ protected function normalizeSections(
// inject all section extensions
$sectionProps = $this->extend($sectionProps);
- $sections[$sectionName] = $sectionProps = array_merge($sectionProps, [
+ $sections[$sectionName] = $sectionProps = [
+ ...$sectionProps,
'name' => $sectionName,
'type' => $type = $sectionProps['type'] ?? $sectionName
- ]);
+ ];
if (empty($type) === true || is_string($type) === false) {
$sections[$sectionName] = [
@@ -734,7 +742,7 @@ protected function normalizeSections(
}
// store all normalized sections
- $this->sections = array_merge($this->sections, $sections);
+ $this->sections = [...$this->sections, ...$sections];
return $sections;
}
@@ -764,13 +772,14 @@ protected function normalizeTabs($tabs): array
$tabProps = $this->convertFieldsToSections($tabName, $tabProps);
$tabProps = $this->convertSectionsToColumns($tabName, $tabProps);
- $tabs[$tabName] = array_merge($tabProps, [
+ $tabs[$tabName] = [
+ ...$tabProps,
'columns' => $this->normalizeColumns($tabName, $tabProps['columns'] ?? []),
'icon' => $tabProps['icon'] ?? null,
'label' => $this->i18n($tabProps['label'] ?? ucfirst($tabName)),
'link' => $this->model->panel()->url(true) . '/?tab=' . $tabName,
'name' => $tabName,
- ]);
+ ];
}
return $this->tabs = $tabs;
From cd0f3b60da66feb6e988880738fa0767ba213888 Mon Sep 17 00:00:00 2001
From: Lukas Bestle
Date: Fri, 23 Feb 2024 22:12:13 +0100
Subject: [PATCH 107/202] Coding style
---
src/Cms/System/UpdateStatus.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Cms/System/UpdateStatus.php b/src/Cms/System/UpdateStatus.php
index 557d09a9bd..b9e80e3d84 100644
--- a/src/Cms/System/UpdateStatus.php
+++ b/src/Cms/System/UpdateStatus.php
@@ -158,9 +158,9 @@ public function messages(): array|null
// collect all matching custom messages
$filters = [
'kirby' => $this->app->version(),
- // Some PHP version strings contain extra info that makes them
- // invalid so we need to strip it off.
- 'php' => preg_replace('#^([^~+-]+).*$#', '$1', phpversion())
+ // some PHP version strings contain extra info that makes them
+ // invalid so we need to strip it off
+ 'php' => preg_replace('/^([^~+-]+).*$/', '$1', phpversion())
];
if ($type === 'plugin') {
From 35904a77846cdf6a6fd425ae7409771c1ed185eb Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Sat, 24 Feb 2024 08:15:20 +0000
Subject: [PATCH 108/202] Update Query.php
Fixes BETWEEN predicate for SQL queries.
---
src/Database/Query.php | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/Database/Query.php b/src/Database/Query.php
index f3acd71b3f..3bdf2b72d6 100644
--- a/src/Database/Query.php
+++ b/src/Database/Query.php
@@ -887,9 +887,10 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
$key = $sql->columnName($this->table, $args[0]);
// ->where('username', 'in', ['myuser', 'myotheruser']);
+ // ->where('quantity', 'between', [10, 50]);
$predicate = trim(strtoupper($args[1]));
if (is_array($args[2]) === true) {
- if (in_array($predicate, ['IN', 'NOT IN']) === false) {
+ if (in_array($predicate, ['IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) === false) {
throw new InvalidArgumentException('Invalid predicate ' . $predicate);
}
@@ -903,15 +904,17 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
$values[] = $valueBinding;
}
- // add that to the where clause in parenthesis
- $result = $key . ' ' . $predicate . ' (' . implode(', ', $values) . ')';
+ // add that to the where clause in parenthesis or seperated by AND
+ $result = $key . ' ' . $predicate . (in_array($predicate, ['IN', 'NOT IN'])
+ ? ' (' . implode(', ', $values) . ')' // IN predicate
+ : ' ' . $values[0] . ' AND ' . $values[1] // BETWEEN predicate
+ );
// ->where('username', 'like', 'myuser');
} else {
$predicates = [
'=', '>=', '>', '<=', '<', '<>', '!=', '<=>',
'IS', 'IS NOT',
- 'BETWEEN', 'NOT BETWEEN',
'LIKE', 'NOT LIKE',
'SOUNDS LIKE',
'REGEXP', 'NOT REGEXP'
From 7c795edf9b0df9582825762e0d3e1f049039a0ab Mon Sep 17 00:00:00 2001
From: SeriousKen
Date: Sat, 24 Feb 2024 08:37:37 +0000
Subject: [PATCH 109/202] Update Query.php
Fix to support BETWEEN predicate in database query abstraction.
From 3f6d99071c0094a6d7d8a2b9bb3f067eef8decb8 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sat, 24 Feb 2024 09:42:21 +0000
Subject: [PATCH 110/202] Added unit test
---
tests/Database/QueryTest.php | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/Database/QueryTest.php b/tests/Database/QueryTest.php
index 3f33bed430..da3b4722e8 100644
--- a/tests/Database/QueryTest.php
+++ b/tests/Database/QueryTest.php
@@ -499,6 +499,14 @@ public function testWhere()
$this->assertSame(2, $count);
+ // between
+ $count = $this->database
+ ->table('users')
+ ->where('balance', 'between', [100, 200])
+ ->count();
+
+ $this->assertSame(3, $count);
+
// 'AND' as value
$count = $this->database
->table('users')
From d2111a6432f44195277747d90b402fa184f971f8 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sat, 24 Feb 2024 10:15:49 +0000
Subject: [PATCH 111/202] Fix coding style
---
src/Database/Query.php | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/Database/Query.php b/src/Database/Query.php
index 3bdf2b72d6..1c9eee4036 100644
--- a/src/Database/Query.php
+++ b/src/Database/Query.php
@@ -828,13 +828,13 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
if ($args[0] === null) {
return $current;
- // ->where('username like "myuser"');
+ // ->where('username like "myuser"');
} elseif (is_string($args[0]) === true) {
// simply add the entire string to the where clause
// escaping or using bindings has to be done before calling this method
$result = $args[0];
- // ->where(['username' => 'myuser']);
+ // ->where(['username' => 'myuser']);
} elseif (is_array($args[0]) === true) {
// simple array mode (AND operator)
$sql = $this->database->sql()->values($this->table, $args[0], ' AND ', true, true);
@@ -868,7 +868,7 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
// store the bindings
$this->bindings($args[1]);
- // ->where('username like ?', 'myuser')
+ // ->where('username like ?', 'myuser')
} elseif (is_string($args[0]) === true && is_string($args[1]) === true) {
// prepared where clause
$result = $args[0];
@@ -905,12 +905,13 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
}
// add that to the where clause in parenthesis or seperated by AND
- $result = $key . ' ' . $predicate . (in_array($predicate, ['IN', 'NOT IN'])
+ $result = $key . ' ' . $predicate . (
+ in_array($predicate, ['IN', 'NOT IN'])
? ' (' . implode(', ', $values) . ')' // IN predicate
: ' ' . $values[0] . ' AND ' . $values[1] // BETWEEN predicate
);
- // ->where('username', 'like', 'myuser');
+ // ->where('username', 'like', 'myuser');
} else {
$predicates = [
'=', '>=', '>', '<=', '<', '<>', '!=', '<=>',
From 8d50627a776e489b04442f9b1ff8ac96f6dcb289 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sat, 24 Feb 2024 10:18:54 +0000
Subject: [PATCH 112/202] Improved code readabilty
---
src/Database/Query.php | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/Database/Query.php b/src/Database/Query.php
index 1c9eee4036..f5daaae8ae 100644
--- a/src/Database/Query.php
+++ b/src/Database/Query.php
@@ -905,11 +905,13 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
}
// add that to the where clause in parenthesis or seperated by AND
- $result = $key . ' ' . $predicate . (
- in_array($predicate, ['IN', 'NOT IN'])
- ? ' (' . implode(', ', $values) . ')' // IN predicate
- : ' ' . $values[0] . ' AND ' . $values[1] // BETWEEN predicate
- );
+ $values = match ($predicate) {
+ 'IN',
+ 'NOT IN' => '(' . implode(', ', $values) . ')',
+ 'BETWEEN',
+ 'NOT BETWEEN' => $values[0] . ' AND ' . $values[1]
+ };
+ $result = $key . ' ' . $predicate . ' ' . $values;
// ->where('username', 'like', 'myuser');
} else {
From b4350c1161e818a3fbc7e98115eedd05eb09b355 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sat, 24 Feb 2024 12:47:10 +0000
Subject: [PATCH 113/202] Added test with string parameters
---
tests/Database/QueryTest.php | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/Database/QueryTest.php b/tests/Database/QueryTest.php
index da3b4722e8..97558231d7 100644
--- a/tests/Database/QueryTest.php
+++ b/tests/Database/QueryTest.php
@@ -507,6 +507,14 @@ public function testWhere()
$this->assertSame(3, $count);
+ // between (with strings)
+ $count = $this->database
+ ->table('users')
+ ->where('username', 'between', ['george', 'mark'])
+ ->count();
+
+ $this->assertSame(3, $count);
+
// 'AND' as value
$count = $this->database
->table('users')
From 9b3398b6ad2ec5d04535e7e349c8a20e51e3ab29 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 24 Feb 2024 18:58:07 +0100
Subject: [PATCH 114/202] Lab: add GitHub source links
---
config/areas/lab/views.php | 14 ++++++++++++--
panel/lab/basics/design/colors/index.php | 3 ++-
panel/lab/basics/design/font-family/index.php | 3 ++-
panel/lab/basics/design/font-size/index.php | 3 ++-
panel/lab/basics/design/font-weight/index.php | 3 ++-
panel/lab/basics/design/height/index.php | 3 ++-
panel/lab/basics/design/opacity/index.php | 5 +++++
panel/lab/basics/design/rounded/index.php | 3 ++-
panel/lab/basics/design/shadow/index.php | 3 ++-
panel/lab/basics/design/spacing/index.php | 1 +
panel/lab/basics/design/z-index/index.php | 3 ++-
panel/lab/basics/icons/1_iconset/index.php | 3 ++-
panel/lab/internals/helpers/array/index.php | 5 +++++
panel/lab/internals/helpers/color/index.php | 5 +++++
panel/lab/internals/helpers/debounce/index.php | 5 +++++
panel/lab/internals/helpers/embed/index.php | 5 +++++
panel/lab/internals/helpers/field/index.php | 5 +++++
panel/lab/internals/helpers/file/index.php | 5 +++++
panel/lab/internals/helpers/focus/index.php | 5 +++++
panel/lab/internals/helpers/isComponent/index.php | 5 +++++
.../lab/internals/helpers/isUploadEvent/index.php | 5 +++++
panel/lab/internals/helpers/keyboard/index.php | 5 +++++
panel/lab/internals/helpers/link/index.php | 5 +++++
panel/lab/internals/helpers/object/index.php | 5 +++++
panel/lab/internals/helpers/queue/index.php | 5 +++++
panel/lab/internals/helpers/ratio/index.php | 5 +++++
panel/lab/internals/helpers/regex/index.php | 5 +++++
panel/lab/internals/helpers/sort/index.php | 5 +++++
panel/lab/internals/helpers/string/index.php | 5 +++++
panel/lab/internals/helpers/upload/index.php | 5 +++++
panel/lab/internals/helpers/url/index.php | 5 +++++
panel/lab/internals/library.colors/index.php | 5 +++++
.../lab/internals/library.dayjs/1_dayjs/index.php | 5 +++++
.../lab/internals/library.dayjs/2_format/index.php | 5 +++++
.../internals/library.dayjs/3_interpret/index.php | 5 +++++
panel/lab/internals/library.dayjs/4_iso/index.php | 5 +++++
.../internals/library.dayjs/5_validate/index.php | 5 +++++
panel/lab/internals/panel/api/index.php | 5 +++++
panel/lab/internals/panel/config/index.php | 5 +++++
panel/lab/internals/panel/dialog/index.php | 5 +++++
panel/lab/internals/panel/drag/index.php | 5 +++++
panel/lab/internals/panel/drawer/index.php | 5 +++++
panel/lab/internals/panel/dropdown/index.php | 5 +++++
panel/lab/internals/panel/events/index.php | 5 +++++
panel/lab/internals/panel/language/index.php | 5 +++++
panel/lab/internals/panel/notification/index.php | 5 +++++
panel/lab/internals/panel/panel/index.php | 5 +++++
panel/lab/internals/panel/system/index.php | 5 +++++
panel/lab/internals/panel/translation/index.php | 5 +++++
panel/lab/internals/panel/upload/index.php | 5 +++++
panel/lab/internals/panel/urls/index.php | 5 +++++
panel/lab/internals/panel/user/index.php | 5 +++++
panel/lab/internals/panel/view/index.php | 5 +++++
panel/src/components/Lab/PlaygroundView.vue | 4 ++--
src/Panel/Lab/Example.php | 13 -------------
55 files changed, 243 insertions(+), 26 deletions(-)
create mode 100644 panel/lab/basics/design/opacity/index.php
create mode 100644 panel/lab/internals/helpers/array/index.php
create mode 100644 panel/lab/internals/helpers/color/index.php
create mode 100644 panel/lab/internals/helpers/debounce/index.php
create mode 100644 panel/lab/internals/helpers/embed/index.php
create mode 100644 panel/lab/internals/helpers/field/index.php
create mode 100644 panel/lab/internals/helpers/file/index.php
create mode 100644 panel/lab/internals/helpers/focus/index.php
create mode 100644 panel/lab/internals/helpers/isComponent/index.php
create mode 100644 panel/lab/internals/helpers/isUploadEvent/index.php
create mode 100644 panel/lab/internals/helpers/keyboard/index.php
create mode 100644 panel/lab/internals/helpers/link/index.php
create mode 100644 panel/lab/internals/helpers/object/index.php
create mode 100644 panel/lab/internals/helpers/queue/index.php
create mode 100644 panel/lab/internals/helpers/ratio/index.php
create mode 100644 panel/lab/internals/helpers/regex/index.php
create mode 100644 panel/lab/internals/helpers/sort/index.php
create mode 100644 panel/lab/internals/helpers/string/index.php
create mode 100644 panel/lab/internals/helpers/upload/index.php
create mode 100644 panel/lab/internals/helpers/url/index.php
create mode 100644 panel/lab/internals/library.colors/index.php
create mode 100644 panel/lab/internals/library.dayjs/1_dayjs/index.php
create mode 100644 panel/lab/internals/library.dayjs/2_format/index.php
create mode 100644 panel/lab/internals/library.dayjs/3_interpret/index.php
create mode 100644 panel/lab/internals/library.dayjs/4_iso/index.php
create mode 100644 panel/lab/internals/library.dayjs/5_validate/index.php
create mode 100644 panel/lab/internals/panel/api/index.php
create mode 100644 panel/lab/internals/panel/config/index.php
create mode 100644 panel/lab/internals/panel/dialog/index.php
create mode 100644 panel/lab/internals/panel/drag/index.php
create mode 100644 panel/lab/internals/panel/drawer/index.php
create mode 100644 panel/lab/internals/panel/dropdown/index.php
create mode 100644 panel/lab/internals/panel/events/index.php
create mode 100644 panel/lab/internals/panel/language/index.php
create mode 100644 panel/lab/internals/panel/notification/index.php
create mode 100644 panel/lab/internals/panel/panel/index.php
create mode 100644 panel/lab/internals/panel/system/index.php
create mode 100644 panel/lab/internals/panel/translation/index.php
create mode 100644 panel/lab/internals/panel/upload/index.php
create mode 100644 panel/lab/internals/panel/urls/index.php
create mode 100644 panel/lab/internals/panel/user/index.php
create mode 100644 panel/lab/internals/panel/view/index.php
diff --git a/config/areas/lab/views.php b/config/areas/lab/views.php
index 53428dda99..c1cf42ddcf 100644
--- a/config/areas/lab/views.php
+++ b/config/areas/lab/views.php
@@ -109,6 +109,16 @@
$props = $example->props();
$vue = $example->vue();
+ if (Docs::installed() === true && $docs = $props['docs'] ?? null) {
+ $docs = new Docs($docs);
+ }
+
+ $github = $docs?->github();
+
+ if ($source = $props['source'] ?? null) {
+ $github ??= 'https://github.com/getkirby/kirby/tree/main/' . $source;
+ }
+
return [
'component' => 'k-lab-playground-view',
'breadcrumb' => [
@@ -121,10 +131,10 @@
]
],
'props' => [
- 'docs' => $props['docs'] ?? null,
+ 'docs' => $docs?->name(),
'examples' => $vue['examples'],
'file' => $example->module(),
- 'github' => $example->github(),
+ 'github' => $github,
'props' => $props,
'styles' => $vue['style'],
'tab' => $example->tab(),
diff --git a/panel/lab/basics/design/colors/index.php b/panel/lab/basics/design/colors/index.php
index 5952f63382..1c9c7d1a0e 100644
--- a/panel/lab/basics/design/colors/index.php
+++ b/panel/lab/basics/design/colors/index.php
@@ -22,5 +22,6 @@
700,
800,
900
- ]
+ ],
+ 'source' => 'panel/src/styles/config/colors.css'
];
diff --git a/panel/lab/basics/design/font-family/index.php b/panel/lab/basics/design/font-family/index.php
index 9b32985e18..b93b746d0d 100644
--- a/panel/lab/basics/design/font-family/index.php
+++ b/panel/lab/basics/design/font-family/index.php
@@ -14,5 +14,6 @@
'2xl',
'3xl',
'4xl'
- ]
+ ],
+ 'source' => 'panel/src/styles/config/font-family.css'
];
diff --git a/panel/lab/basics/design/font-size/index.php b/panel/lab/basics/design/font-size/index.php
index 0d5c0d134a..fd8264ba50 100644
--- a/panel/lab/basics/design/font-size/index.php
+++ b/panel/lab/basics/design/font-size/index.php
@@ -10,5 +10,6 @@
'2xl',
'3xl',
'4xl'
- ]
+ ],
+ 'source' => 'panel/src/styles/config/font-size.css'
];
diff --git a/panel/lab/basics/design/font-weight/index.php b/panel/lab/basics/design/font-weight/index.php
index 0ee9658a64..cbec936202 100644
--- a/panel/lab/basics/design/font-weight/index.php
+++ b/panel/lab/basics/design/font-weight/index.php
@@ -6,5 +6,6 @@
'normal',
'semi',
'bold',
- ]
+ ],
+ 'source' => 'panel/src/styles/config/font-weight.css'
];
diff --git a/panel/lab/basics/design/height/index.php b/panel/lab/basics/design/height/index.php
index 6f8d3def5c..b16c92b8a0 100644
--- a/panel/lab/basics/design/height/index.php
+++ b/panel/lab/basics/design/height/index.php
@@ -7,5 +7,6 @@
'md',
'lg',
'xl',
- ]
+ ],
+ 'source' => 'panel/src/styles/config/height.css'
];
diff --git a/panel/lab/basics/design/opacity/index.php b/panel/lab/basics/design/opacity/index.php
new file mode 100644
index 0000000000..09df9590af
--- /dev/null
+++ b/panel/lab/basics/design/opacity/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/styles/config/opacity.css'
+];
diff --git a/panel/lab/basics/design/rounded/index.php b/panel/lab/basics/design/rounded/index.php
index 159b92e263..1e557e909c 100644
--- a/panel/lab/basics/design/rounded/index.php
+++ b/panel/lab/basics/design/rounded/index.php
@@ -7,5 +7,6 @@
'md',
'lg',
'xl',
- ]
+ ],
+ 'source' => 'panel/src/styles/config/rounded.css'
];
diff --git a/panel/lab/basics/design/shadow/index.php b/panel/lab/basics/design/shadow/index.php
index 2afc8db9d3..5af4ebeeed 100644
--- a/panel/lab/basics/design/shadow/index.php
+++ b/panel/lab/basics/design/shadow/index.php
@@ -6,5 +6,6 @@
'md',
'lg',
'xl',
- ]
+ ],
+ 'source' => 'panel/src/styles/config/shadow.css'
];
diff --git a/panel/lab/basics/design/spacing/index.php b/panel/lab/basics/design/spacing/index.php
index fd311c86bf..96b9b4b2a9 100644
--- a/panel/lab/basics/design/spacing/index.php
+++ b/panel/lab/basics/design/spacing/index.php
@@ -14,4 +14,5 @@
36,
48
],
+ 'source' => 'panel/src/styles/config/spacing.css'
];
diff --git a/panel/lab/basics/design/z-index/index.php b/panel/lab/basics/design/z-index/index.php
index b25bf9f456..12b9fc7bc8 100644
--- a/panel/lab/basics/design/z-index/index.php
+++ b/panel/lab/basics/design/z-index/index.php
@@ -14,5 +14,6 @@
'toolbar',
'content',
'background',
- ]
+ ],
+ 'source' => 'panel/src/styles/config/z-index.css'
];
diff --git a/panel/lab/basics/icons/1_iconset/index.php b/panel/lab/basics/icons/1_iconset/index.php
index 5c5a9510fa..d2c21f7ab1 100644
--- a/panel/lab/basics/icons/1_iconset/index.php
+++ b/panel/lab/basics/icons/1_iconset/index.php
@@ -13,5 +13,6 @@
}
return [
- 'icons' => $icons
+ 'icons' => $icons,
+ 'source' => 'panel/public/img/icons.svg'
];
diff --git a/panel/lab/internals/helpers/array/index.php b/panel/lab/internals/helpers/array/index.php
new file mode 100644
index 0000000000..e436e488ca
--- /dev/null
+++ b/panel/lab/internals/helpers/array/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/array.js'
+];
diff --git a/panel/lab/internals/helpers/color/index.php b/panel/lab/internals/helpers/color/index.php
new file mode 100644
index 0000000000..24f3c0c467
--- /dev/null
+++ b/panel/lab/internals/helpers/color/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/color.js'
+];
diff --git a/panel/lab/internals/helpers/debounce/index.php b/panel/lab/internals/helpers/debounce/index.php
new file mode 100644
index 0000000000..10a932d1f1
--- /dev/null
+++ b/panel/lab/internals/helpers/debounce/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/debounce.js'
+];
diff --git a/panel/lab/internals/helpers/embed/index.php b/panel/lab/internals/helpers/embed/index.php
new file mode 100644
index 0000000000..e4f41a2c5d
--- /dev/null
+++ b/panel/lab/internals/helpers/embed/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/embed.js'
+];
diff --git a/panel/lab/internals/helpers/field/index.php b/panel/lab/internals/helpers/field/index.php
new file mode 100644
index 0000000000..703c05b110
--- /dev/null
+++ b/panel/lab/internals/helpers/field/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/field.js'
+];
diff --git a/panel/lab/internals/helpers/file/index.php b/panel/lab/internals/helpers/file/index.php
new file mode 100644
index 0000000000..f7b2e8187d
--- /dev/null
+++ b/panel/lab/internals/helpers/file/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/file.js'
+];
diff --git a/panel/lab/internals/helpers/focus/index.php b/panel/lab/internals/helpers/focus/index.php
new file mode 100644
index 0000000000..ce90f570bf
--- /dev/null
+++ b/panel/lab/internals/helpers/focus/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/focus.js'
+];
diff --git a/panel/lab/internals/helpers/isComponent/index.php b/panel/lab/internals/helpers/isComponent/index.php
new file mode 100644
index 0000000000..530741425c
--- /dev/null
+++ b/panel/lab/internals/helpers/isComponent/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/isComponent.js'
+];
diff --git a/panel/lab/internals/helpers/isUploadEvent/index.php b/panel/lab/internals/helpers/isUploadEvent/index.php
new file mode 100644
index 0000000000..c1919539e3
--- /dev/null
+++ b/panel/lab/internals/helpers/isUploadEvent/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/isUploadEvent.js'
+];
diff --git a/panel/lab/internals/helpers/keyboard/index.php b/panel/lab/internals/helpers/keyboard/index.php
new file mode 100644
index 0000000000..f2f9e8140a
--- /dev/null
+++ b/panel/lab/internals/helpers/keyboard/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/keyboard.js'
+];
diff --git a/panel/lab/internals/helpers/link/index.php b/panel/lab/internals/helpers/link/index.php
new file mode 100644
index 0000000000..375f8066c2
--- /dev/null
+++ b/panel/lab/internals/helpers/link/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/link.js'
+];
diff --git a/panel/lab/internals/helpers/object/index.php b/panel/lab/internals/helpers/object/index.php
new file mode 100644
index 0000000000..0db4ddada8
--- /dev/null
+++ b/panel/lab/internals/helpers/object/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/object.js'
+];
diff --git a/panel/lab/internals/helpers/queue/index.php b/panel/lab/internals/helpers/queue/index.php
new file mode 100644
index 0000000000..8bc8ceaf34
--- /dev/null
+++ b/panel/lab/internals/helpers/queue/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/queue.js'
+];
diff --git a/panel/lab/internals/helpers/ratio/index.php b/panel/lab/internals/helpers/ratio/index.php
new file mode 100644
index 0000000000..2e4c4b3d3d
--- /dev/null
+++ b/panel/lab/internals/helpers/ratio/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/ratio.js'
+];
diff --git a/panel/lab/internals/helpers/regex/index.php b/panel/lab/internals/helpers/regex/index.php
new file mode 100644
index 0000000000..aab4ab5250
--- /dev/null
+++ b/panel/lab/internals/helpers/regex/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/regex.js'
+];
diff --git a/panel/lab/internals/helpers/sort/index.php b/panel/lab/internals/helpers/sort/index.php
new file mode 100644
index 0000000000..848d1be29b
--- /dev/null
+++ b/panel/lab/internals/helpers/sort/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/sort.js'
+];
diff --git a/panel/lab/internals/helpers/string/index.php b/panel/lab/internals/helpers/string/index.php
new file mode 100644
index 0000000000..1dda28ec72
--- /dev/null
+++ b/panel/lab/internals/helpers/string/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/string.js'
+];
diff --git a/panel/lab/internals/helpers/upload/index.php b/panel/lab/internals/helpers/upload/index.php
new file mode 100644
index 0000000000..3d5b30f854
--- /dev/null
+++ b/panel/lab/internals/helpers/upload/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/upload.js'
+];
diff --git a/panel/lab/internals/helpers/url/index.php b/panel/lab/internals/helpers/url/index.php
new file mode 100644
index 0000000000..28bc130a92
--- /dev/null
+++ b/panel/lab/internals/helpers/url/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/helpers/url.js'
+];
diff --git a/panel/lab/internals/library.colors/index.php b/panel/lab/internals/library.colors/index.php
new file mode 100644
index 0000000000..b015c92c4c
--- /dev/null
+++ b/panel/lab/internals/library.colors/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/libraries/colors.js'
+];
diff --git a/panel/lab/internals/library.dayjs/1_dayjs/index.php b/panel/lab/internals/library.dayjs/1_dayjs/index.php
new file mode 100644
index 0000000000..28cd3b8c0e
--- /dev/null
+++ b/panel/lab/internals/library.dayjs/1_dayjs/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/libraries/dayjs.js'
+];
diff --git a/panel/lab/internals/library.dayjs/2_format/index.php b/panel/lab/internals/library.dayjs/2_format/index.php
new file mode 100644
index 0000000000..28cd3b8c0e
--- /dev/null
+++ b/panel/lab/internals/library.dayjs/2_format/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/libraries/dayjs.js'
+];
diff --git a/panel/lab/internals/library.dayjs/3_interpret/index.php b/panel/lab/internals/library.dayjs/3_interpret/index.php
new file mode 100644
index 0000000000..8e9bf76521
--- /dev/null
+++ b/panel/lab/internals/library.dayjs/3_interpret/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/libraries/dayjs-interpret.js'
+];
diff --git a/panel/lab/internals/library.dayjs/4_iso/index.php b/panel/lab/internals/library.dayjs/4_iso/index.php
new file mode 100644
index 0000000000..484325de29
--- /dev/null
+++ b/panel/lab/internals/library.dayjs/4_iso/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/libraries/dayjs-iso.js'
+];
diff --git a/panel/lab/internals/library.dayjs/5_validate/index.php b/panel/lab/internals/library.dayjs/5_validate/index.php
new file mode 100644
index 0000000000..7ec4694ff8
--- /dev/null
+++ b/panel/lab/internals/library.dayjs/5_validate/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/libraries/dayjs-validate.js'
+];
diff --git a/panel/lab/internals/panel/api/index.php b/panel/lab/internals/panel/api/index.php
new file mode 100644
index 0000000000..eeba0d07c8
--- /dev/null
+++ b/panel/lab/internals/panel/api/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/api/index.js'
+];
diff --git a/panel/lab/internals/panel/config/index.php b/panel/lab/internals/panel/config/index.php
new file mode 100644
index 0000000000..3db6b98233
--- /dev/null
+++ b/panel/lab/internals/panel/config/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/panel.js'
+];
diff --git a/panel/lab/internals/panel/dialog/index.php b/panel/lab/internals/panel/dialog/index.php
new file mode 100644
index 0000000000..0644ec2f2e
--- /dev/null
+++ b/panel/lab/internals/panel/dialog/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/dialog.js'
+];
diff --git a/panel/lab/internals/panel/drag/index.php b/panel/lab/internals/panel/drag/index.php
new file mode 100644
index 0000000000..5fc3483d6e
--- /dev/null
+++ b/panel/lab/internals/panel/drag/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/drag.js'
+];
diff --git a/panel/lab/internals/panel/drawer/index.php b/panel/lab/internals/panel/drawer/index.php
new file mode 100644
index 0000000000..316c470435
--- /dev/null
+++ b/panel/lab/internals/panel/drawer/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/drawer.js'
+];
diff --git a/panel/lab/internals/panel/dropdown/index.php b/panel/lab/internals/panel/dropdown/index.php
new file mode 100644
index 0000000000..212ac547e3
--- /dev/null
+++ b/panel/lab/internals/panel/dropdown/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/dropdown.js'
+];
diff --git a/panel/lab/internals/panel/events/index.php b/panel/lab/internals/panel/events/index.php
new file mode 100644
index 0000000000..4d8c2fb1d0
--- /dev/null
+++ b/panel/lab/internals/panel/events/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/events.js'
+];
diff --git a/panel/lab/internals/panel/language/index.php b/panel/lab/internals/panel/language/index.php
new file mode 100644
index 0000000000..c566102b5c
--- /dev/null
+++ b/panel/lab/internals/panel/language/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/language.js'
+];
diff --git a/panel/lab/internals/panel/notification/index.php b/panel/lab/internals/panel/notification/index.php
new file mode 100644
index 0000000000..ee6ea86626
--- /dev/null
+++ b/panel/lab/internals/panel/notification/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/notification.js'
+];
diff --git a/panel/lab/internals/panel/panel/index.php b/panel/lab/internals/panel/panel/index.php
new file mode 100644
index 0000000000..3db6b98233
--- /dev/null
+++ b/panel/lab/internals/panel/panel/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/panel.js'
+];
diff --git a/panel/lab/internals/panel/system/index.php b/panel/lab/internals/panel/system/index.php
new file mode 100644
index 0000000000..9a13546ac4
--- /dev/null
+++ b/panel/lab/internals/panel/system/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/system.js'
+];
diff --git a/panel/lab/internals/panel/translation/index.php b/panel/lab/internals/panel/translation/index.php
new file mode 100644
index 0000000000..af8580c47a
--- /dev/null
+++ b/panel/lab/internals/panel/translation/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/translation.js'
+];
diff --git a/panel/lab/internals/panel/upload/index.php b/panel/lab/internals/panel/upload/index.php
new file mode 100644
index 0000000000..3eb93e15a1
--- /dev/null
+++ b/panel/lab/internals/panel/upload/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/upload.js'
+];
diff --git a/panel/lab/internals/panel/urls/index.php b/panel/lab/internals/panel/urls/index.php
new file mode 100644
index 0000000000..3db6b98233
--- /dev/null
+++ b/panel/lab/internals/panel/urls/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/panel.js'
+];
diff --git a/panel/lab/internals/panel/user/index.php b/panel/lab/internals/panel/user/index.php
new file mode 100644
index 0000000000..450b34a4f1
--- /dev/null
+++ b/panel/lab/internals/panel/user/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/user.js'
+];
diff --git a/panel/lab/internals/panel/view/index.php b/panel/lab/internals/panel/view/index.php
new file mode 100644
index 0000000000..74ca6edbba
--- /dev/null
+++ b/panel/lab/internals/panel/view/index.php
@@ -0,0 +1,5 @@
+ 'panel/src/panel/view.js'
+];
diff --git a/panel/src/components/Lab/PlaygroundView.vue b/panel/src/components/Lab/PlaygroundView.vue
index fc2a849b13..3dce3ca083 100644
--- a/panel/src/components/Lab/PlaygroundView.vue
+++ b/panel/src/components/Lab/PlaygroundView.vue
@@ -16,11 +16,11 @@
/>
diff --git a/src/Panel/Lab/Example.php b/src/Panel/Lab/Example.php
index 7e48ed51c7..a5ab2d6690 100644
--- a/src/Panel/Lab/Example.php
+++ b/src/Panel/Lab/Example.php
@@ -2,12 +2,10 @@
namespace Kirby\Panel\Lab;
-use Kirby\Cms\App;
use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\Dir;
use Kirby\Filesystem\F;
use Kirby\Http\Response;
-use Kirby\Toolkit\Str;
/**
* One or multiple lab examples with one or multiple tabs
@@ -81,17 +79,6 @@ public function file(string $filename): string
return $this->parent->root() . '/' . $this->path() . '/' . $filename;
}
- public function github(): string
- {
- $path = Str::after($this->root(), App::instance()->root('kirby'));
-
- if ($tab = $this->tab()) {
- $path .= '/' . $tab;
- }
-
- return 'https://github.com/getkirby/kirby/tree/main' . $path;
- }
-
public function id(): string
{
return $this->id;
From ea293a6d538780a421024202eee677ced67c0e67 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 24 Feb 2024 19:03:28 +0100
Subject: [PATCH 115/202] Lab: better call signature for `$helper`
---
panel/lab/internals/helpers/array/index.vue | 52 ++-
panel/lab/internals/helpers/string/index.vue | 317 +++++++------------
2 files changed, 143 insertions(+), 226 deletions(-)
diff --git a/panel/lab/internals/helpers/array/index.vue b/panel/lab/internals/helpers/array/index.vue
index 6678c238bd..412e6ccf02 100644
--- a/panel/lab/internals/helpers/array/index.vue
+++ b/panel/lab/internals/helpers/array/index.vue
@@ -1,19 +1,17 @@
-
-
- Access the following array helpers in your Vue components through
- this.$helper.array
-
-
+
+ Access the following array helpers in your Vue components through
+ this.$helper.array
+
-
- Creates an array from an object:
- this.$helper.array.fromObject(object)
-
+ Creates an array from an object:
+
+ this.$helper.array.fromObject(object): array
+
@@ -32,13 +30,9 @@
-
- Filters an array by a provided query:
-
- this.$helper.array.search(array, "{{ searchQuery }}", { min: 2,
- field: "name" })
-
-
+ Filters an array by a provided query:
+
+ this.$helper.array.search(array, "{{ searchQuery }}", { min: 2, field: "name" }): array
@@ -64,11 +58,11 @@
-
- Sorts an array by one or more fields and directions:
- this.$helper.array.sortBy(array, "name desc")
-
+ Sorts an array by one or more fields and directions:
+
+ this.$helper.array.sortBy(array, "name desc"): array
+
@@ -87,11 +81,11 @@
-
- Splits an array into groups by a delimiter entry:
- this.$helper.array.split(array, "-")
-
+ Splits an array into groups by a delimiter entry:
+
+ this.$helper.array.split(array, "-"): array
+
@@ -110,11 +104,11 @@
-
- Wraps a value in an array (ensures the value will be an array):
- this.$helper.array.wrap(value)
-
+ Wraps a value in an array (ensures the value will be an array):
+
+ this.$helper.array.wrap(value): array
+
diff --git a/panel/lab/internals/helpers/string/index.vue b/panel/lab/internals/helpers/string/index.vue
index 66af00001b..21375b9715 100644
--- a/panel/lab/internals/helpers/string/index.vue
+++ b/panel/lab/internals/helpers/string/index.vue
@@ -9,20 +9,15 @@
-
- Converts camel-case to kebab-case:
- this.$helper.string.camelToKebab(string)
-
+ Converts camel-case to kebab-case:
+
+ this.$helper.string.camelToKebab(string): string
Input
-
+
Result
@@ -36,26 +31,19 @@
-
- Escapes HTML in string:
- this.$helper.string.escapeHTML(string)
-
+ Escapes HTML in string:
+
+ this.$helper.string.escapeHTML(string): string
Input
-
+
Result
- {{
- $helper.string.escapeHTML(html)
- }}
+ {{ $helper.string.escapeHTML(html) }}
@@ -63,24 +51,21 @@
-
- Checks if string contains an emoji:
- this.$helper.string.hasEmoji(string)
-
+ Checks if string contains an emoji:
+
+ this.$helper.string.hasEmoji(string): boolean
Input
-
+
Result
- {{ $helper.string.hasEmoji(emoji) }}
+ {{
+ $helper.string.hasEmoji(emoji)
+ }}
@@ -88,24 +73,21 @@
-
- Checks if a string is empty:
- this.$helper.string.isEmpty(string)
-
+ Checks if a string is empty:
+
+ this.$helper.string.isEmpty(string): boolean
Input
-
+
Result
- {{ $helper.string.isEmpty(empty) }}
+ {{
+ $helper.string.isEmpty(empty)
+ }}
@@ -113,20 +95,15 @@
-
- Turns first letter lowercase:
- this.$helper.string.lcfirst(string)
-
+ Turns first letter lowercase:
+
+ this.$helper.string.lcfirst(string): string
Input
-
+
Result
@@ -138,24 +115,21 @@
-
- Trims the given character(s) at the beginning of the string:
- this.$helper.string.ltrim(string, replace)
-
+ Trims the given character(s) at the beginning of the string:
+
+ this.$helper.string.ltrim(string): string
Input
-
+
Result
- {{ $helper.string.ltrim(ltrim, '*') }}
+ {{
+ $helper.string.ltrim(ltrim, "*")
+ }}
@@ -163,28 +137,19 @@
-
- Prefixes string with 0 until length is reached:
- this.$helper.string.pad(string, length)
-
+ Prefixes string with 0 until length is reached:
+
+ this.$helper.string.pad(string, length): string
Input
-
+
- How many digits?
-
+ Length
+
Result
@@ -198,10 +163,9 @@
-
- Generate random alpha-num string of specified length:
- this.$helper.string.random(length)
-
+ Generate random alpha-num string of specified length:
+
+ this.$helper.string.random(length): string
@@ -223,24 +187,21 @@
-
- Trims the given character(s) at the end of the string:
- this.$helper.string.rtrim(string, replace)
-
+ Trims the given character(s) at the end of the string:
+
+ this.$helper.string.rtrim(string): string
Input
-
+
Result
- {{ $helper.string.rtrim(rtrim, '*') }}
+ {{
+ $helper.string.rtrim(rtrim, "*")
+ }}
@@ -248,20 +209,23 @@
-
- Convert string to ASCII slug:
- this.$helper.string.slug(string, rules, allowed, separator)
-
+ Convert string to ASCII slug:
+
+
+ this.$helper.string.slug(string, rules, allowed, separator): string
- rules
(array): Array of custom rules for replacing characters, e.g. [{ "ä": "ae" }]
+ rules
(array): Array of custom rules for replacing
+ characters, e.g. [{ "ä": "ae" }]
- allowed
(string): Allowed characters, default is a-z0-9
+ allowed
(string): Allowed characters, default is
+ a-z0-9
- separator
(string): Separator for the slug, default is -
+ separator
(string): Separator for the slug, default is
+ -
@@ -270,16 +234,12 @@
Input
-
+
Result
{{
- $helper.string.slug(slug, [{'ä': 'ae' }])
+ $helper.string.slug(slug, [{ ä: "ae" }])
}}
@@ -288,26 +248,19 @@
-
- Removes HTML from a string:
- this.$helper.string.stripHTML(string)
-
+ Removes HTML from a string:
+
+ this.$helper.string.stripHTML(string): string
Input
-
+
Result
- {{
- $helper.string.stripHTML(html)
- }}
+ {{ $helper.string.stripHTML(html) }}
@@ -315,26 +268,19 @@
-
- Turns first letter uppercase:
- this.$helper.string.ucfirst(string)
-
+ Turns first letter uppercase:
+
+ this.$helper.string.ucfirst(string): string
Input
-
+
Result
- {{
- $helper.string.ucfirst(ucfirst)
- }}
+ {{ $helper.string.ucfirst(ucfirst) }}
@@ -342,24 +288,17 @@
-
- Replaces template placeholders in string with provided values:
- this.$helper.string.template(string, values)
-
+ Replaces template placeholders in string with provided values:
+
+ this.$helper.string.template(string, values): string
Input
-
-
- {{
- templateValues
- }}
+
+
+ {{ templateValues }}
Result
@@ -373,26 +312,19 @@
-
- Turns first letter of each word uppercase:
- this.$helper.string.ucwords(string)
-
+ Turns first letter of each word uppercase:
+
+ this.$helper.string.ucwords(string): string
Input
-
+
Result
- {{
- $helper.string.ucwords(ucwords)
- }}
+ {{ $helper.string.ucwords(ucwords) }}
@@ -400,20 +332,15 @@
-
- Turns escaped HTML entities into actual characters again:
- this.$helper.string.unescapeHTML(string)
-
+ Turns escaped HTML entities into actual characters again:
+
+ this.$helper.string.unescapeHTML(string): string
Input
-
+
Result
@@ -427,18 +354,15 @@
-
- Returns a unique ID:
- this.$helper.string.uuid()
-
+ Returns a unique ID:
+
+ this.$helper.string.uuid(): string
- {{
- $helper.string.uuid()
- }}
+ Result
+ {{ $helper.string.uuid() }}
-
@@ -448,7 +372,7 @@ export const camelCase = {
data() {
return {
camelCase: "myCamelCase"
- }
+ };
}
};
/** @script-end */
@@ -457,8 +381,8 @@ export const camelCase = {
export const html = {
data() {
return {
- html: "This is HTML
",
- }
+ html: "This is HTML
"
+ };
}
};
/** @script-end */
@@ -467,8 +391,8 @@ export const html = {
export const emoji = {
data() {
return {
- emoji: "This string contains an emoji 🎉",
- }
+ emoji: "This string contains an emoji 🎉"
+ };
}
};
/** @script-end */
@@ -477,8 +401,8 @@ export const emoji = {
export const empty = {
data() {
return {
- empty: " ",
- }
+ empty: " "
+ };
}
};
/** @script-end */
@@ -487,8 +411,8 @@ export const empty = {
export const lcfirst = {
data() {
return {
- lcfirst: "This should start with a lowercase letter",
- }
+ lcfirst: "This should start with a lowercase letter"
+ };
}
};
/** @script-end */
@@ -497,8 +421,8 @@ export const lcfirst = {
export const ltrim = {
data() {
return {
- ltrim: "***This had *'s at the beginning",
- }
+ ltrim: "***This had *'s at the beginning"
+ };
}
};
/** @script-end */
@@ -508,8 +432,8 @@ export const pad = {
data() {
return {
padString: "99",
- padCount: 5,
- }
+ padCount: 5
+ };
}
};
/** @script-end */
@@ -519,7 +443,7 @@ export const random = {
data() {
return {
random: this.$helper.string.random(20)
- }
+ };
}
};
/** @script-end */
@@ -528,8 +452,8 @@ export const random = {
export const rtrim = {
data() {
return {
- rtrim: "This had *'s at the end***",
- }
+ rtrim: "This had *'s at the end***"
+ };
}
};
/** @script-end */
@@ -538,8 +462,8 @@ export const rtrim = {
export const slug = {
data() {
return {
- slug: "This is a string with späces",
- }
+ slug: "This is a string with späces"
+ };
}
};
/** @script-end */
@@ -548,17 +472,16 @@ export const slug = {
export const template = {
data() {
return {
- template: "This is { foo } and {{ baz }}",
- }
+ template: "This is { foo } and {{ baz }}"
+ };
},
computed: {
templateValues() {
return {
- "foo": "bar",
- "baz": "qux"
- }
+ foo: "bar",
+ baz: "qux"
+ };
}
-
}
};
/** @script-end */
@@ -567,8 +490,8 @@ export const template = {
export const ucfirst = {
data() {
return {
- ucfirst: "this should start with an uppercase letter",
- }
+ ucfirst: "this should start with an uppercase letter"
+ };
}
};
/** @script-end */
@@ -577,8 +500,8 @@ export const ucfirst = {
export const ucwords = {
data() {
return {
- ucwords: "this is a string with multiple words",
- }
+ ucwords: "this is a string with multiple words"
+ };
}
};
/** @script-end */
@@ -588,7 +511,7 @@ export const unhtml = {
data() {
return {
unhtml: "This is <div>HTML</div>"
- }
+ };
}
};
/** @script-end */
From 008e54b9604336a88ee9d1a03ee3a95a579baa56 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 24 Feb 2024 22:29:14 +0100
Subject: [PATCH 116/202] Psalm: suppress `DuplicateArrayKey`
---
psalm.xml.dist | 3 +++
1 file changed, 3 insertions(+)
diff --git a/psalm.xml.dist b/psalm.xml.dist
index b3059f3044..6caab21a17 100644
--- a/psalm.xml.dist
+++ b/psalm.xml.dist
@@ -31,6 +31,9 @@
+
+
+
From a486a2e4d7a006a8ab2d070c359a62c30e534a96 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sun, 25 Feb 2024 00:58:10 +0000
Subject: [PATCH 117/202] Improved parameter binding for inserts and selects
---
src/Database/Database.php | 18 +++++++++++++++++-
tests/Database/DbTest.php | 20 +++++++++++++++-----
tests/Database/QueryTest.php | 34 ++++++++++++++++++++++++++++------
3 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/src/Database/Database.php b/src/Database/Database.php
index 1683187a43..736fabe137 100644
--- a/src/Database/Database.php
+++ b/src/Database/Database.php
@@ -305,7 +305,23 @@ protected function hit(string $query, array $bindings = []): bool
// try to prepare and execute the sql
try {
$this->statement = $this->connection->prepare($query);
- $this->statement->execute($bindings);
+ // bind parameters to statement
+ foreach ($bindings as $parameter => $value) {
+ // positional parameters start at 1
+ if (is_int($parameter)) {
+ $parameter++;
+ }
+
+ $type = match (gettype($value)) {
+ 'integer' => PDO::PARAM_INT,
+ 'boolean' => PDO::PARAM_BOOL,
+ 'NULL' => PDO::PARAM_NULL,
+ default => PDO::PARAM_STR
+ };
+
+ $this->statement->bindValue($parameter, $value, $type);
+ }
+ $this->statement->execute();
$this->affected = $this->statement->rowCount();
$this->lastId = Str::startsWith($query, 'insert ', true) ? $this->connection->lastInsertId() : null;
diff --git a/tests/Database/DbTest.php b/tests/Database/DbTest.php
index b80453cb14..1420de34a3 100644
--- a/tests/Database/DbTest.php
+++ b/tests/Database/DbTest.php
@@ -26,7 +26,8 @@ public function setUp(): void
"fname" TEXT,
"lname" TEXT,
"password" TEXT NOT NULL,
- "email" TEXT NOT NULL
+ "email" TEXT NOT NULL,
+ "active" INTEGER NOT NULL
);
');
@@ -36,7 +37,8 @@ public function setUp(): void
'fname' => 'John',
'lname' => 'Lennon',
'email' => 'john@test.com',
- 'password' => 'beatles'
+ 'password' => 'beatles',
+ 'active' => true,
]);
Db::insert('users', [
@@ -44,7 +46,8 @@ public function setUp(): void
'fname' => 'Paul',
'lname' => 'McCartney',
'email' => 'paul@test.com',
- 'password' => 'beatles'
+ 'password' => 'beatles',
+ 'active' => true,
]);
Db::insert('users', [
@@ -52,7 +55,8 @@ public function setUp(): void
'fname' => 'George',
'lname' => 'Harrison',
'email' => 'george@test.com',
- 'password' => 'beatles'
+ 'password' => 'beatles',
+ 'active' => false,
]);
}
@@ -177,6 +181,10 @@ public function testSelect()
$result = Db::select('users', 'username', null, 'username ASC', 1, 1);
$this->assertCount(1, $result);
$this->assertSame('john', $result->first()->username());
+
+ $result = Db::select('users', 'username', ['active' => false]);
+ $this->assertCount(1, $result);
+ $this->assertSame('george', $result->first()->username());
}
/**
@@ -228,10 +236,12 @@ public function testInsert()
'fname' => 'Ringo',
'lname' => 'Starr',
'email' => 'ringo@test.com',
- 'password' => 'beatles'
+ 'password' => 'beatles',
+ 'active' => false,
]);
$this->assertSame(4, $result);
$this->assertSame('ringo@test.com', Db::row('users', '*', ['username' => 'ringo'])->email());
+ $this->assertSame('0', Db::row('users', '*', ['username' => 'ringo'])->active());
}
/**
diff --git a/tests/Database/QueryTest.php b/tests/Database/QueryTest.php
index 97558231d7..8f463bcd78 100644
--- a/tests/Database/QueryTest.php
+++ b/tests/Database/QueryTest.php
@@ -31,7 +31,8 @@ public function setUp(): void
"lname" TEXT,
"password" TEXT NOT NULL,
"email" TEXT NOT NULL,
- "balance" INTEGER
+ "balance" INTEGER,
+ "active" INTEGER NOT NULL
);
');
@@ -63,7 +64,8 @@ public function setUp(): void
'lname' => 'Lennon',
'email' => 'john@test.com',
'password' => 'beatles',
- 'balance' => 200
+ 'balance' => 200,
+ 'active' => true,
]);
$this->database->table('users')->insert([
@@ -73,7 +75,8 @@ public function setUp(): void
'lname' => 'McCartney',
'email' => 'paul@test.com',
'password' => 'beatles',
- 'balance' => 150
+ 'balance' => 150,
+ 'active' => true,
]);
$this->database->table('users')->insert([
@@ -83,7 +86,8 @@ public function setUp(): void
'lname' => 'Harrison',
'email' => 'george@test.com',
'password' => 'beatles',
- 'balance' => 100
+ 'balance' => 100,
+ 'active' => false,
]);
$this->database->table('users')->insert([
@@ -93,7 +97,8 @@ public function setUp(): void
'lname' => 'Otto',
'email' => 'mark@test.com',
'password' => 'beatles',
- 'balance' => 50
+ 'balance' => 50,
+ 'active' => true,
]);
$this->database->table('users')->insert([
@@ -103,7 +108,8 @@ public function setUp(): void
'lname' => 'Bar',
'email' => 'foo@bar.com',
'password' => 'AND',
- 'balance' => -30
+ 'balance' => -30,
+ 'active' => false,
]);
}
@@ -475,6 +481,22 @@ public function testWhere()
$this->assertSame(4, $count);
+ // boolean comparison
+ $count = $this->database
+ ->table('users')
+ ->where('active = ?', [false])
+ ->count();
+
+ $this->assertSame(2, $count);
+
+ // boolean comparison
+ $count = $this->database
+ ->table('users')
+ ->where('active', '=', false)
+ ->count();
+
+ $this->assertSame(2, $count);
+
// like 1
$count = $this->database
->table('users')
From be4ccda9a59caf2a1762f512b73f47e8bcd5d6cb Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sun, 25 Feb 2024 11:02:46 +0000
Subject: [PATCH 118/202] Added test for update
---
tests/Database/DbTest.php | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/Database/DbTest.php b/tests/Database/DbTest.php
index 1420de34a3..df9dc7af04 100644
--- a/tests/Database/DbTest.php
+++ b/tests/Database/DbTest.php
@@ -253,6 +253,11 @@ public function testUpdate()
$this->assertTrue($result);
$this->assertSame('john@gmail.com', Db::row('users', '*', ['username' => 'john'])->email());
$this->assertSame('paul@test.com', Db::row('users', '*', ['username' => 'paul'])->email());
+
+ $result = Db::update('users', ['active' => false], ['username' => 'john']);
+ $this->assertTrue($result);
+ $this->assertSame('0', Db::row('users', '*', ['username' => 'john'])->active());
+ $this->assertSame('1', Db::row('users', '*', ['username' => 'paul'])->active());
}
/**
From c2813392cf109e375c17065d3f3a1aee81860cd2 Mon Sep 17 00:00:00 2001
From: Lukas Bestle
Date: Sun, 25 Feb 2024 13:08:55 +0100
Subject: [PATCH 119/202] Fix coding style
---
src/Database/Database.php | 2 +-
src/Database/Query.php | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/Database/Database.php b/src/Database/Database.php
index 736fabe137..9db17aed5d 100644
--- a/src/Database/Database.php
+++ b/src/Database/Database.php
@@ -320,7 +320,7 @@ protected function hit(string $query, array $bindings = []): bool
};
$this->statement->bindValue($parameter, $value, $type);
- }
+ }
$this->statement->execute();
$this->affected = $this->statement->rowCount();
diff --git a/src/Database/Query.php b/src/Database/Query.php
index f5daaae8ae..32b8c86647 100644
--- a/src/Database/Query.php
+++ b/src/Database/Query.php
@@ -828,13 +828,13 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
if ($args[0] === null) {
return $current;
- // ->where('username like "myuser"');
+ // ->where('username like "myuser"');
} elseif (is_string($args[0]) === true) {
// simply add the entire string to the where clause
// escaping or using bindings has to be done before calling this method
$result = $args[0];
- // ->where(['username' => 'myuser']);
+ // ->where(['username' => 'myuser']);
} elseif (is_array($args[0]) === true) {
// simple array mode (AND operator)
$sql = $this->database->sql()->values($this->table, $args[0], ' AND ', true, true);
@@ -868,7 +868,7 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
// store the bindings
$this->bindings($args[1]);
- // ->where('username like ?', 'myuser')
+ // ->where('username like ?', 'myuser')
} elseif (is_string($args[0]) === true && is_string($args[1]) === true) {
// prepared where clause
$result = $args[0];
@@ -906,14 +906,14 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
// add that to the where clause in parenthesis or seperated by AND
$values = match ($predicate) {
- 'IN',
+ 'IN',
'NOT IN' => '(' . implode(', ', $values) . ')',
- 'BETWEEN',
+ 'BETWEEN',
'NOT BETWEEN' => $values[0] . ' AND ' . $values[1]
};
$result = $key . ' ' . $predicate . ' ' . $values;
- // ->where('username', 'like', 'myuser');
+ // ->where('username', 'like', 'myuser');
} else {
$predicates = [
'=', '>=', '>', '<=', '<', '<>', '!=', '<=>',
From 2c4d163b8bdf0d44894da4330ff9aa496353de7b Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Sun, 25 Feb 2024 16:18:08 +0000
Subject: [PATCH 120/202] Adds support for non-string scalar values in a where
clause when using 2 arguments
---
src/Database/Query.php | 2 +-
tests/Database/QueryTest.php | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/Database/Query.php b/src/Database/Query.php
index 32b8c86647..1181b9880b 100644
--- a/src/Database/Query.php
+++ b/src/Database/Query.php
@@ -869,7 +869,7 @@ protected function filterQuery(array $args, $current, string $mode = 'AND')
$this->bindings($args[1]);
// ->where('username like ?', 'myuser')
- } elseif (is_string($args[0]) === true && is_string($args[1]) === true) {
+ } elseif (is_string($args[0]) === true && is_scalar($args[1]) === true) {
// prepared where clause
$result = $args[0];
diff --git a/tests/Database/QueryTest.php b/tests/Database/QueryTest.php
index 8f463bcd78..b080a9f336 100644
--- a/tests/Database/QueryTest.php
+++ b/tests/Database/QueryTest.php
@@ -481,6 +481,14 @@ public function testWhere()
$this->assertSame(4, $count);
+ // numeric comparison (2 arguments)
+ $count = $this->database
+ ->table('users')
+ ->where('balance > ?', 0)
+ ->count();
+
+ $this->assertSame(4, $count);
+
// boolean comparison
$count = $this->database
->table('users')
@@ -497,6 +505,14 @@ public function testWhere()
$this->assertSame(2, $count);
+ // boolean comparison (2 arguments)
+ $count = $this->database
+ ->table('users')
+ ->where('active = ?', false)
+ ->count();
+
+ $this->assertSame(2, $count);
+
// like 1
$count = $this->database
->table('users')
From b06df63bf89208862954f8fab81f1b53d5de12f3 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 25 Feb 2024 19:49:30 +0100
Subject: [PATCH 121/202] Update icons
---
panel/public/img/icons.svg | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/panel/public/img/icons.svg b/panel/public/img/icons.svg
index 86a3b63fc7..950867ee6e 100644
--- a/panel/public/img/icons.svg
+++ b/panel/public/img/icons.svg
@@ -86,7 +86,7 @@
-
+
@@ -126,8 +126,7 @@
-
-
+
@@ -151,7 +150,7 @@
-
+
@@ -175,8 +174,7 @@
-
-
+
From 52cd88f8219b99ba13ab984b15c02545a4191547 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 11:44:47 +0100
Subject: [PATCH 122/202] Add native validation to `range` input
---
panel/lab/components/inputs/alpha/index.vue | 2 +-
panel/lab/components/inputs/hue/index.vue | 2 +-
panel/lab/components/inputs/range/index.vue | 2 +-
.../src/components/Forms/Input/RangeInput.vue | 28 +++++++++++++++++++
4 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/panel/lab/components/inputs/alpha/index.vue b/panel/lab/components/inputs/alpha/index.vue
index a0f313a6a8..07a844916f 100644
--- a/panel/lab/components/inputs/alpha/index.vue
+++ b/panel/lab/components/inputs/alpha/index.vue
@@ -1,6 +1,6 @@
-
+
diff --git a/panel/lab/components/inputs/hue/index.vue b/panel/lab/components/inputs/hue/index.vue
index ed63e2d39c..dc503b98b3 100644
--- a/panel/lab/components/inputs/hue/index.vue
+++ b/panel/lab/components/inputs/hue/index.vue
@@ -1,6 +1,6 @@
-
+
diff --git a/panel/lab/components/inputs/range/index.vue b/panel/lab/components/inputs/range/index.vue
index 97ae7e8ce3..4ef004a12a 100644
--- a/panel/lab/components/inputs/range/index.vue
+++ b/panel/lab/components/inputs/range/index.vue
@@ -1,6 +1,6 @@
-
+
diff --git a/panel/src/components/Forms/Input/RangeInput.vue b/panel/src/components/Forms/Input/RangeInput.vue
index 131c9ef795..e17a9d6646 100644
--- a/panel/src/components/Forms/Input/RangeInput.vue
+++ b/panel/src/components/Forms/Input/RangeInput.vue
@@ -80,6 +80,8 @@ export const props = {
/**
* @example
+ *
+ * @todo remove vuelidate parts in v5 - until then we keep parrallel validation
*/
export default {
mixins: [Input, props],
@@ -89,6 +91,11 @@ export default {
// Otherwise place the baseline at the minimum
return this.min < 0 ? 0 : this.min;
},
+ isEmpty() {
+ return (
+ this.value === "" || this.value === undefined || this.value === null
+ );
+ },
label() {
return this.required || this.value || this.value === 0
? this.format(this.position)
@@ -103,10 +110,14 @@ export default {
watch: {
position() {
this.onInvalid();
+ },
+ value() {
+ this.validate();
}
},
mounted() {
this.onInvalid();
+ this.validate();
if (this.$props.autofocus) {
this.focus();
@@ -129,6 +140,23 @@ export default {
},
onInput(value) {
this.$emit("input", value);
+ },
+ validate() {
+ const errors = [];
+
+ if (this.required && this.isEmpty === true) {
+ errors.push(this.$t("error.validation.required"));
+ }
+
+ if (this.isEmpty === false && this.min && this.value < this.min) {
+ errors.push(this.$t("error.validation.min", { min: this.min }));
+ }
+
+ if (this.isEmpty === false && this.max && this.value > this.max) {
+ errors.push(this.$t("error.validation.max", { max: this.max }));
+ }
+
+ this.$refs.range?.setCustomValidity(errors.join(", "));
}
},
validations() {
From 1cb242fc60b4f24a4a4e0e26ef69106980b58449 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 25 Feb 2024 21:18:22 +0100
Subject: [PATCH 123/202] Fix header offset when no sticky header
Fixes #6283
---
panel/src/components/Drawers/Drawer.vue | 1 +
panel/src/components/Layout/Header.vue | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/panel/src/components/Drawers/Drawer.vue b/panel/src/components/Drawers/Drawer.vue
index abebbd1ca0..4f01adbfc3 100644
--- a/panel/src/components/Drawers/Drawer.vue
+++ b/panel/src/components/Drawers/Drawer.vue
@@ -78,6 +78,7 @@ export default {
.k-drawer {
--header-sticky-offset: calc(var(--drawer-body-padding) * -1);
+
z-index: var(--z-toolbar);
display: flex;
flex-basis: var(--drawer-width);
diff --git a/panel/src/components/Layout/Header.vue b/panel/src/components/Layout/Header.vue
index a2311d4169..1b2a6e8b66 100644
--- a/panel/src/components/Layout/Header.vue
+++ b/panel/src/components/Layout/Header.vue
@@ -93,7 +93,7 @@ export default {
:root {
--header-color-back: var(--color-light);
--header-padding-block: var(--spacing-4);
- --header-sticky-offset: calc(var(--scroll-top) + 4rem);
+ --header-sticky-offset: var(--scroll-top);
}
.k-header {
@@ -165,4 +165,7 @@ export default {
top: var(--scroll-top);
z-index: var(--z-toolbar);
}
+:root:has(.k-header[data-has-buttons="true"]) {
+ --header-sticky-offset: calc(var(--scroll-top) + 4rem);
+}
From 66947300b29ff130baf8df93cb45ab3846cdd713 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Mon, 26 Feb 2024 11:46:21 +0000
Subject: [PATCH 124/202] Improved column creation for tables. Adds support for
size on varchars, unsigned for integers, and floats and decimals.
---
src/Database/Sql.php | 33 ++++++++++++++-----
src/Database/Sql/Sqlite.php | 4 ++-
tests/Database/SqlTest.php | 65 +++++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/src/Database/Sql.php b/src/Database/Sql.php
index 136b394a86..c4e78a8b73 100644
--- a/src/Database/Sql.php
+++ b/src/Database/Sql.php
@@ -132,11 +132,13 @@ public function columnTypes(): array
{
return [
'id' => '{{ name }} INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
- 'varchar' => '{{ name }} varchar(255) {{ null }} {{ default }} {{ unique }}',
+ 'varchar' => '{{ name }} varchar({{ size }}) {{ null }} {{ default }} {{ unique }}',
'text' => '{{ name }} TEXT {{ unique }}',
- 'int' => '{{ name }} INT(11) UNSIGNED {{ null }} {{ default }} {{ unique }}',
+ 'int' => '{{ name }} INT(11) {{ unsigned }} {{ null }} {{ default }} {{ unique }}',
'timestamp' => '{{ name }} TIMESTAMP {{ null }} {{ default }} {{ unique }}',
- 'bool' => '{{ name }} TINYINT(1) {{ null }} {{ default }} {{ unique }}'
+ 'bool' => '{{ name }} TINYINT(1) {{ null }} {{ default }} {{ unique }}',
+ 'float' => '{{ name }} DOUBLE {{ null }} {{ default }} {{ unique }}',
+ 'decimal' => '{{ name }} DECIMAL({{ precision }}, {{ decimal_places }}) {{ null }} {{ default }} {{ unique }}'
];
}
@@ -157,6 +159,10 @@ public function combineIdentifier(string $table, string $column, bool $values =
* @param string $name Column name
* @param array $column Column definition array; valid keys:
* - `type` (required): Column template to use
+ * - `unsigned`: Whether an int column is signed or unsigned (boolean)
+ * - `size`: The size of varchar (int)
+ * - `precision`: The precision of a decimal type
+ * - `decimal_places`: The number of decimal places for a decimal type
* - `null`: Whether the column may be NULL (boolean)
* - `key`: Index this column is part of; special values `'primary'` for PRIMARY KEY and `true` for automatic naming
* - `unique`: Whether the index (or if not set the column itself) has a UNIQUE constraint
@@ -191,6 +197,13 @@ public function createColumn(string $name, array $column): array
}
}
+ // unsigned (defaults to true for backwards compatibility)
+ if (isset($column['unsigned']) === true && $column['unsigned'] === false) {
+ $unsigned = '';
+ } else {
+ $unsigned = 'UNSIGNED';
+ }
+
// unique
$uniqueKey = false;
$uniqueColumn = null;
@@ -208,11 +221,15 @@ public function createColumn(string $name, array $column): array
$columnDefault = $this->columnDefault($name, $column);
$query = trim(Str::template($template, [
- 'name' => $this->quoteIdentifier($name),
- 'null' => $null,
- 'default' => $columnDefault['query'],
- 'unique' => $uniqueColumn
- ], ['fallback' => '']));
+ 'name' => $this->quoteIdentifier($name),
+ 'unsigned' => $unsigned,
+ 'size' => $column['size'] ?? 255,
+ 'precision' => $column['precision'] ?? 14,
+ 'decimal_places' => $column['decimal_places'] ?? 4,
+ 'null' => $null,
+ 'default' => $columnDefault['query'],
+ 'unique' => $uniqueColumn
+ ], ['fallback' => '']));
return [
'query' => $query,
diff --git a/src/Database/Sql/Sqlite.php b/src/Database/Sql/Sqlite.php
index 05097a554b..fd737c0238 100644
--- a/src/Database/Sql/Sqlite.php
+++ b/src/Database/Sql/Sqlite.php
@@ -42,7 +42,9 @@ public function columnTypes(): array
'text' => '{{ name }} TEXT {{ null }} {{ default }} {{ unique }}',
'int' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
'timestamp' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
- 'bool' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}'
+ 'bool' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
+ 'float' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}',
+ 'decimal' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}'
];
}
diff --git a/tests/Database/SqlTest.php b/tests/Database/SqlTest.php
index 85fa1d6297..6199846748 100644
--- a/tests/Database/SqlTest.php
+++ b/tests/Database/SqlTest.php
@@ -358,6 +358,71 @@ public function testCreateTable()
$table['query']
);
$this->assertSame([], $table['bindings']);
+
+ // with varchar and size
+ $table = $this->sql->createTable('table', [
+ 'test' => ['type' => 'varchar', 'size' => 50],
+ 'another' => ['type' => 'varchar', 'size' => 100, 'null' => false]
+ ]);
+ $this->assertSame(
+ 'CREATE TABLE `table` (' . PHP_EOL .
+ '`test` varchar(50) NULL,' . PHP_EOL .
+ '`another` varchar(100) NOT NULL' . PHP_EOL .
+ ')',
+ $table['query']
+ );
+
+ // int type signed and unsigned
+ $table = $this->sql->createTable('table', [
+ 'test' => ['type' => 'int'],
+ 'another' => ['type' => 'int', 'unsigned' => false, 'null' => false]
+ ]);
+ $this->assertSame(
+ 'CREATE TABLE `table` (' . PHP_EOL .
+ '`test` INT(11) UNSIGNED NULL,' . PHP_EOL .
+ '`another` INT(11) NOT NULL' . PHP_EOL .
+ ')',
+ $table['query']
+ );
+
+ // float type
+ $table = $this->sql->createTable('table', [
+ 'test' => ['type' => 'float'],
+ 'another' => ['type' => 'float', 'null' => false]
+ ]);
+ $this->assertSame(
+ 'CREATE TABLE `table` (' . PHP_EOL .
+ '`test` DOUBLE NULL,' . PHP_EOL .
+ '`another` DOUBLE NOT NULL' . PHP_EOL .
+ ')',
+ $table['query']
+ );
+
+ // decimal type
+ $table = $this->sql->createTable('table', [
+ 'test' => ['type' => 'decimal'],
+ 'another' => ['type' => 'decimal', 'null' => false]
+ ]);
+ $this->assertSame(
+ 'CREATE TABLE `table` (' . PHP_EOL .
+ '`test` DECIMAL(14, 4) NULL,' . PHP_EOL .
+ '`another` DECIMAL(14, 4) NOT NULL' . PHP_EOL .
+ ')',
+ $table['query']
+ );
+
+ // decimal type with precision and decimal_places
+ $table = $this->sql->createTable('table', [
+ 'test' => ['type' => 'decimal', 'precision' => 10],
+ 'another' => ['type' => 'decimal', 'precision' => 12, 'decimal_places' => 2, 'null' => false]
+ ]);
+ $this->assertSame(
+ 'CREATE TABLE `table` (' . PHP_EOL .
+ '`test` DECIMAL(10, 4) NULL,' . PHP_EOL .
+ '`another` DECIMAL(12, 2) NOT NULL' . PHP_EOL .
+ ')',
+ $table['query']
+ );
}
/**
From c4f3d662b4f0b933cb7143435383cea2e7393926 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 26 Feb 2024 13:14:02 +0100
Subject: [PATCH 125/202] Refactor acceptAttribute in FileBlueprint class
---
src/Cms/FileBlueprint.php | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/src/Cms/FileBlueprint.php b/src/Cms/FileBlueprint.php
index 97fef9837c..6398fd2fbe 100644
--- a/src/Cms/FileBlueprint.php
+++ b/src/Cms/FileBlueprint.php
@@ -132,7 +132,6 @@ public function acceptMime(): string
* This behavior might change in the future to instead return the union of mime, extensions and types.
*
* @since 4.2.0
- * @return string
*/
public function acceptAttribute(): string
{
@@ -162,28 +161,25 @@ public function acceptAttribute(): string
// get extensions from "type" option
if (is_array($accept['type']) === true) {
$extensions = array_map(
- F::typeToExtensions(...),
+ fn($type) => F::typeToExtensions($type) ?? [],
$accept['type']
);
- // F::typeToExtensions might return null instead of empty arrays,
- // we need to filter those out
- $fromType = array_merge(...array_values(array_filter($extensions)));
+ $fromType = array_merge(...array_values($extensions));
$restrictions[] = $fromType;
}
// get extensions from "extension" option
if (is_array($accept['extension']) === true) {
- $fromExtension = $accept['extension'];
- $restrictions[] = $fromExtension;
+ $restrictions[] = $accept['extension'];
}
// intersect all restrictions
- if (count($restrictions) > 1) {
- $list = array_intersect(...$restrictions);
- } else {
- $list = $restrictions[0];
- }
+ $list = match (count($restrictions)) {
+ 0 => [],
+ 1 => $restrictions[0],
+ default => array_intersect(...$restrictions)
+ };
$list = array_unique($list);
From 341c8b5f05e6fa2b6c078c9ba15b9b5cb40d37c6 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 26 Feb 2024 13:14:56 +0100
Subject: [PATCH 126/202] Refactor toExtensions method of Mime class
---
src/Filesystem/Mime.php | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/Filesystem/Mime.php b/src/Filesystem/Mime.php
index 00accb8f45..fe614f6eb8 100644
--- a/src/Filesystem/Mime.php
+++ b/src/Filesystem/Mime.php
@@ -275,26 +275,26 @@ public static function toExtensions(string $mime = null, bool $matchWildcards =
$testMime = fn (string $v) => static::matches($v, $mime);
foreach (static::$types as $key => $value) {
- $isArray = is_array($value) === true;
-
- if ($matchWildcards === true) {
- if ($isArray === true && A::some($value, $testMime)) {
- $extensions[] = $key;
+ if (is_array($value) === true) {
+ if ($matchWildcards === true) {
+ if (A::some($value, $testMime)) {
+ $extensions[] = $key;
+ }
+ } else {
+ if (in_array($mime, $value) === true) {
+ $extensions[] = $key;
+ }
}
-
- if ($isArray === false && $testMime($value) === true) {
- $extensions[] = $key;
+ } else {
+ if ($matchWildcards === true) {
+ if($testMime($value) === true) {
+ $extensions[] = $key;
+ }
+ } else {
+ if ($value === $mime) {
+ $extensions[] = $key;
+ }
}
-
- continue;
- }
-
- if ($isArray === true && in_array($mime, $value) === true) {
- $extensions[] = $key;
- }
-
- if ($isArray === false && $value === $mime) {
- $extensions[] = $key;
}
}
From 552194950cf36191b731623c130f224a10ae134b Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 26 Feb 2024 13:16:42 +0100
Subject: [PATCH 127/202] Use DataProvider for testAcceptAttribute in
FileBlueprintTest
---
tests/Cms/Blueprints/FileBlueprintTest.php | 145 +++++++++------------
1 file changed, 60 insertions(+), 85 deletions(-)
diff --git a/tests/Cms/Blueprints/FileBlueprintTest.php b/tests/Cms/Blueprints/FileBlueprintTest.php
index 7f7029cc8a..c1cee60bdf 100644
--- a/tests/Cms/Blueprints/FileBlueprintTest.php
+++ b/tests/Cms/Blueprints/FileBlueprintTest.php
@@ -10,110 +10,85 @@
*/
class FileBlueprintTest extends TestCase
{
- protected ?Page $parent;
- protected array $acceptCases;
-
- protected function setUp(): void
- {
- $this->parent = Page::factory([
- 'slug' => 'test'
- ]);
-
- $this->acceptCases = [
- 'acceptWildcard' => [
- 'accept' => 'image/*',
- 'expected' => ['.jpg', '.jpeg', '.gif', '.png'],
- 'notExpected' => ['.js', '.pdf', '.docx', '.zip']
+ public static function acceptAttributeProvider() {
+ return [
+ [
+ 'wildcard', // case name
+ 'image/*', // accept option in blueprint
+ ['.jpg', '.jpeg', '.gif', '.png'], // expected extensions
+ ['.js', '.pdf', '.docx', '.zip'] // not expected extensions
],
- 'acceptMimeAsString' => [
- 'accept' => 'image/jpeg, image/png',
- 'expected' => ['.jpg', '.jpeg', '.png'],
- 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip']
+ [
+ 'mimeAsString',
+ 'image/jpeg, image/png',
+ ['.jpg', '.jpeg', '.png'],
+ ['.gif', '.js', '.pdf', '.docx', '.zip']
],
- 'acceptMimeAsProperty' => [
- 'accept' => [
- 'mime' => 'image/jpeg, image/png'
- ],
- 'expected' => ['.jpg', '.jpeg', '.png'],
- 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip']
+ [
+ 'mimeAsProperty',
+ ['mime' => 'image/jpeg, image/png'],
+ ['.jpg', '.jpeg', '.png'],
+ ['.gif', '.js', '.pdf', '.docx', '.zip']
],
- 'acceptExtensions' => [
- 'accept' => [
- 'extension' => 'jpg, png'
- ],
- 'expected' => ['.jpg', '.png'],
- 'notExpected' => ['.gif', '.jpeg', '.js', '.pdf', '.docx', '.zip']
+ [
+ 'extensions',
+ ['extension' => 'jpg, png'],
+ ['.jpg', '.png'],
+ ['.gif', '.jpeg', '.js', '.pdf', '.docx', '.zip']
],
- 'acceptExtensionsAndMime' => [
- 'accept' => [
- 'extension' => 'foo, bar', // when mime is present, extensions are ignored
- 'mime' => 'image/jpeg, image/png'
- ],
- 'expected' => ['.jpg', '.jpeg', '.png'],
- 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
+ [
+ 'extensionsAndMime',
+ ['extension' => 'foo, bar', 'mime' => 'image/jpeg, image/png'],
+ ['.jpg', '.jpeg', '.png'],
+ ['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
],
- 'acceptType' => [
- 'accept' => [
- 'type' => 'image'
- ],
- 'expected' => ['.jpg', '.jpeg', '.gif', '.png'],
- 'notExpected' => ['.js', '.pdf', '.docx', '.zip']
+ [
+ 'type',
+ ['type' => 'image'],
+ ['.jpg', '.jpeg', '.gif', '.png'],
+ ['.js', '.pdf', '.docx', '.zip']
],
- 'acceptTypeAndMime' => [
- 'accept' => [
- 'type' => 'document', // when mime is present, type is ignored
- 'mime' => 'image/jpeg, image/png'
- ],
- 'expected' => ['.jpg', '.jpeg', '.png'],
- 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip']
+ [
+ 'typeAndMime',
+ ['type' => 'document', 'mime' => 'image/jpeg, image/png'],
+ ['.jpg', '.jpeg', '.png'],
+ ['.gif', '.js', '.pdf', '.docx', '.zip']
],
- 'acceptInteresect' => [
- 'accept' => [
- 'type' => 'image',
- 'extension' => 'jpg, png, foo, bar', // foo bar should be ignored
- ],
- 'expected' => ['.jpg', '.png'],
- 'notExpected' => ['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
+ [
+ 'intersect',
+ ['type' => 'image', 'extension' => 'jpg, png, foo, bar'],
+ ['.jpg', '.png'],
+ ['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
],
];
- // set up the blueprint files
- foreach ($this->acceptCases as $name => $case) {
- Blueprint::$loaded['files/' . $name] = [
- 'accept' => $case['accept']
- ];
- }
- }
-
- protected function tearDown(): void
- {
- Blueprint::$loaded = [];
- $this->parent = null;
}
/**
* @covers ::acceptAttribute
+ * @dataProvider acceptAttributeProvider
*/
- public function testAcceptAttribute()
+ public function testAcceptAttribute($name, $accept, $expected, $notExpected)
{
- foreach ($this->acceptCases as $name => $case) {
- $file = new File([
- 'filename' => 'tmp',
- 'parent' => $this->parent,
- 'template' => $name
- ]);
- $acceptAttribute = $file->blueprint()->acceptAttribute();
+ Blueprint::$loaded['files/' . $name] = [
+ 'accept' => $accept
+ ];
- $expected = $case['expected'];
- $notExpected = $case['notExpected'];
+ $file = new File([
+ 'filename' => 'tmp',
+ 'parent' => $this->createMock(Page::class),
+ 'template' => $name
+ ]);
+ $acceptAttribute = $file->blueprint()->acceptAttribute();
- foreach ($expected as $extension) {
- $this->assertStringContainsString($extension, $acceptAttribute, "Case $name: $extension should be accepted");
- }
+ foreach ($expected as $extension) {
+ $this->assertStringContainsString($extension, $acceptAttribute, "Case $name: $extension should be accepted");
+ }
- foreach ($notExpected as $extension) {
- $this->assertStringNotContainsString($extension, $acceptAttribute, "Case $name: $extension should not be accepted");
- }
+ foreach ($notExpected as $extension) {
+ $this->assertStringNotContainsString($extension, $acceptAttribute, "Case $name: $extension should not be accepted");
}
+
+ unset(Blueprint::$loaded['files/' . $name]);
}
}
From 9d4041306938a5ef692443d729a5254aa2299c14 Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 26 Feb 2024 13:29:20 +0100
Subject: [PATCH 128/202] fix coding style
---
tests/Cms/Blueprints/FileBlueprintTest.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/Cms/Blueprints/FileBlueprintTest.php b/tests/Cms/Blueprints/FileBlueprintTest.php
index c1cee60bdf..f9aa88cc4e 100644
--- a/tests/Cms/Blueprints/FileBlueprintTest.php
+++ b/tests/Cms/Blueprints/FileBlueprintTest.php
@@ -10,7 +10,8 @@
*/
class FileBlueprintTest extends TestCase
{
- public static function acceptAttributeProvider() {
+ public static function acceptAttributeProvider()
+ {
return [
[
'wildcard', // case name
@@ -61,7 +62,6 @@ public static function acceptAttributeProvider() {
['.gif', '.js', '.pdf', '.docx', '.zip', '.foo', '.bar']
],
];
-
}
/**
@@ -79,6 +79,7 @@ public function testAcceptAttribute($name, $accept, $expected, $notExpected)
'parent' => $this->createMock(Page::class),
'template' => $name
]);
+
$acceptAttribute = $file->blueprint()->acceptAttribute();
foreach ($expected as $extension) {
From 73fc43d0323a4dce60bdbdfb5d54a12595d469bc Mon Sep 17 00:00:00 2001
From: Roman Steiner
Date: Mon, 26 Feb 2024 13:38:13 +0100
Subject: [PATCH 129/202] Fix coding style
---
src/Cms/FileBlueprint.php | 2 +-
src/Filesystem/Mime.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Cms/FileBlueprint.php b/src/Cms/FileBlueprint.php
index 6398fd2fbe..fc8bcf43a6 100644
--- a/src/Cms/FileBlueprint.php
+++ b/src/Cms/FileBlueprint.php
@@ -161,7 +161,7 @@ public function acceptAttribute(): string
// get extensions from "type" option
if (is_array($accept['type']) === true) {
$extensions = array_map(
- fn($type) => F::typeToExtensions($type) ?? [],
+ fn ($type) => F::typeToExtensions($type) ?? [],
$accept['type']
);
diff --git a/src/Filesystem/Mime.php b/src/Filesystem/Mime.php
index fe614f6eb8..5b839183b9 100644
--- a/src/Filesystem/Mime.php
+++ b/src/Filesystem/Mime.php
@@ -287,7 +287,7 @@ public static function toExtensions(string $mime = null, bool $matchWildcards =
}
} else {
if ($matchWildcards === true) {
- if($testMime($value) === true) {
+ if ($testMime($value) === true) {
$extensions[] = $key;
}
} else {
From 30adabd88adeeb6bb06cfe6b9dac987dc1baef29 Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Mon, 26 Feb 2024 19:24:01 +0000
Subject: [PATCH 130/202] Fix coding style
---
src/Database/Sql.php | 8 ++++----
src/Database/Sql/Sqlite.php | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Database/Sql.php b/src/Database/Sql.php
index c4e78a8b73..dd2145eb4a 100644
--- a/src/Database/Sql.php
+++ b/src/Database/Sql.php
@@ -159,10 +159,10 @@ public function combineIdentifier(string $table, string $column, bool $values =
* @param string $name Column name
* @param array $column Column definition array; valid keys:
* - `type` (required): Column template to use
- * - `unsigned`: Whether an int column is signed or unsigned (boolean)
- * - `size`: The size of varchar (int)
- * - `precision`: The precision of a decimal type
- * - `decimal_places`: The number of decimal places for a decimal type
+ * - `unsigned`: Whether an int column is signed or unsigned (boolean)
+ * - `size`: The size of varchar (int)
+ * - `precision`: The precision of a decimal type
+ * - `decimal_places`: The number of decimal places for a decimal type
* - `null`: Whether the column may be NULL (boolean)
* - `key`: Index this column is part of; special values `'primary'` for PRIMARY KEY and `true` for automatic naming
* - `unique`: Whether the index (or if not set the column itself) has a UNIQUE constraint
diff --git a/src/Database/Sql/Sqlite.php b/src/Database/Sql/Sqlite.php
index fd737c0238..fcb36b51a2 100644
--- a/src/Database/Sql/Sqlite.php
+++ b/src/Database/Sql/Sqlite.php
@@ -44,7 +44,7 @@ public function columnTypes(): array
'timestamp' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
'bool' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
'float' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}',
- 'decimal' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}'
+ 'decimal' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}'
];
}
From ba6f7c5a3517474dbf862d8b29d18d05d5da2ddb Mon Sep 17 00:00:00 2001
From: Ken Lynch
Date: Wed, 28 Feb 2024 09:55:14 +0000
Subject: [PATCH 131/202] Change option to camel case
---
src/Database/Sql.php | 6 +++---
tests/Database/SqlTest.php | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Database/Sql.php b/src/Database/Sql.php
index dd2145eb4a..f5829e24d1 100644
--- a/src/Database/Sql.php
+++ b/src/Database/Sql.php
@@ -138,7 +138,7 @@ public function columnTypes(): array
'timestamp' => '{{ name }} TIMESTAMP {{ null }} {{ default }} {{ unique }}',
'bool' => '{{ name }} TINYINT(1) {{ null }} {{ default }} {{ unique }}',
'float' => '{{ name }} DOUBLE {{ null }} {{ default }} {{ unique }}',
- 'decimal' => '{{ name }} DECIMAL({{ precision }}, {{ decimal_places }}) {{ null }} {{ default }} {{ unique }}'
+ 'decimal' => '{{ name }} DECIMAL({{ precision }}, {{ decimalPlaces }}) {{ null }} {{ default }} {{ unique }}'
];
}
@@ -162,7 +162,7 @@ public function combineIdentifier(string $table, string $column, bool $values =
* - `unsigned`: Whether an int column is signed or unsigned (boolean)
* - `size`: The size of varchar (int)
* - `precision`: The precision of a decimal type
- * - `decimal_places`: The number of decimal places for a decimal type
+ * - `decimalPlaces`: The number of decimal places for a decimal type
* - `null`: Whether the column may be NULL (boolean)
* - `key`: Index this column is part of; special values `'primary'` for PRIMARY KEY and `true` for automatic naming
* - `unique`: Whether the index (or if not set the column itself) has a UNIQUE constraint
@@ -225,7 +225,7 @@ public function createColumn(string $name, array $column): array
'unsigned' => $unsigned,
'size' => $column['size'] ?? 255,
'precision' => $column['precision'] ?? 14,
- 'decimal_places' => $column['decimal_places'] ?? 4,
+ 'decimalPlaces' => $column['decimalPlaces'] ?? 4,
'null' => $null,
'default' => $columnDefault['query'],
'unique' => $uniqueColumn
diff --git a/tests/Database/SqlTest.php b/tests/Database/SqlTest.php
index 6199846748..93eab61c57 100644
--- a/tests/Database/SqlTest.php
+++ b/tests/Database/SqlTest.php
@@ -411,10 +411,10 @@ public function testCreateTable()
$table['query']
);
- // decimal type with precision and decimal_places
+ // decimal type with precision and decimalPlaces
$table = $this->sql->createTable('table', [
'test' => ['type' => 'decimal', 'precision' => 10],
- 'another' => ['type' => 'decimal', 'precision' => 12, 'decimal_places' => 2, 'null' => false]
+ 'another' => ['type' => 'decimal', 'precision' => 12, 'decimalPlaces' => 2, 'null' => false]
]);
$this->assertSame(
'CREATE TABLE `table` (' . PHP_EOL .
From fafc29494b4d4a296b2590714dbdb32188e6c059 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Wed, 28 Feb 2024 11:08:15 +0100
Subject: [PATCH 132/202] Small design change for invalid examples
---
panel/src/components/Lab/PlaygroundView.vue | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/panel/src/components/Lab/PlaygroundView.vue b/panel/src/components/Lab/PlaygroundView.vue
index fc2a849b13..1abd8664b2 100644
--- a/panel/src/components/Lab/PlaygroundView.vue
+++ b/panel/src/components/Lab/PlaygroundView.vue
@@ -133,9 +133,8 @@ export default {
margin-top: var(--spacing-12);
}
-.k-lab-input-examples .k-lab-example-canvas:has(:invalid) {
+.k-lab-input-examples .k-lab-example:has(:invalid) {
outline: 2px solid var(--color-red-500);
- outline-offset: -2px;
}
.k-lab-input-examples-focus .k-lab-example-canvas > .k-button {
From b77d534236e53fcd31ea5243fbc407b47586e305 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 10 Feb 2024 13:26:43 +0100
Subject: [PATCH 133/202] Native validaty for `date`/`time` inputs
---
.../lab/components/inputs/calendar/index.vue | 2 +-
panel/lab/components/inputs/date/index.vue | 2 +-
panel/lab/components/inputs/time/index.vue | 6 +-
.../components/inputs/timeoptions/index.vue | 18 ++-
.../components/Forms/Input/CalendarInput.vue | 27 +---
.../src/components/Forms/Input/DateInput.vue | 118 +++++++++++-------
.../src/components/Forms/Input/TimeInput.vue | 40 +++---
.../Forms/Input/TimeoptionsInput.vue | 17 ++-
panel/src/libraries/dayjs-iso.js | 15 ++-
9 files changed, 154 insertions(+), 91 deletions(-)
diff --git a/panel/lab/components/inputs/calendar/index.vue b/panel/lab/components/inputs/calendar/index.vue
index 9d8d6d25b7..da679d0da7 100644
--- a/panel/lab/components/inputs/calendar/index.vue
+++ b/panel/lab/components/inputs/calendar/index.vue
@@ -1,6 +1,6 @@
-
+
-
+
diff --git a/panel/lab/components/inputs/time/index.vue b/panel/lab/components/inputs/time/index.vue
index fc83f677c6..135a233167 100644
--- a/panel/lab/components/inputs/time/index.vue
+++ b/panel/lab/components/inputs/time/index.vue
@@ -1,6 +1,6 @@
-
+
@@ -35,11 +35,11 @@
-
+
-
+
diff --git a/panel/lab/components/inputs/timeoptions/index.vue b/panel/lab/components/inputs/timeoptions/index.vue
index e317f1c689..42083e9f08 100644
--- a/panel/lab/components/inputs/timeoptions/index.vue
+++ b/panel/lab/components/inputs/timeoptions/index.vue
@@ -1,6 +1,6 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/panel/src/components/Forms/Input/CalendarInput.vue b/panel/src/components/Forms/Input/CalendarInput.vue
index 890dd4cdea..ade0108486 100644
--- a/panel/src/components/Forms/Input/CalendarInput.vue
+++ b/panel/src/components/Forms/Input/CalendarInput.vue
@@ -69,6 +69,8 @@
+
+
@@ -86,6 +88,7 @@
+
+
From 59fab4ed58d7960c561bbe097695678ea5cbf8f0 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 11 Jan 2024 18:50:52 +0100
Subject: [PATCH 137/202] Video block: fix for missing poster
---
config/blocks/video/video.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/blocks/video/video.php b/config/blocks/video/video.php
index 96d977ef1a..640bd26759 100644
--- a/config/blocks/video/video.php
+++ b/config/blocks/video/video.php
@@ -11,7 +11,7 @@
$url = $video->url();
$attrs = array_filter([
'controls' => true,
- 'poster' => $block->poster()->toFile()->url()
+ 'poster' => $block->poster()->toFile()?->url()
]);
} else {
$url = $block->url();
From 283e8b85c352e3363be97af1be8b7217c1519af2 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 11 Jan 2024 19:02:20 +0100
Subject: [PATCH 138/202] Video block: add fields for attributes
---
config/blocks/video/video.php | 8 ++++++--
config/blocks/video/video.yml | 32 ++++++++++++++++++++++++++++++++
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/config/blocks/video/video.php b/config/blocks/video/video.php
index 640bd26759..a1b1a316e1 100644
--- a/config/blocks/video/video.php
+++ b/config/blocks/video/video.php
@@ -10,8 +10,12 @@
) {
$url = $video->url();
$attrs = array_filter([
- 'controls' => true,
- 'poster' => $block->poster()->toFile()?->url()
+ 'autoplay' => $block->autoplay()->toBool(),
+ 'controls' => $block->controls()->toBool(),
+ 'loop' => $block->loop()->toBool(),
+ 'muted' => $block->muted()->toBool(),
+ 'poster' => $block->poster()->toFile()?->url(),
+ 'preload' => $block->preload()->value(),
]);
} else {
$url = $block->url();
diff --git a/config/blocks/video/video.yml b/config/blocks/video/video.yml
index 80ea99aa6e..b8882311bb 100644
--- a/config/blocks/video/video.yml
+++ b/config/blocks/video/video.yml
@@ -37,3 +37,35 @@ fields:
label: field.blocks.video.caption
type: writer
inline: true
+ autoplay:
+ type: toggle
+ width: 1/3
+ when:
+ location: kirby
+ muted:
+ type: toggle
+ width: 1/3
+ default: true
+ when:
+ location: kirby
+ loop:
+ type: toggle
+ width: 1/3
+ when:
+ location: kirby
+ controls:
+ type: toggle
+ width: 1/3
+ default: true
+ when:
+ location: kirby
+ preload:
+ type: select
+ width: 2/3
+ default: auto
+ options:
+ - auto
+ - metadata
+ - none
+ when:
+ location: kirby
From a5abdfdc625816be5f629afe358ebf2e97254c8d Mon Sep 17 00:00:00 2001
From: Ahmet Bora
Date: Mon, 22 Jan 2024 14:25:11 +0300
Subject: [PATCH 139/202] Add translation strings for the new video fields
---
config/blocks/video/video.yml | 9 ++++++++-
i18n/translations/en.json | 7 +++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/config/blocks/video/video.yml b/config/blocks/video/video.yml
index b8882311bb..b5fc104611 100644
--- a/config/blocks/video/video.yml
+++ b/config/blocks/video/video.yml
@@ -3,7 +3,7 @@ icon: video
preview: video
fields:
location:
- label: field.blocks.image.location
+ label: field.blocks.video.location
type: radio
columns: 2
default: "web"
@@ -17,6 +17,7 @@ fields:
when:
location: web
video:
+ label: field.blocks.video.name
type: files
query: model.videos
multiple: false
@@ -24,6 +25,7 @@ fields:
when:
location: kirby
poster:
+ label: field.blocks.video.poster
type: files
query: model.images
multiple: false
@@ -38,28 +40,33 @@ fields:
type: writer
inline: true
autoplay:
+ label: field.blocks.video.autoplay
type: toggle
width: 1/3
when:
location: kirby
muted:
+ label: field.blocks.video.muted
type: toggle
width: 1/3
default: true
when:
location: kirby
loop:
+ label: field.blocks.video.loop
type: toggle
width: 1/3
when:
location: kirby
controls:
+ label: field.blocks.video.controls
type: toggle
width: 1/3
default: true
when:
location: kirby
preload:
+ label: field.blocks.video.preload
type: select
width: 2/3
default: auto
diff --git a/i18n/translations/en.json b/i18n/translations/en.json
index a2fe216281..5fa13376d9 100644
--- a/i18n/translations/en.json
+++ b/i18n/translations/en.json
@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
+ "field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
+ "field.blocks.video.controls": "Controls",
+ "field.blocks.video.location": "Location",
+ "field.blocks.video.loop": "Loop",
+ "field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
+ "field.blocks.video.poster": "Poster",
+ "field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",
From eed3bdbfc4a964a9f1b1da22142bbd74790b54ba Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 24 Feb 2024 22:22:55 +0100
Subject: [PATCH 140/202] Video block: fix preview order
---
panel/src/components/Forms/Blocks/Types/Video.vue | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/panel/src/components/Forms/Blocks/Types/Video.vue b/panel/src/components/Forms/Blocks/Types/Video.vue
index 16b0f49fbe..7fa1f05aaa 100644
--- a/panel/src/components/Forms/Blocks/Types/Video.vue
+++ b/panel/src/components/Forms/Blocks/Types/Video.vue
@@ -47,15 +47,11 @@ export default {
return this.content.poster?.[0]?.url;
},
video() {
- if (this.content.location === "web") {
- return this.$helper.embed.video(this.content.url ?? "", true);
+ if (this.content.location === "kirby") {
+ return this.content.video?.[0]?.url;
}
- if (this.content.video?.[0]?.url) {
- return this.content.video[0].url;
- }
-
- return null;
+ return this.$helper.embed.video(this.content.url ?? "", true);
}
}
};
From 571127a4c3cd7edc4c44df1337af990764da5d43 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 24 Feb 2024 19:06:11 +0100
Subject: [PATCH 141/202] Lab: more `$helper` docs
---
panel/lab/internals/helpers/color/index.vue | 54 +++++-
panel/lab/internals/helpers/embed/index.vue | 112 +++++++++++-
panel/lab/internals/helpers/file/index.vue | 92 +++++++++-
.../internals/helpers/isComponent/index.vue | 37 +++-
.../internals/helpers/isUploadEvent/index.vue | 17 +-
.../lab/internals/helpers/keyboard/index.vue | 25 ++-
panel/lab/internals/helpers/page/index.vue | 13 --
panel/lab/internals/helpers/ratio/index.vue | 57 +++++-
panel/lab/internals/helpers/url/index.vue | 160 +++++++++++++++-
panel/lab/internals/library.colors/index.vue | 172 +++++++++++++-----
panel/src/helpers/file.js | 3 +-
panel/src/helpers/page.js | 8 +
panel/src/helpers/ratio.js | 2 +-
panel/src/helpers/url.js | 6 +-
panel/src/libraries/colors.js | 6 +-
15 files changed, 662 insertions(+), 102 deletions(-)
delete mode 100644 panel/lab/internals/helpers/page/index.vue
diff --git a/panel/lab/internals/helpers/color/index.vue b/panel/lab/internals/helpers/color/index.vue
index 8fb2c60a13..3165414b1e 100644
--- a/panel/lab/internals/helpers/color/index.vue
+++ b/panel/lab/internals/helpers/color/index.vue
@@ -1,13 +1,53 @@
-
- These docs are still work in progress and will be added soon
+
+ For parsing, formating and converting color values, you can use
+ $library.colors
+
+
+
+ Resolves color alias to proper CSS values:
+
+ this.$helper.color(alias): string
+
+
+
+
+ Input
+ this.$helper.color("Pattern")
+
+
+ Result
+ {{ $helper.color("Pattern") }}
+
+
+ this.$helper.color("purple")
+
+
+ {{ $helper.color("purple") }}
+
+
+ this.$helper.color("purple-500")
+
+
+ {{ $helper.color("purple-500") }}
+
+
+ this.$helper.color("#ff00ff")
+
+
+ {{ $helper.color("#ff00ff") }}
+
+
+
-
+
\ No newline at end of file
diff --git a/panel/lab/internals/helpers/embed/index.vue b/panel/lab/internals/helpers/embed/index.vue
index 8fb2c60a13..61fb087957 100644
--- a/panel/lab/internals/helpers/embed/index.vue
+++ b/panel/lab/internals/helpers/embed/index.vue
@@ -1,13 +1,119 @@
-
- These docs are still work in progress and will be added soon
+
+
+ Access the following embed helpers in your Vue components through
+ this.$helper.embed
+
+
+
+
+ Builds a YouTube embed URL:
+
+ this.$helper.embed.youtube(url, doNotTrack): string|false
+
+
+
+
+
+ Input
+
+
+
+
+ Result
+ {{ $helper.embed.youtube(youtube, youtubeNotTrack) }}
+
+
+
+
+
+
+
+ Builds a Vimeo embed URL:
+
+ this.$helper.embed.vimeo(url, doNotTrack): string|false
+
+
+
+
+
+ Input
+
+
+
+
+ Result
+ {{ $helper.embed.vimeo(vimeo, vimeoNotTrack) }}
+
+
+
+
+
+
+
+ Builds an embed URL for the given video URL:
+
+ this.$helper.embed.video(url, doNotTrack): string|false
+
+
+
+
+
+ Input
+ {{ youtube }}
+
+
+ Result
+ {{ $helper.embed.video(youtube, youtubeNotTrack) }}
+
+
+ {{ vimeo }}
+
+
+ {{ $helper.embed.video(vimeo, vimeoNotTrack) }}
+
+
+
+
diff --git a/panel/lab/internals/helpers/file/index.vue b/panel/lab/internals/helpers/file/index.vue
index 8fb2c60a13..bbf02b40d1 100644
--- a/panel/lab/internals/helpers/file/index.vue
+++ b/panel/lab/internals/helpers/file/index.vue
@@ -1,13 +1,99 @@
-
- These docs are still work in progress and will be added soon
+
+
+ Access the following file helpers in your Vue components through
+ this.$helper.file
+
+
+
+
+ Extracts the extension:
+
+ this.$helper.file.extension(filename): string
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.file.extension(filename) }}
+
+
+
+
+
+
+
+ Extracts the name without extension:
+
+ this.$helper.file.name(filename): string
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.file.name(filename) }}
+
+
+
+
+
+
+
+ Creates a nice human-readable file size string with size unit:
+
+ this.$helper.file.niceSize(size): string
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.file.niceSize(size) }}
+
+
+
+
diff --git a/panel/lab/internals/helpers/isComponent/index.vue b/panel/lab/internals/helpers/isComponent/index.vue
index 8fb2c60a13..e8966c3f7c 100644
--- a/panel/lab/internals/helpers/isComponent/index.vue
+++ b/panel/lab/internals/helpers/isComponent/index.vue
@@ -1,13 +1,42 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+ Checks if the coponent is registered globally:
+
+ this.$helper.isComponent(name): boolean
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{
+ $helper.isComponent(component)
+ }}
+
+
+
+
diff --git a/panel/lab/internals/helpers/isUploadEvent/index.vue b/panel/lab/internals/helpers/isUploadEvent/index.vue
index 8fb2c60a13..5ad0b62371 100644
--- a/panel/lab/internals/helpers/isUploadEvent/index.vue
+++ b/panel/lab/internals/helpers/isUploadEvent/index.vue
@@ -1,13 +1,12 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+ Checks if provided event is an upload-related event:
+
+
+ this.$helper.isUploadEvent(event): boolean
+
+
-
-
diff --git a/panel/lab/internals/helpers/keyboard/index.vue b/panel/lab/internals/helpers/keyboard/index.vue
index 8fb2c60a13..553587212c 100644
--- a/panel/lab/internals/helpers/keyboard/index.vue
+++ b/panel/lab/internals/helpers/keyboard/index.vue
@@ -1,13 +1,22 @@
-
- These docs are still work in progress and will be added soon
+
+
+ Access the following keyboard helpers in your Vue components through
+ this.$helper.keyboard
+
+
+
+
+ Returns name of meta key for current OS:
+
+
+ this.$helper.keyboard.metaKey(): string
+
+
+ Result
+ {{ $helper.keyboard.metaKey() }}
+
-
-
diff --git a/panel/lab/internals/helpers/page/index.vue b/panel/lab/internals/helpers/page/index.vue
deleted file mode 100644
index 8fb2c60a13..0000000000
--- a/panel/lab/internals/helpers/page/index.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- These docs are still work in progress and will be added soon
-
-
-
-
-
diff --git a/panel/lab/internals/helpers/ratio/index.vue b/panel/lab/internals/helpers/ratio/index.vue
index 8fb2c60a13..192d9869ac 100644
--- a/panel/lab/internals/helpers/ratio/index.vue
+++ b/panel/lab/internals/helpers/ratio/index.vue
@@ -1,13 +1,62 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+ Returns a percentage string for the provided fraction:
+
+
+ this.$helper.ratio(fraction, fallback, vertical): string
+
+
+
+
+
+ Input
+
+
+
+ Result
+
+ {{ ratio }}
+
+
+
+
+
+
+
diff --git a/panel/lab/internals/helpers/url/index.vue b/panel/lab/internals/helpers/url/index.vue
index 8fb2c60a13..8e2260e44d 100644
--- a/panel/lab/internals/helpers/url/index.vue
+++ b/panel/lab/internals/helpers/url/index.vue
@@ -1,13 +1,167 @@
-
- These docs are still work in progress and will be added soon
+
+
+ Access the following url helpers in your Vue components through
+ this.$helper.url
+
+
+
+
+ Returns the base URL from the <base> element:
+ this.$helper.url.base(): string
+
+
+
+ Result
+ {{ $helper.url.base() }}
+
+
+
+
+
+
+ Turns the given object into an URL query string and appends it, if
+ given, to the query of the origin:
+
+
+ this.$helper.url.buildQuery(query, origin): string
+
+
+
+
+
+ Input
+ {{ query }}
+
+ {{ origin }}
+
+
+ Result
+ {{ $helper.url.buildQuery(query, origin) }}
+
+
+
+
+
+
+
+
+ Builds a full URL object based on the given path or another URL object
+ and query data:
+
+
+ this.$helper.url.buildUrl(url, query, origin): string
+
+
+
+
+
+ Input
+
+
+ {{ query }}
+
+
+ Result
+ {{ $helper.url.buildUrl(url, query) }}
+
+
+
+
+
+
+
+ Checks if the url string is absolute:
+
+ this.$helper.url.isAbsolute(url): boolean
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.url.isAbsolute(url) }}
+
+
+
+
+
+
+
+ Checks if the url is on the same origin:
+
+ this.$helper.url.isSameOrigin(url): boolean
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.url.isSameOrigin(url) }}
+
+
+
+
+
+
+
+ Checks if the given argument is a URL:
+
+ this.$helper.url.isUrl(url): boolean
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.url.isUrl(url) }}
+
+
+
+
diff --git a/panel/lab/internals/library.colors/index.vue b/panel/lab/internals/library.colors/index.vue
index b8ef3ccfca..3f89a67889 100644
--- a/panel/lab/internals/library.colors/index.vue
+++ b/panel/lab/internals/library.colors/index.vue
@@ -1,62 +1,126 @@
-
+
+
+
+
+ Kirby provides at $library.colors
several methods to parse, format and convert colors in HEX, RGB and HSL formats.
+
+
+
+
+
-
-
-
-
+
+
+ Tries to parse a string as HEX, RGB or HSL color
+
+
- →
+ this.$library.colors.parse(string)
- {{ parsed ?? "{}" }}
-
-
-
+
+
+
+
+
+
+ {{ parsed ?? "{}" }}
+
+
+
-
-
-
-
+
+
+ Parses the input string and coverts it (if necessary) to the target color space
+
+
- →
+ this.$library.colors.parseAs(string, format)
-
+
+
+
+
+
+
+
+ {{ parsedAs || "{}" }}
+
+
+
+
+
+
+
+
+ Formats color as CSS string.
+
+
- →
+ this.$library.colors.toString(color, format, alpha)
- {{ parsedAs || "{}" }}
-
-
-
+
+
+ Input
+ {{ color }}
+
+
+ Format
+
+
+
+
+ Result
+ {{
+ $library.colors.toString(color, stringFormat, stringAlpha)
+ }}
+
+
@@ -69,9 +133,21 @@ export default {
value: null,
parsedAs: null,
valueAs: null,
- parseAsFormat: "hex"
+ parseAsFormat: "hex",
+ stringFormat: "hex",
+ stringAlpha: true
};
},
+ computed: {
+ color() {
+ return {
+ r: 100,
+ g: 200,
+ b: 255,
+ a: 0.5
+ };
+ }
+ },
methods: {
parse(value) {
this.value = value;
@@ -84,3 +160,17 @@ export default {
}
};
+
+
diff --git a/panel/src/helpers/file.js b/panel/src/helpers/file.js
index 2715269d1f..5ab9c6c490 100644
--- a/panel/src/helpers/file.js
+++ b/panel/src/helpers/file.js
@@ -19,8 +19,7 @@ export const name = (filename) => {
};
/**
- * Creates a nice human-readable file size string
- * with size unit
+ * Creates a nice human-readable file size string with size unit
*
* @param {Number} size
* @returns {String}
diff --git a/panel/src/helpers/page.js b/panel/src/helpers/page.js
index 05ab70956f..8913549b51 100644
--- a/panel/src/helpers/page.js
+++ b/panel/src/helpers/page.js
@@ -1,3 +1,11 @@
+/**
+ * Returns props for a page status button
+ * @internal
+ *
+ * @param {string} status
+ * @param {boolean} disabled
+ * @returns {object}
+ */
export function status(status, disabled = false) {
const button = {
class: "k-status-icon",
diff --git a/panel/src/helpers/ratio.js b/panel/src/helpers/ratio.js
index f475d8a49e..415bb864b1 100644
--- a/panel/src/helpers/ratio.js
+++ b/panel/src/helpers/ratio.js
@@ -1,5 +1,5 @@
/**
- * Returns a percentage string fro the provided fraction
+ * Returns a percentage string for the provided fraction
*
* @param {String} fraction fraction to convert to a percentage
* @param {String} fallback default value if fraction cannot be parsed
diff --git a/panel/src/helpers/url.js b/panel/src/helpers/url.js
index 27ec4aa8c2..378a68f39c 100644
--- a/panel/src/helpers/url.js
+++ b/panel/src/helpers/url.js
@@ -1,5 +1,6 @@
/**
* Returns the base URL from the element
+ *
* @since 4.0.0
* @returns {URL}
*/
@@ -10,6 +11,9 @@ export function base() {
}
/**
+ * Turns the given object into an URL query string
+ * and appends it, if given, to the query of the origin
+ *
* @since 4.0.0
* @param {object} query
* @param {string|URL} origin
@@ -142,8 +146,8 @@ export function toObject(url, origin) {
export default {
base,
- buildUrl,
buildQuery,
+ buildUrl,
isAbsolute,
isSameOrigin,
isUrl,
diff --git a/panel/src/libraries/colors.js b/panel/src/libraries/colors.js
index cfdecd73c1..fb191652b7 100644
--- a/panel/src/libraries/colors.js
+++ b/panel/src/libraries/colors.js
@@ -88,12 +88,11 @@ export function convert(color, format) {
}
/**
- * Tries to parse a string as HEX, RGB or HSL
- * color and returns an object with type, string and values
+ * Tries to parse a string as HEX, RGB or HSL color
* @since 4.0.0
*
* @param {string} string
- * @returns {object|null}
+ * @returns {object|string|null}
*/
export function parse(string) {
let values;
@@ -182,6 +181,7 @@ export function parseAs(string, format) {
*
* @param {object|string} color
* @param {string} format hex, rgb, hsl or hsv
+ * @param {boolean} alpha
* @returns {string}
*/
export function toString(color, format, alpha = true) {
From 0aea00d9a2c9ee0ca262ea9a2f78b3115c8a4bf5 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 24 Feb 2024 19:09:39 +0100
Subject: [PATCH 142/202] Lab: finalize `$helper.url` docs
---
panel/lab/internals/helpers/url/index.vue | 41 ++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/panel/lab/internals/helpers/url/index.vue b/panel/lab/internals/helpers/url/index.vue
index 8e2260e44d..eb33266d03 100644
--- a/panel/lab/internals/helpers/url/index.vue
+++ b/panel/lab/internals/helpers/url/index.vue
@@ -133,6 +133,35 @@
+
+
+
+ Make sure the URL is absolute:
+
+ this.$helper.url.makeAbsolute(path): string
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.url.makeAbsolute(absolute) }}
+
+
+
+
+
+
+
+ Converts any given url to a URL object:
+
+ this.$helper.url.toObject(url, origin): URL
+
+
@@ -161,7 +190,17 @@ export const query = {
};
/** @script-end */
+/** @script: absolute */
+export const absolute = {
+ data() {
+ return {
+ absolute: "docs"
+ };
+ }
+};
+/** @script-end */
+
export default {
- mixins: [url, query]
+ mixins: [url, query, absolute]
};
From dc582afd1dd7be67a96e9f291e5fe99f7184c9d9 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 17:58:46 +0100
Subject: [PATCH 143/202] Lab `$helper.debounce` docs
---
panel/lab/internals/helpers/debounce/index.vue | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/panel/lab/internals/helpers/debounce/index.vue b/panel/lab/internals/helpers/debounce/index.vue
index 8fb2c60a13..d5dcb40699 100644
--- a/panel/lab/internals/helpers/debounce/index.vue
+++ b/panel/lab/internals/helpers/debounce/index.vue
@@ -1,13 +1,13 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+ Debounces the callback function:
+
+
+ const original = (a, b) => {};
+const debounced = this.$helper.debounce(original, 500);
+
+
-
-
From 65f7665bb6b145d0de34a3536bfb6b6c66e0783a Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 17:59:09 +0100
Subject: [PATCH 144/202] Lab `RegExp.escape()` docs
---
panel/lab/internals/helpers/regex/index.vue | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/panel/lab/internals/helpers/regex/index.vue b/panel/lab/internals/helpers/regex/index.vue
index 8fb2c60a13..8815a770f4 100644
--- a/panel/lab/internals/helpers/regex/index.vue
+++ b/panel/lab/internals/helpers/regex/index.vue
@@ -1,13 +1,11 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+ Escapes a string to be used in a regular expression:
+
+ RegExp.escape(string)
+
+
-
-
From 41793215158e16239ab2f278ac22e69b5c881209 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 17:59:35 +0100
Subject: [PATCH 145/202] Make `$helper.field` functions internal
---
panel/lab/internals/helpers/field/index.php | 5 -----
panel/lab/internals/helpers/field/index.vue | 13 -------------
panel/src/helpers/field.js | 6 ++++++
3 files changed, 6 insertions(+), 18 deletions(-)
delete mode 100644 panel/lab/internals/helpers/field/index.php
delete mode 100644 panel/lab/internals/helpers/field/index.vue
diff --git a/panel/lab/internals/helpers/field/index.php b/panel/lab/internals/helpers/field/index.php
deleted file mode 100644
index 703c05b110..0000000000
--- a/panel/lab/internals/helpers/field/index.php
+++ /dev/null
@@ -1,5 +0,0 @@
- 'panel/src/helpers/field.js'
-];
diff --git a/panel/lab/internals/helpers/field/index.vue b/panel/lab/internals/helpers/field/index.vue
deleted file mode 100644
index 8fb2c60a13..0000000000
--- a/panel/lab/internals/helpers/field/index.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- These docs are still work in progress and will be added soon
-
-
-
-
-
diff --git a/panel/src/helpers/field.js b/panel/src/helpers/field.js
index 35667b4952..ee7f6d741e 100644
--- a/panel/src/helpers/field.js
+++ b/panel/src/helpers/field.js
@@ -1,5 +1,7 @@
/**
* Loads the default value for a field definition
+ * @internal
+ *
* @param {Object} field
* @returns {mixed}
*/
@@ -35,6 +37,8 @@ export function defaultValue(field) {
/**
* Creates form values for provided fields
+ * @internal
+ *
* @param {Object} fields
* @returns {Object}
*/
@@ -55,6 +59,7 @@ export function form(fields) {
/**
* Checks if a form field is visible based on its "when" conditions
* and the current form values. Also works for sections.
+ * @internal
*
* @param {Object} field - The form field object
* @param {Object} values - The current form values object
@@ -92,6 +97,7 @@ export function isVisible(field, values) {
/**
* Adds proper endpoint and section definitions
* to subfields for a form field.
+ * @internal
*
* @param {object} field
* @param {object} fields
From 8fe628e1049215d44652c26e9c75f81fb52371c8 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 18:02:55 +0100
Subject: [PATCH 146/202] Lab: remove helper focus placeholder
---
panel/lab/internals/helpers/focus/index.php | 5 -----
panel/lab/internals/helpers/focus/index.vue | 13 -------------
2 files changed, 18 deletions(-)
delete mode 100644 panel/lab/internals/helpers/focus/index.php
delete mode 100644 panel/lab/internals/helpers/focus/index.vue
diff --git a/panel/lab/internals/helpers/focus/index.php b/panel/lab/internals/helpers/focus/index.php
deleted file mode 100644
index ce90f570bf..0000000000
--- a/panel/lab/internals/helpers/focus/index.php
+++ /dev/null
@@ -1,5 +0,0 @@
- 'panel/src/helpers/focus.js'
-];
diff --git a/panel/lab/internals/helpers/focus/index.vue b/panel/lab/internals/helpers/focus/index.vue
deleted file mode 100644
index 8fb2c60a13..0000000000
--- a/panel/lab/internals/helpers/focus/index.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- These docs are still work in progress and will be added soon
-
-
-
-
-
From 9ee28d392d1f0437ed90ea865c8cbf2a8ae94068 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 19:04:50 +0100
Subject: [PATCH 147/202] Lab `$helper.link` docs
---
panel/lab/internals/helpers/link/index.vue | 94 +++++++++++++++++++++-
panel/src/helpers/link.js | 32 ++++++++
2 files changed, 123 insertions(+), 3 deletions(-)
diff --git a/panel/lab/internals/helpers/link/index.vue b/panel/lab/internals/helpers/link/index.vue
index 8fb2c60a13..04033fb0e9 100644
--- a/panel/lab/internals/helpers/link/index.vue
+++ b/panel/lab/internals/helpers/link/index.vue
@@ -1,13 +1,101 @@
-
- These docs are still work in progress and will be added soon
+
+
+ Access the following link helpers in your Vue components through
+ this.$helper.link
+
+
+
+
+ Detects the type of a link:
+
+ this.$helper.link.detect(link): object
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ $helper.link.detect(detect) }}
+
+
+
+
+
+
+
+ Returns preview data for the link:
+
+ this.$helper.link.preview(link): object
+
+
+
+
+
+ Input
+
+
+
+ Result
+ {{ previewResult }}
+
+
+
+
+
+
+
+ Returns default types:
+
+ this.$helper.link.types(keys): object
+
+
+
+ Result
+ {{ $helper.link.types() }}
+
+
diff --git a/panel/src/helpers/link.js b/panel/src/helpers/link.js
index baa5e7f512..db7d97d22b 100644
--- a/panel/src/helpers/link.js
+++ b/panel/src/helpers/link.js
@@ -1,3 +1,9 @@
+/**
+ * Detects the type of a link
+ * @param {String} value
+ * @param {Object} _types Custom types, otherwise default types are used
+ * @returns {Object}
+ */
export function detect(value, _types) {
value = value ?? "";
_types = _types ?? types();
@@ -19,14 +25,29 @@ export function detect(value, _types) {
}
}
+/**
+ * Converts file permalink to file UUID
+ * @param {String} value
+ * @returns {String}
+ */
export function getFileUUID(value) {
return value.replace("/@/file/", "file://");
}
+/**
+ * Converts page permalink to page UUID
+ * @param {String} value
+ * @returns {String}
+ */
export function getPageUUID(value) {
return value.replace("/@/page/", "page://");
}
+/**
+ * Checks if string is a file UUID or permalink
+ * @param {String} value
+ * @returns {Boolean}
+ */
export function isFileUUID(value) {
return (
value.startsWith("file://") === true ||
@@ -34,6 +55,11 @@ export function isFileUUID(value) {
);
}
+/**
+ * Checks if string is a file UUID or permalink
+ * @param {String} value
+ * @returns {Boolean}
+ */
export function isPageUUID(value) {
return (
value === "site://" ||
@@ -42,6 +68,12 @@ export function isPageUUID(value) {
);
}
+/**
+ * Returns preview data for the link
+ * @param {Object} { type, link }
+ * @param {Array} fields
+ * @returns
+ */
export async function preview({ type, link }, fields) {
if (type === "page" && link) {
return await previewForPage(link, fields);
From 38f34b6217e5773a9f1a05c594c48e7590c33ff5 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 19:17:25 +0100
Subject: [PATCH 148/202] Lab: `$object` docs
---
panel/lab/internals/helpers/object/index.vue | 237 ++++++++++++++++++-
panel/src/helpers/object.js | 2 +-
2 files changed, 230 insertions(+), 9 deletions(-)
diff --git a/panel/lab/internals/helpers/object/index.vue b/panel/lab/internals/helpers/object/index.vue
index 8fb2c60a13..6804737d27 100644
--- a/panel/lab/internals/helpers/object/index.vue
+++ b/panel/lab/internals/helpers/object/index.vue
@@ -1,13 +1,234 @@
-
- These docs are still work in progress and will be added soon
+
+
+ Access the following object helpers in your Vue components through
+ this.$helper.object
+
+
+
+
+ Checks if value is empty:
+
+ this.$helper.object.isEmpty(value): boolean
+
+
+
+
+
+ Input
+ ""
+
+
+ Result
+ {{
+ $helper.object.isEmpty("")
+ }}
+
+
+ null
+
+
+ {{
+ $helper.object.isEmpty(null)
+ }}
+
+
+ undefined
+
+
+ {{
+ $helper.object.isEmpty(undefined)
+ }}
+
+
+ {}
+
+
+ {{
+ $helper.object.isEmpty({})
+ }}
+
+
+ { foo: "bar" }
+
+
+ {{
+ $helper.object.isEmpty({ foo: "bar" })
+ }}
+
+
+ []
+
+
+ {{
+ $helper.object.isEmpty([])
+ }}
+
+
+ ["foo", "bar"]
+
+
+ {{
+ $helper.object.isEmpty(["foo", "bar"])
+ }}
+
+
+
+
+
+
+
+ Checks if input is an object:
+
+ this.$helper.object.isObject(value): boolean
+
+
+
+
+
+ Input
+ null
+
+
+ Result
+ {{
+ $helper.object.isObject(null)
+ }}
+
+
+ {}
+
+
+ {{
+ $helper.object.isObject({})
+ }}
+
+
+ { foo: "bar" }
+
+
+ {{
+ $helper.object.isObject({ foo: "bar" })
+ }}
+
+
+ ["foo", "bar"]
+
+
+ {{
+ $helper.object.isObject(["foo", "bar"])
+ }}
+
+
+
+
+
+
+
+ Counts all keys in the object:
+
+ this.$helper.object.length(object): int
+
+
+
+
+
+ Input
+ {}
+
+
+ Result
+ {{ $helper.object.length({}) }}
+
+
+ { foo: "bar", baz: "qux" }
+
+
+ {{
+ $helper.object.length({ foo: "bar", baz: "qux" })
+ }}
+
+
+
+
+
+
+
+ Merges two objects:
+
+ this.$helper.object.merge(target, source): object
+
+
+
+
+
+ Input
+ { foo: "bar"}, { baz: "qux" }
+
+
+ Result
+ {{
+ $helper.object.merge({ foo: "bar" }, { baz: "qux" })
+ }}
+
+
+
+
+
+
+
+ Check if the objects are identical:
+
+ this.$helper.object.same(a, b): boolean
+
+
+
+
+
+ Input
+ { foo: "bar"}, { baz: "qux" }
+
+
+ Result
+ {{
+ $helper.object.same({ foo: "bar" }, { baz: "qux" })
+ }}
+
+
+ { foo: "bar"}, { foo: "bar" }
+
+
+ {{
+ $helper.object.same({ foo: "bar" }, { foo: "bar" })
+ }}
+
+
+
+
+
+
+
+ Converts to lowercase all keys in an object:
+
+ this.$helper.object.toLowerKeys(object): object
+
+
+
+
+
+ Input
+ { FOO: "bar", bAz: "qux" }
+
+
+ Result
+ {{
+ $helper.object.toLowerKeys({ FOO: "bar", bAz: "qux" })
+ }}
+
+
+
+
-
-
diff --git a/panel/src/helpers/object.js b/panel/src/helpers/object.js
index aaf956729c..7ceba6886d 100644
--- a/panel/src/helpers/object.js
+++ b/panel/src/helpers/object.js
@@ -51,7 +51,7 @@ export function isObject(input) {
* @since 4.0.0
*
* @param {object} object
- * @returns int
+ * @returns {int}
*/
export function length(object) {
return Object.keys(object ?? {}).length;
From 0bc7c59fe445681d9623d1b4b8d31e89567fb2a4 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 19:20:37 +0100
Subject: [PATCH 149/202] Lab: remove helper queue placeholder
---
panel/lab/internals/helpers/queue/index.php | 5 -----
panel/lab/internals/helpers/queue/index.vue | 13 -------------
2 files changed, 18 deletions(-)
delete mode 100644 panel/lab/internals/helpers/queue/index.php
delete mode 100644 panel/lab/internals/helpers/queue/index.vue
diff --git a/panel/lab/internals/helpers/queue/index.php b/panel/lab/internals/helpers/queue/index.php
deleted file mode 100644
index 8bc8ceaf34..0000000000
--- a/panel/lab/internals/helpers/queue/index.php
+++ /dev/null
@@ -1,5 +0,0 @@
- 'panel/src/helpers/queue.js'
-];
diff --git a/panel/lab/internals/helpers/queue/index.vue b/panel/lab/internals/helpers/queue/index.vue
deleted file mode 100644
index 8fb2c60a13..0000000000
--- a/panel/lab/internals/helpers/queue/index.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- These docs are still work in progress and will be added soon
-
-
-
-
-
From a4fdb01f453841659ab7b2674881b9e38fa33012 Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 19:26:35 +0100
Subject: [PATCH 150/202] Lab `$helper.sort` docs
---
panel/lab/internals/helpers/sort/index.vue | 29 +++++++++++++++-------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/panel/lab/internals/helpers/sort/index.vue b/panel/lab/internals/helpers/sort/index.vue
index 8fb2c60a13..28ce8ae19e 100644
--- a/panel/lab/internals/helpers/sort/index.vue
+++ b/panel/lab/internals/helpers/sort/index.vue
@@ -1,13 +1,24 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+
+ Natural sort algorithm with unicode support based on
+ github.com/bubkoo/natsort :
+
+
+ this.$helper.sort(options): boolean
+
+
+ Example
+ const sorter = sort({
+ desc: direction === "desc",
+ insensitive: true
+});
+
+array.sort((a, b) => sorter(a, b)});
+
-
-
From 132542aab189bf63e35c462d91631e783dab17aa Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Thu, 29 Feb 2024 19:32:52 +0100
Subject: [PATCH 151/202] Lab `$helper.upload` docs
---
panel/lab/internals/helpers/object/index.vue | 12 -----
panel/lab/internals/helpers/upload/index.vue | 52 ++++++++++++++++----
2 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/panel/lab/internals/helpers/object/index.vue b/panel/lab/internals/helpers/object/index.vue
index 6804737d27..4e25466c39 100644
--- a/panel/lab/internals/helpers/object/index.vue
+++ b/panel/lab/internals/helpers/object/index.vue
@@ -14,7 +14,6 @@
this.$helper.object.isEmpty(value): boolean
-
Input
@@ -75,7 +74,6 @@
}}
-
@@ -85,7 +83,6 @@
this.$helper.object.isObject(value): boolean
-
Input
@@ -122,7 +119,6 @@
}}
-
@@ -132,7 +128,6 @@
this.$helper.object.length(object): int
-
Input
@@ -151,7 +146,6 @@
}}
-
@@ -161,7 +155,6 @@
this.$helper.object.merge(target, source): object
-
Input
@@ -174,7 +167,6 @@
}}
-
@@ -184,7 +176,6 @@
this.$helper.object.same(a, b): boolean
-
Input
@@ -205,7 +196,6 @@
}}
-
@@ -215,7 +205,6 @@
this.$helper.object.toLowerKeys(object): object
-
Input
@@ -228,7 +217,6 @@
}}
-
diff --git a/panel/lab/internals/helpers/upload/index.vue b/panel/lab/internals/helpers/upload/index.vue
index 8fb2c60a13..b1dca078ba 100644
--- a/panel/lab/internals/helpers/upload/index.vue
+++ b/panel/lab/internals/helpers/upload/index.vue
@@ -1,13 +1,47 @@
-
- These docs are still work in progress and will be added soon
-
+
+
+ Uploads a file using XMLHttpRequest:
+
+
+ this.$helper.upload(file, params): Promise
+
+
+ file
(File): file to upload
+
+ params
(object): upload option
+
+
+
+ url
(string): URL endpoint to sent the request to
+
+
+ method
(string): HTTP method (e.g.
+ "POST"
)
+
+
+ filename
(string): filename to use for the upload
+
+ headers
(object): request headers
+ attributes
(object): additional attributes
+
+ progress
(Function): callback whenever the progress
+ changes
+
+
+ complete
(Function): callback when upload completed
+
+
+ success
(Function): callback when upload succeeded
+
+
+ error
(Function): callback when upload failed
+
+
+
+
+
+
-
-
From 13423e43973e5570fcd8be9187bb2cab94caaec5 Mon Sep 17 00:00:00 2001
From: Bastian Allgeier
Date: Fri, 1 Mar 2024 15:35:34 +0100
Subject: [PATCH 152/202] Small fix to highlight results
---
panel/lab/internals/helpers/link/index.vue | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/panel/lab/internals/helpers/link/index.vue b/panel/lab/internals/helpers/link/index.vue
index 04033fb0e9..2031dc35bf 100644
--- a/panel/lab/internals/helpers/link/index.vue
+++ b/panel/lab/internals/helpers/link/index.vue
@@ -22,7 +22,9 @@
Result
- {{ $helper.link.detect(detect) }}
+ {{
+ $helper.link.detect(detect)
+ }}
@@ -43,7 +45,7 @@
Result
- {{ previewResult }}
+ {{ previewResult }}
@@ -58,7 +60,7 @@
Result
- {{ $helper.link.types() }}
+ {{ $helper.link.types() }}
From 1b1a56010a1b7eb8ede7692fa28575ab8b6d005d Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 2 Mar 2024 13:51:10 +0100
Subject: [PATCH 153/202] Small fix for invalid highlighting
---
panel/src/components/Lab/PlaygroundView.vue | 1 +
1 file changed, 1 insertion(+)
diff --git a/panel/src/components/Lab/PlaygroundView.vue b/panel/src/components/Lab/PlaygroundView.vue
index e88c72c5fe..b936f31961 100644
--- a/panel/src/components/Lab/PlaygroundView.vue
+++ b/panel/src/components/Lab/PlaygroundView.vue
@@ -135,6 +135,7 @@ export default {
.k-lab-input-examples .k-lab-example:has(:invalid) {
outline: 2px solid var(--color-red-500);
+ outline-offset: -2px;
}
.k-lab-input-examples-focus .k-lab-example-canvas > .k-button {
From 9ccf87951f518819b329a0e8cc8b7292c3d001ef Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sat, 2 Mar 2024 14:03:50 +0100
Subject: [PATCH 154/202] Fix choice input grid in picklist input
---
panel/src/components/Forms/Input/PicklistInput.vue | 3 +++
1 file changed, 3 insertions(+)
diff --git a/panel/src/components/Forms/Input/PicklistInput.vue b/panel/src/components/Forms/Input/PicklistInput.vue
index d41b7b6d70..4ae5de56f5 100644
--- a/panel/src/components/Forms/Input/PicklistInput.vue
+++ b/panel/src/components/Forms/Input/PicklistInput.vue
@@ -328,6 +328,9 @@ export default {
visibility: hidden;
}
+.k-picklist-input-options.k-grid {
+ --columns: 1;
+}
.k-picklist-input-options li + li {
margin-top: var(--spacing-1);
}
From 545cfeaa79bc76dda4309c541f2ac82e81acb17d Mon Sep 17 00:00:00 2001
From: Nico Hoffmann
Date: Sun, 3 Mar 2024 11:26:31 +0100
Subject: [PATCH 155/202] Fix WriterField counter
---
panel/src/components/Forms/Field/WriterField.vue | 10 ++++++++--
panel/src/components/Forms/Input/WriterInput.vue | 12 ++++++------
panel/src/mixins/forms/counter.js | 13 ++-----------
3 files changed, 16 insertions(+), 19 deletions(-)
diff --git a/panel/src/components/Forms/Field/WriterField.vue b/panel/src/components/Forms/Field/WriterField.vue
index 167c2aec8c..acb945368d 100644
--- a/panel/src/components/Forms/Field/WriterField.vue
+++ b/panel/src/components/Forms/Field/WriterField.vue
@@ -20,12 +20,18 @@
diff --git a/panel/src/components/Navigation/FileBrowser.vue b/panel/src/components/Navigation/FileBrowser.vue
index 8c3290daea..476e3239a1 100644
--- a/panel/src/components/Navigation/FileBrowser.vue
+++ b/panel/src/components/Navigation/FileBrowser.vue
@@ -18,9 +18,12 @@
+
+