From df958a8e2e1bff04ed3d0c2d7c8c0b958c396552 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 18:08:10 +0000 Subject: [PATCH] Version v0.16.0-dev --- VERSION | 2 +- asset/css/action-link-and-button-link.less | 26 + asset/css/balls.less | 40 +- asset/css/compat.less | 63 +- asset/css/controls.less | 13 +- asset/css/empty-state.less | 5 +- asset/css/icinga-icons.less | 36 +- asset/css/item-layout.less | 177 +++ asset/css/list/item-list.less | 83 +- asset/css/list/item-table.less | 162 ++- asset/css/list/list-item.less | 68 +- asset/css/mixin/mixins.less | 5 + asset/css/schedule-element.less | 58 +- asset/css/search-bar.less | 40 +- asset/css/search-base.less | 82 +- asset/css/search-editor.less | 12 +- asset/css/suggestion-element.less | 29 + asset/css/variables.less | 26 +- asset/js/iterator.js | 96 ++ asset/js/widget/BaseInput.js | 15 +- asset/js/widget/FilterInput.js | 18 +- asset/js/widget/TermInput.js | 17 +- composer.lock | 575 ++++---- vendor/autoload.php | 7 +- vendor/brick/math/composer.json | 14 +- vendor/brick/math/src/BigDecimal.php | 347 +++-- vendor/brick/math/src/BigInteger.php | 403 +++--- vendor/brick/math/src/BigNumber.php | 428 +++--- vendor/brick/math/src/BigRational.php | 206 +-- .../src/Exception/DivisionByZeroException.php | 14 +- .../Exception/IntegerOverflowException.php | 8 +- .../math/src/Exception/MathException.php | 2 - .../src/Exception/NegativeNumberException.php | 2 +- .../src/Exception/NumberFormatException.php | 19 +- .../Exception/RoundingNecessaryException.php | 6 +- vendor/brick/math/src/Internal/Calculator.php | 235 +--- .../Internal/Calculator/BcMathCalculator.php | 69 +- .../src/Internal/Calculator/GmpCalculator.php | 74 +- .../Internal/Calculator/NativeCalculator.php | 141 +- .../math/src/Internal/CalculatorRegistry.php | 73 + vendor/brick/math/src/RoundingMode.php | 31 +- vendor/composer/InstalledVersions.php | 45 +- vendor/composer/autoload_classmap.php | 7 +- vendor/composer/autoload_files.php | 3 +- vendor/composer/autoload_psr4.php | 8 +- vendor/composer/autoload_real.php | 10 +- vendor/composer/autoload_static.php | 45 +- vendor/composer/installed.json | 536 +++---- vendor/composer/installed.php | 148 +- vendor/composer/platform_check.php | 9 +- .../cweagans/composer-patches/composer.json | 30 - .../composer-patches/src/PatchEvent.php | 70 - .../composer-patches/src/PatchEvents.php | 30 - .../cweagans/composer-patches/src/Patches.php | 599 -------- .../collections/.doctrine-project.json | 32 - vendor/doctrine/collections/composer.json | 18 +- .../Expr/ClosureExpressionVisitor.php | 269 ---- .../Common/Collections/Expr/Comparison.php | 74 - .../Common/Collections/ExpressionBuilder.php | 181 --- .../AbstractLazyCollection.php | 77 +- .../Collections => src}/ArrayCollection.php | 138 +- .../Common/Collections => src}/Collection.php | 52 +- .../Common/Collections => src}/Criteria.php | 110 +- .../src/Expr/ClosureExpressionVisitor.php | 214 +++ .../collections/src/Expr/Comparison.php | 62 + .../Expr/CompositeExpression.php | 29 +- .../Collections => src}/Expr/Expression.php | 2 + .../Expr/ExpressionVisitor.php | 23 +- .../Common/Collections => src}/Expr/Value.php | 9 +- .../collections/src/ExpressionBuilder.php | 128 ++ vendor/doctrine/collections/src/Order.php | 11 + .../ReadableCollection.php | 93 +- .../Common/Collections => src}/Selectable.php | 12 +- vendor/ipl/html/composer.json | 3 +- vendor/ipl/html/src/Attribute.php | 47 +- vendor/ipl/html/src/Attributes.php | 24 +- vendor/ipl/html/src/BaseHtmlElement.php | 66 +- .../src/Contract/DecorableFormElement.php | 32 + .../html/src/Contract/DecorationResult.php | 35 + .../html/src/Contract/DecoratorOptions.php | 40 + .../Contract/DecoratorOptionsInterface.php | 18 + .../Contract/DefaultFormElementDecoration.php | 39 + vendor/ipl/html/src/Contract/Form.php | 87 ++ .../ipl/html/src/Contract/FormDecoration.php | 40 + vendor/ipl/html/src/Contract/FormElement.php | 4 +- .../src/Contract/FormElementDecoration.php | 43 + .../src/Contract/FormElementDecorator.php | 2 + vendor/ipl/html/src/Contract/FormElements.php | 103 ++ .../src/Contract/HtmlElementInterface.php | 90 ++ vendor/ipl/html/src/Contract/MutableHtml.php | 90 ++ vendor/ipl/html/src/Form.php | 143 +- .../src/FormDecoration/DecoratorChain.php | 297 ++++ .../FormDecoration/DescriptionDecorator.php | 100 ++ .../src/FormDecoration/ErrorsDecorator.php | 64 + .../src/FormDecoration/FieldsetDecorator.php | 43 + .../FormDecoration/FormDecorationResult.php | 54 + .../FormElementDecorationResult.php | 96 ++ .../src/FormDecoration/HtmlTagDecorator.php | 217 +++ .../src/FormDecoration/LabelDecorator.php | 105 ++ .../FormDecoration/RenderElementDecorator.php | 18 + .../src/FormDecoration/Transformation.php | 39 + .../src/FormDecorator/CallbackDecorator.php | 3 + .../html/src/FormDecorator/DdDtDecorator.php | 6 +- .../src/FormDecorator/DecoratorInterface.php | 4 +- .../html/src/FormDecorator/DivDecorator.php | 3 + .../html/src/FormElement/BaseFormElement.php | 80 +- .../html/src/FormElement/FieldsetElement.php | 15 +- .../ipl/html/src/FormElement/FileElement.php | 6 +- .../ipl/html/src/FormElement/FormElements.php | 245 +++- .../ipl/html/src/FormElement/RadioElement.php | 10 + .../html/src/FormElement/SelectElement.php | 2 +- .../ipl/html/src/FormElement/TextElement.php | 36 + vendor/ipl/html/src/HtmlDocument.php | 106 +- vendor/ipl/orm/composer.json | 2 +- vendor/ipl/orm/src/Relation/BelongsToMany.php | 29 +- vendor/ipl/orm/src/Resolver.php | 5 +- vendor/ipl/sql/src/Connection.php | 20 + vendor/ipl/sql/src/Test/SharedDatabases.php | 175 +++ vendor/ipl/sql/src/Test/TestConnection.php | 49 + vendor/ipl/validator/composer.json | 6 +- vendor/ipl/validator/src/BetweenValidator.php | 29 +- .../ipl/validator/src/CallbackValidator.php | 2 +- vendor/ipl/validator/src/CidrValidator.php | 4 + .../ipl/validator/src/DateTimeValidator.php | 6 +- .../src/DeferredInArrayValidator.php | 6 +- .../validator/src/EmailAddressValidator.php | 5 +- vendor/ipl/validator/src/FileValidator.php | 37 +- .../validator/src/GreaterThanValidator.php | 17 +- .../ipl/validator/src/HostnameValidator.php | 4 +- vendor/ipl/validator/src/InArrayValidator.php | 14 +- .../ipl/validator/src/LessThanValidator.php | 17 +- .../ipl/validator/src/PrivateKeyValidator.php | 7 +- .../validator/src/StringLengthValidator.php | 35 +- vendor/ipl/validator/src/ValidatorChain.php | 26 +- .../ipl/validator/src/X509CertValidator.php | 6 +- vendor/ipl/web/composer.json | 4 +- vendor/ipl/web/src/Common/BaseItemList.php | 54 +- vendor/ipl/web/src/Common/BaseItemTable.php | 3 + vendor/ipl/web/src/Common/BaseListItem.php | 5 +- .../web/src/Common/BaseOrderedItemList.php | 1 + .../web/src/Common/BaseOrderedListItem.php | 1 + .../ipl/web/src/Common/BaseTableRowItem.php | 4 +- .../ipl/web/src/Common/CsrfCounterMeasure.php | 55 + vendor/ipl/web/src/Common/ItemRenderer.php | 92 ++ vendor/ipl/web/src/Compat/CompatForm.php | 68 + .../FormDecorator/CheckboxDecorator.php | 52 + .../FormDecorator/DescriptionDecorator.php | 34 + .../Compat/FormDecorator/LabelDecorator.php | 74 + vendor/ipl/web/src/Compat/SearchControls.php | 61 +- .../ipl/web/src/Control/PaginationControl.php | 67 +- .../web/src/Control/SearchBar/Suggestions.php | 27 +- .../ipl/web/src/Control/SearchBar/Terms.php | 8 +- vendor/ipl/web/src/Control/SortControl.php | 62 +- .../src/FormDecorator/IcingaFormDecorator.php | 6 + .../web/src/FormElement/ScheduleElement.php | 129 +- .../ScheduleElement/AnnuallyFields.php | 27 +- .../ScheduleElement/MonthlyFields.php | 3 +- .../ScheduleElement/WeeklyFields.php | 3 +- .../web/src/FormElement/SearchSuggestions.php | 279 ++++ .../web/src/FormElement/SuggestionElement.php | 87 ++ vendor/ipl/web/src/FormElement/TermInput.php | 21 +- .../FormElement/TermInput/TermContainer.php | 21 +- .../FormElement/TermInput/TermSuggestions.php | 279 +--- vendor/ipl/web/src/Layout/Controls.php | 2 +- .../ipl/web/src/Layout/DetailedItemLayout.php | 27 + .../src/Layout/DetailedItemTableLayout.php | 19 + .../ipl/web/src/Layout/HeaderItemLayout.php | 17 + vendor/ipl/web/src/Layout/ItemLayout.php | 478 +++++++ vendor/ipl/web/src/Layout/ItemTableLayout.php | 125 ++ .../ipl/web/src/Layout/MinimalItemLayout.php | 30 + .../web/src/Layout/MinimalItemTableLayout.php | 29 + vendor/ipl/web/src/Widget/Ball.php | 102 ++ vendor/ipl/web/src/Widget/ButtonLink.php | 45 +- vendor/ipl/web/src/Widget/ContinueWith.php | 5 + vendor/ipl/web/src/Widget/ItemList.php | 191 +++ vendor/ipl/web/src/Widget/ItemTable.php | 76 + .../Widget/ItemTable/ItemTableRenderer.php | 26 + vendor/ipl/web/src/Widget/ItemTableRow.php | 46 + vendor/ipl/web/src/Widget/ListItem.php | 46 + vendor/ipl/web/src/Widget/StateBall.php | 56 +- vendor/ramsey/collection/LICENSE | 2 +- vendor/ramsey/collection/composer.json | 133 +- .../ramsey/collection/src/AbstractArray.php | 65 +- .../collection/src/AbstractCollection.php | 281 ++-- vendor/ramsey/collection/src/AbstractSet.php | 21 +- .../ramsey/collection/src/ArrayInterface.php | 6 +- vendor/ramsey/collection/src/Collection.php | 25 +- .../collection/src/CollectionInterface.php | 112 +- .../collection/src/DoubleEndedQueue.php | 133 +- .../src/DoubleEndedQueueInterface.php | 43 +- ...rException.php => CollectionException.php} | 7 +- .../Exception/CollectionMismatchException.php | 4 +- .../Exception/InvalidArgumentException.php | 4 +- ...eption.php => InvalidPropertyOrMethod.php} | 8 +- .../src/Exception/NoSuchElementException.php | 4 +- .../src/Exception/OutOfBoundsException.php | 4 +- .../UnsupportedOperationException.php | 4 +- vendor/ramsey/collection/src/GenericArray.php | 2 +- .../ramsey/collection/src/Map/AbstractMap.php | 113 +- .../collection/src/Map/AbstractTypedMap.php | 24 +- .../src/Map/AssociativeArrayMap.php | 3 +- .../collection/src/Map/MapInterface.php | 59 +- .../collection/src/Map/NamedParameterMap.php | 22 +- vendor/ramsey/collection/src/Map/TypedMap.php | 47 +- .../collection/src/Map/TypedMapInterface.php | 3 +- vendor/ramsey/collection/src/Queue.php | 105 +- .../ramsey/collection/src/QueueInterface.php | 23 +- vendor/ramsey/collection/src/Set.php | 20 +- vendor/ramsey/collection/src/Sort.php | 31 + .../ramsey/collection/src/Tool/TypeTrait.php | 48 +- .../src/Tool/ValueExtractorTrait.php | 76 +- .../src/Tool/ValueToStringTrait.php | 16 +- vendor/ramsey/uuid/LICENSE | 2 +- vendor/ramsey/uuid/composer.json | 141 +- vendor/ramsey/uuid/src/BinaryUtils.php | 33 +- .../uuid/src/Builder/BuilderCollection.php | 19 +- .../uuid/src/Builder/DefaultUuidBuilder.php | 4 +- .../uuid/src/Builder/DegradedUuidBuilder.php | 34 +- .../uuid/src/Builder/FallbackBuilder.php | 22 +- .../uuid/src/Builder/UuidBuilderInterface.php | 7 +- .../ramsey/uuid/src/Codec/CodecInterface.php | 32 +- .../ramsey/uuid/src/Codec/GuidStringCodec.php | 31 +- .../uuid/src/Codec/OrderedTimeCodec.php | 62 +- vendor/ramsey/uuid/src/Codec/StringCodec.php | 59 +- .../src/Codec/TimestampFirstCombCodec.php | 39 +- .../uuid/src/Codec/TimestampLastCombCodec.php | 25 +- .../Converter/Number/BigNumberConverter.php | 19 +- .../Number/DegradedNumberConverter.php | 6 +- .../Number/GenericNumberConverter.php | 27 +- .../Converter/NumberConverterInterface.php | 32 +- .../Converter/Time/BigNumberTimeConverter.php | 13 +- .../Converter/Time/DegradedTimeConverter.php | 6 +- .../Converter/Time/GenericTimeConverter.php | 66 +- .../src/Converter/Time/PhpTimeConverter.php | 75 +- .../src/Converter/Time/UnixTimeConverter.php | 92 ++ .../src/Converter/TimeConverterInterface.php | 27 +- vendor/ramsey/uuid/src/DegradedUuid.php | 6 +- .../uuid/src/DeprecatedUuidInterface.php | 61 +- .../uuid/src/DeprecatedUuidMethodsTrait.php | 194 +-- .../src/Exception/DceSecurityException.php | 3 +- .../Exception/InvalidUuidStringException.php | 4 +- .../uuid/src/Exception/NameException.php | 3 +- .../src/Exception/RandomSourceException.php | 4 +- vendor/ramsey/uuid/src/FeatureSet.php | 176 +-- .../uuid/src/Fields/FieldsInterface.php | 9 +- .../src/Fields/SerializableFieldsTrait.php | 19 +- .../uuid/src/Generator/CombGenerator.php | 67 +- .../src/Generator/DceSecurityGenerator.php | 55 +- .../DceSecurityGeneratorInterface.php | 27 +- .../src/Generator/DefaultNameGenerator.php | 24 +- .../src/Generator/DefaultTimeGenerator.php | 59 +- .../src/Generator/NameGeneratorFactory.php | 3 +- .../src/Generator/NameGeneratorInterface.php | 9 +- .../src/Generator/PeclUuidNameGenerator.php | 32 +- .../src/Generator/PeclUuidRandomGenerator.php | 2 +- .../src/Generator/PeclUuidTimeGenerator.php | 5 +- .../src/Generator/RandomBytesGenerator.php | 9 +- .../src/Generator/RandomGeneratorFactory.php | 3 +- .../Generator/RandomGeneratorInterface.php | 2 +- .../uuid/src/Generator/RandomLibAdapter.php | 17 +- .../src/Generator/TimeGeneratorFactory.php | 33 +- .../src/Generator/TimeGeneratorInterface.php | 13 +- .../uuid/src/Generator/UnixTimeGenerator.php | 165 +++ vendor/ramsey/uuid/src/Guid/Fields.php | 76 +- vendor/ramsey/uuid/src/Guid/Guid.php | 24 +- vendor/ramsey/uuid/src/Guid/GuidBuilder.php | 41 +- .../uuid/src/Lazy/LazyUuidFromString.php | 367 ++--- .../uuid/src/Math/BrickMathCalculator.php | 18 +- .../uuid/src/Math/CalculatorInterface.php | 25 +- vendor/ramsey/uuid/src/Math/RoundingMode.php | 181 ++- vendor/ramsey/uuid/src/Nonstandard/Fields.php | 31 +- vendor/ramsey/uuid/src/Nonstandard/Uuid.php | 7 +- .../uuid/src/Nonstandard/UuidBuilder.php | 44 +- vendor/ramsey/uuid/src/Nonstandard/UuidV6.php | 74 +- .../Dce/SystemDceSecurityProvider.php | 80 +- .../Provider/DceSecurityProviderInterface.php | 3 +- .../Provider/Node/FallbackNodeProvider.php | 21 +- .../Provider/Node/NodeProviderCollection.php | 19 +- .../src/Provider/Node/RandomNodeProvider.php | 24 +- .../src/Provider/Node/StaticNodeProvider.php | 19 +- .../src/Provider/Node/SystemNodeProvider.php | 93 +- .../src/Provider/Time/FixedTimeProvider.php | 23 +- vendor/ramsey/uuid/src/Rfc4122/Fields.php | 120 +- .../uuid/src/Rfc4122/FieldsInterface.php | 58 +- vendor/ramsey/uuid/src/Rfc4122/MaxTrait.php | 40 + vendor/ramsey/uuid/src/Rfc4122/MaxUuid.php | 28 + vendor/ramsey/uuid/src/Rfc4122/NilTrait.php | 9 +- vendor/ramsey/uuid/src/Rfc4122/NilUuid.php | 7 +- vendor/ramsey/uuid/src/Rfc4122/TimeTrait.php | 53 + .../ramsey/uuid/src/Rfc4122/UuidBuilder.php | 89 +- .../ramsey/uuid/src/Rfc4122/UuidInterface.php | 14 +- vendor/ramsey/uuid/src/Rfc4122/UuidV1.php | 60 +- vendor/ramsey/uuid/src/Rfc4122/UuidV2.php | 80 +- vendor/ramsey/uuid/src/Rfc4122/UuidV3.php | 23 +- vendor/ramsey/uuid/src/Rfc4122/UuidV4.php | 22 +- vendor/ramsey/uuid/src/Rfc4122/UuidV5.php | 23 +- vendor/ramsey/uuid/src/Rfc4122/UuidV6.php | 29 + vendor/ramsey/uuid/src/Rfc4122/UuidV7.php | 58 + vendor/ramsey/uuid/src/Rfc4122/UuidV8.php | 60 + vendor/ramsey/uuid/src/Rfc4122/Validator.php | 16 +- .../ramsey/uuid/src/Rfc4122/VariantTrait.php | 77 +- .../ramsey/uuid/src/Rfc4122/VersionTrait.php | 53 +- vendor/ramsey/uuid/src/Type/Decimal.php | 44 +- vendor/ramsey/uuid/src/Type/Hexadecimal.php | 77 +- vendor/ramsey/uuid/src/Type/Integer.php | 125 +- .../ramsey/uuid/src/Type/NumberInterface.php | 2 +- vendor/ramsey/uuid/src/Type/Time.php | 58 +- vendor/ramsey/uuid/src/Type/TypeInterface.php | 8 +- vendor/ramsey/uuid/src/Uuid.php | 430 +++--- vendor/ramsey/uuid/src/UuidFactory.php | 239 ++-- .../ramsey/uuid/src/UuidFactoryInterface.php | 227 ++- vendor/ramsey/uuid/src/UuidInterface.php | 51 +- .../uuid/src/Validator/GenericValidator.php | 8 +- .../uuid/src/Validator/ValidatorInterface.php | 8 +- vendor/ramsey/uuid/src/functions.php | 96 +- vendor/symfony/polyfill-ctype/Ctype.php | 232 ---- vendor/symfony/polyfill-ctype/LICENSE | 19 - vendor/symfony/polyfill-ctype/bootstrap.php | 50 - vendor/symfony/polyfill-ctype/bootstrap80.php | 46 - vendor/symfony/polyfill-ctype/composer.json | 38 - vendor/symfony/polyfill-php80/Php80.php | 115 -- vendor/symfony/polyfill-php80/PhpToken.php | 106 -- .../Resources/stubs/Attribute.php | 31 - .../Resources/stubs/PhpToken.php | 16 - .../Resources/stubs/Stringable.php | 20 - .../Resources/stubs/UnhandledMatchError.php | 16 - .../Resources/stubs/ValueError.php | 16 - vendor/symfony/polyfill-php80/bootstrap.php | 42 - .../LICENSE | 2 +- vendor/symfony/polyfill-php84/Php84.php | 217 +++ .../Resources/stubs/Deprecated.php | 25 + .../Resources/stubs/ReflectionConstant.php | 158 +++ vendor/symfony/polyfill-php84/bootstrap.php | 82 ++ vendor/symfony/polyfill-php84/bootstrap82.php | 20 + .../composer.json | 10 +- vendor/webmozart/assert/.php-cs-fixer.php | 27 + vendor/webmozart/assert/composer.json | 31 +- vendor/webmozart/assert/src/Assert.php | 306 +++- vendor/webmozart/assert/src/Mixin.php | 1229 +++++++++-------- .../assert/tools/php-cs-fixer/composer.json | 5 + .../assert/tools/phpunit/composer.json | 5 + .../assert/tools/psalm/composer.json | 5 + .../assert/tools/roave-bc-check/composer.json | 5 + 343 files changed, 12871 insertions(+), 9394 deletions(-) create mode 100644 asset/css/action-link-and-button-link.less create mode 100644 asset/css/item-layout.less create mode 100644 asset/css/suggestion-element.less create mode 100644 asset/js/iterator.js create mode 100644 vendor/brick/math/src/Internal/CalculatorRegistry.php delete mode 100644 vendor/cweagans/composer-patches/composer.json delete mode 100644 vendor/cweagans/composer-patches/src/PatchEvent.php delete mode 100644 vendor/cweagans/composer-patches/src/PatchEvents.php delete mode 100644 vendor/cweagans/composer-patches/src/Patches.php delete mode 100644 vendor/doctrine/collections/.doctrine-project.json delete mode 100644 vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php delete mode 100644 vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php delete mode 100644 vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/AbstractLazyCollection.php (79%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/ArrayCollection.php (74%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Collection.php (71%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Criteria.php (62%) create mode 100644 vendor/doctrine/collections/src/Expr/ClosureExpressionVisitor.php create mode 100644 vendor/doctrine/collections/src/Expr/Comparison.php rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Expr/CompositeExpression.php (66%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Expr/Expression.php (89%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Expr/ExpressionVisitor.php (68%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Expr/Value.php (70%) create mode 100644 vendor/doctrine/collections/src/ExpressionBuilder.php create mode 100644 vendor/doctrine/collections/src/Order.php rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/ReadableCollection.php (70%) rename vendor/doctrine/collections/{lib/Doctrine/Common/Collections => src}/Selectable.php (72%) create mode 100644 vendor/ipl/html/src/Contract/DecorableFormElement.php create mode 100644 vendor/ipl/html/src/Contract/DecorationResult.php create mode 100644 vendor/ipl/html/src/Contract/DecoratorOptions.php create mode 100644 vendor/ipl/html/src/Contract/DecoratorOptionsInterface.php create mode 100644 vendor/ipl/html/src/Contract/DefaultFormElementDecoration.php create mode 100644 vendor/ipl/html/src/Contract/Form.php create mode 100644 vendor/ipl/html/src/Contract/FormDecoration.php create mode 100644 vendor/ipl/html/src/Contract/FormElementDecoration.php create mode 100644 vendor/ipl/html/src/Contract/FormElements.php create mode 100644 vendor/ipl/html/src/Contract/HtmlElementInterface.php create mode 100644 vendor/ipl/html/src/Contract/MutableHtml.php create mode 100644 vendor/ipl/html/src/FormDecoration/DecoratorChain.php create mode 100644 vendor/ipl/html/src/FormDecoration/DescriptionDecorator.php create mode 100644 vendor/ipl/html/src/FormDecoration/ErrorsDecorator.php create mode 100644 vendor/ipl/html/src/FormDecoration/FieldsetDecorator.php create mode 100644 vendor/ipl/html/src/FormDecoration/FormDecorationResult.php create mode 100644 vendor/ipl/html/src/FormDecoration/FormElementDecorationResult.php create mode 100644 vendor/ipl/html/src/FormDecoration/HtmlTagDecorator.php create mode 100644 vendor/ipl/html/src/FormDecoration/LabelDecorator.php create mode 100644 vendor/ipl/html/src/FormDecoration/RenderElementDecorator.php create mode 100644 vendor/ipl/html/src/FormDecoration/Transformation.php create mode 100644 vendor/ipl/sql/src/Test/SharedDatabases.php create mode 100644 vendor/ipl/web/src/Common/ItemRenderer.php mode change 100644 => 100755 vendor/ipl/web/src/Compat/CompatForm.php create mode 100644 vendor/ipl/web/src/Compat/FormDecorator/CheckboxDecorator.php create mode 100644 vendor/ipl/web/src/Compat/FormDecorator/DescriptionDecorator.php create mode 100755 vendor/ipl/web/src/Compat/FormDecorator/LabelDecorator.php create mode 100644 vendor/ipl/web/src/FormElement/SearchSuggestions.php create mode 100644 vendor/ipl/web/src/FormElement/SuggestionElement.php create mode 100644 vendor/ipl/web/src/Layout/DetailedItemLayout.php create mode 100644 vendor/ipl/web/src/Layout/DetailedItemTableLayout.php create mode 100644 vendor/ipl/web/src/Layout/HeaderItemLayout.php create mode 100644 vendor/ipl/web/src/Layout/ItemLayout.php create mode 100644 vendor/ipl/web/src/Layout/ItemTableLayout.php create mode 100644 vendor/ipl/web/src/Layout/MinimalItemLayout.php create mode 100644 vendor/ipl/web/src/Layout/MinimalItemTableLayout.php create mode 100644 vendor/ipl/web/src/Widget/Ball.php create mode 100644 vendor/ipl/web/src/Widget/ItemList.php create mode 100644 vendor/ipl/web/src/Widget/ItemTable.php create mode 100644 vendor/ipl/web/src/Widget/ItemTable/ItemTableRenderer.php create mode 100644 vendor/ipl/web/src/Widget/ItemTableRow.php create mode 100644 vendor/ipl/web/src/Widget/ListItem.php rename vendor/ramsey/collection/src/Exception/{InvalidSortOrderException.php => CollectionException.php} (73%) rename vendor/ramsey/collection/src/Exception/{ValueExtractionException.php => InvalidPropertyOrMethod.php} (58%) create mode 100644 vendor/ramsey/collection/src/Sort.php create mode 100644 vendor/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php create mode 100644 vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php create mode 100644 vendor/ramsey/uuid/src/Rfc4122/MaxTrait.php create mode 100644 vendor/ramsey/uuid/src/Rfc4122/MaxUuid.php create mode 100644 vendor/ramsey/uuid/src/Rfc4122/TimeTrait.php create mode 100644 vendor/ramsey/uuid/src/Rfc4122/UuidV6.php create mode 100644 vendor/ramsey/uuid/src/Rfc4122/UuidV7.php create mode 100644 vendor/ramsey/uuid/src/Rfc4122/UuidV8.php delete mode 100644 vendor/symfony/polyfill-ctype/Ctype.php delete mode 100644 vendor/symfony/polyfill-ctype/LICENSE delete mode 100644 vendor/symfony/polyfill-ctype/bootstrap.php delete mode 100644 vendor/symfony/polyfill-ctype/bootstrap80.php delete mode 100644 vendor/symfony/polyfill-ctype/composer.json delete mode 100644 vendor/symfony/polyfill-php80/Php80.php delete mode 100644 vendor/symfony/polyfill-php80/PhpToken.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php delete mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php delete mode 100644 vendor/symfony/polyfill-php80/bootstrap.php rename vendor/symfony/{polyfill-php80 => polyfill-php84}/LICENSE (95%) create mode 100644 vendor/symfony/polyfill-php84/Php84.php create mode 100644 vendor/symfony/polyfill-php84/Resources/stubs/Deprecated.php create mode 100644 vendor/symfony/polyfill-php84/Resources/stubs/ReflectionConstant.php create mode 100644 vendor/symfony/polyfill-php84/bootstrap.php create mode 100644 vendor/symfony/polyfill-php84/bootstrap82.php rename vendor/symfony/{polyfill-php80 => polyfill-php84}/composer.json (74%) create mode 100644 vendor/webmozart/assert/.php-cs-fixer.php create mode 100644 vendor/webmozart/assert/tools/php-cs-fixer/composer.json create mode 100644 vendor/webmozart/assert/tools/phpunit/composer.json create mode 100644 vendor/webmozart/assert/tools/psalm/composer.json create mode 100644 vendor/webmozart/assert/tools/roave-bc-check/composer.json diff --git a/VERSION b/VERSION index 5f1dd0a..8347ddf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.15.1 +v0.16.0-dev diff --git a/asset/css/action-link-and-button-link.less b/asset/css/action-link-and-button-link.less new file mode 100644 index 0000000..d654f66 --- /dev/null +++ b/asset/css/action-link-and-button-link.less @@ -0,0 +1,26 @@ +.action-link { + color: var(--control-color, @control-color); +} + +.button-link { + .action-link(); + .rounded-corners(3px); + + background: var(--default-input-bg, @default-input-bg); + display: inline-block; + padding: 0.25em 0.5em; + + &:hover { + background: var(--default-input-hover-bg, @default-input-hover-bg); + text-decoration: none; + } + + &[aria-disabled="true"] { + background: none; + border: 1px solid var(--control-disabled-color, @control-disabled-color); + color: var(--control-disabled-color, @control-disabled-color); + cursor: not-allowed; + + .user-select(none); + } +} diff --git a/asset/css/balls.less b/asset/css/balls.less index f3afae3..70ef391 100644 --- a/asset/css/balls.less +++ b/asset/css/balls.less @@ -2,18 +2,27 @@ .ball { border-radius: 50%; - display: inline-block; - text-align: center; + display: inline-flex; + align-items: center; + justify-content: center; } .ball-size-xs { height: 1/3em; width: 1/3em; + + i.icon, span { + display: none; + } } .ball-size-s { height: 0.5em; width: 0.5em; + + i.icon, span { + display: none; + } } .ball-size-m { @@ -21,10 +30,14 @@ width: 0.75em; line-height: 0; - i.icon:before { + i.icon::before { font-size: .75 - @ball-pad * 2; line-height: 1em; } + + span { + display: none; + } } .ball-size-ml { @@ -35,11 +48,15 @@ i.icon { line-height: 0.3; - &:before { + &::before { font-size: 0.8 - @ball-pad * 2; line-height: 1 - @ball-pad * 2; } } + + span { + display: none; + } } .ball-size-l { @@ -47,7 +64,7 @@ width: 1.5em; line-height: 1em; - i.icon:before { + i.icon::before, span { font-size: 1 - @ball-pad * 2; line-height: 1.5 - @ball-pad * 2; } @@ -57,7 +74,7 @@ width: 2em; height: 2em; - i.icon:before { + i.icon::before, span { line-height: 2 - @ball-pad * 2; } } @@ -75,7 +92,7 @@ .state-ball { .ball(); - &.state-pending:not(.ball-size-l):not(.ball-size-xl) { + &.state-pending:not(.ball-size-l, .ball-size-xl) { .ball-solid(var(--state-pending, @state-pending)); } @@ -84,7 +101,7 @@ .ball-outline(var(--state-pending, @state-pending)); } - &.state-up:not(.ball-size-l):not(.ball-size-xl) { + &.state-up:not(.ball-size-l, .ball-size-xl) { .ball-solid(var(--state-up, @state-up)); } @@ -97,7 +114,7 @@ .ball-solid(var(--state-down, @state-down)); } - &.state-ok:not(.ball-size-l):not(.ball-size-xl) { + &.state-ok:not(.ball-size-l, .ball-size-xl) { .ball-solid(var(--state-ok, @state-ok)); } @@ -124,7 +141,6 @@ i.icon { text-align: center; - display: block; &::before { margin-right: 0; @@ -133,13 +149,13 @@ // Specific icon styles &.ball-size-l i { - &.fa-sitemap:before { + &.fa-sitemap::before { font-size: 8px; // px to ignore browser min font-size } } &.ball-size-xl i { - &.fa-sitemap:before { + &.fa-sitemap::before { font-size: .857em; line-height: (2 - @ball-pad * 2) / .857; } diff --git a/asset/css/compat.less b/asset/css/compat.less index 1188c7e..c4772ac 100644 --- a/asset/css/compat.less +++ b/asset/css/compat.less @@ -2,10 +2,15 @@ .icinga-controls { .uploaded-files { - background-color: @default-input-bg; + background-color: var(--default-input-bg, @default-input-bg); } } +// Icinga Web < 2.13 +.button-link[aria-disabled="true"]:hover { + background: none; +} + form.icinga-form { .uploaded-files { flex: 1 1 auto; @@ -20,6 +25,14 @@ form.icinga-form { } } +.icinga-controls { + .required-hint { + font-weight: bold; + color: var(--default-text-color-light, @default-text-color-light); + } +} + + // Button styles // The `form` selector is only required to overrule the hover effect applied by Icinga Web. @@ -86,3 +99,51 @@ form.icinga-form .control-group { } } } + +// suggestion-element style +form.icinga-form .suggestion-element-group { + flex: 1 1 auto; + + .suggestion-element { + border-radius: 0 0.25em 0.25em 0; + } +} + +.module-icingadb { + // Icinga DB Web (legacy) table header layout (e.g. in group details) + > .controls { + > .table-row { + display: flex; + gap: .5em; + + > .col.title { + margin-right: auto; + } + } + } + + // Icinga DB Web (legacy) object grid layout + > .content > .item-table.group-grid:has(.col.title) { + grid-template-columns: repeat(auto-fit, 15em) !important; + + > .group-grid-cell { + display: revert; + + &::before, &::after { + display: none !important; + } + + > .col.title { + border: none; + + > .column-content { + overflow: hidden; + + > * { + .text-ellipsis(); + } + } + } + } + } +} diff --git a/asset/css/controls.less b/asset/css/controls.less index 1bccbd8..ed27794 100644 --- a/asset/css/controls.less +++ b/asset/css/controls.less @@ -16,7 +16,7 @@ display: block; } - i:before { + i::before { margin: 0; } } @@ -52,7 +52,7 @@ } } - i.icon:before { + i.icon::before { color: inherit; } } @@ -69,7 +69,7 @@ height: 100%; } - i.icon:before { + i.icon::before { margin-right: 0; } } @@ -154,11 +154,6 @@ } > .search-controls > .search-bar .filter-input-area { - label { - &::after, - input { - padding: 0 .5em; - } - } + --term-padding-v: 0px; } } diff --git a/asset/css/empty-state.less b/asset/css/empty-state.less index 6291055..75879d8 100644 --- a/asset/css/empty-state.less +++ b/asset/css/empty-state.less @@ -1,5 +1,5 @@ .empty-state { - color: @empty-state-color; + color: var(--empty-state-color, @empty-state-color); } .empty-state-bar { @@ -7,5 +7,6 @@ text-align: center; .rounded-corners(); - background-color: @empty-state-bar-bg; + background-color: var(--empty-state-bar-bg, @empty-state-bar-bg); + color: var(--default-text-color, @default-text-color); } diff --git a/asset/css/icinga-icons.less b/asset/css/icinga-icons.less index 5b631f9..5888217 100644 --- a/asset/css/icinga-icons.less +++ b/asset/css/icinga-icons.less @@ -1,5 +1,5 @@ @font-face { - font-family: 'Icinga-Icons'; + font-family: Icinga-Icons; src: url('@{iplWebAssets}/font/icinga-icons/fonts/Icinga-Icons.ttf') format('truetype'), url('@{iplWebAssets}/font/icinga-icons/fonts/Icinga-Icons.woff') format('woff'), url('@{iplWebAssets}/font/icinga-icons/fonts/Icinga-Icons.svg') format('svg'); @@ -8,9 +8,9 @@ font-display: block; } -[class^="iicon-"]:before, [class*=" iicon-"]:before { +[class^="iicon-"]::before, [class*=" iicon-"]::before { /* use !important to prevent issues with browser extensions that change fonts */ - font-family: 'Icinga-Icons'; + font-family: Icinga-Icons; speak: none; font-style: normal; font-weight: normal; @@ -23,42 +23,42 @@ -moz-osx-font-smoothing: grayscale; } -.iicon-certificate:before { +.iicon-certificate::before { content: "\e906"; } -.iicon-filter-check-circle:before { +.iicon-filter-check-circle::before { content: "\e90b"; } -.iicon-ca-check-circle:before { +.iicon-ca-check-circle::before { content: "\e908"; } -.iicon-refresh-cert:before { +.iicon-refresh-cert::before { content: "\e909"; } -.iicon-th-list:before { +.iicon-th-list::before { content: "\e90a"; } -.iicon-icinga:before { +.iicon-icinga::before { content: "\e907"; } -.iicon-minimal:before, -.iicon-list-view-minimal:before { +.iicon-minimal::before, +.iicon-list-view-minimal::before { content: "\e900"; } -.iicon-detailed:before, -.iicon-list-view-detailed:before { +.iicon-detailed::before, +.iicon-list-view-detailed::before { content: "\e901"; } -.iicon-default:before, -.iicon-list-view-default:before { +.iicon-default::before, +.iicon-list-view-default::before { content: "\e902"; } -.iicon-grid:before { +.iicon-grid::before { content: "\e903"; } -.iicon-bracket-open:before { +.iicon-bracket-open::before { content: "\e904"; } -.iicon-bracket-close:before { +.iicon-bracket-close::before { content: "\e905"; } diff --git a/asset/css/item-layout.less b/asset/css/item-layout.less new file mode 100644 index 0000000..0d5ef68 --- /dev/null +++ b/asset/css/item-layout.less @@ -0,0 +1,177 @@ +// Layout + +.item-layout { + // Note that mode specific rules are as strict as possible to avoid conflicts with nested layouts. + // Consider an item which contains another item in a different layout mode. Coincidentally, this is + // already the case in Icinga DB Web with the last comment flyout. + + .flowing-content(@layout) when (@layout = "default") { + display: inline-flex; + align-items: baseline; + white-space: nowrap; + min-width: 0; + column-gap: .28125em; // calculated width + + > .ellipsize, > .subject { // .subject is compat only, Icinga DB Web used it thoroughly + .text-ellipsis(); + } + } + .flowing-content(@layout) when (@layout = "detailed") { + display: inline-flex; + align-items: baseline; + flex-wrap: wrap; + column-gap: .28125em; // calculated width + } + + display: flex; + + .visual { + display: flex; + flex-direction: column; + + width: auto; + padding: .25em 0; + margin-right: 1em; + + > i.icon { + font-size: 1.5em; + + &::before { + margin-right: 0; + } + } + } + + .main { + flex: 1 1 auto; + padding: .25em 0; + width: 0; + } + + header { + display: flex; + align-items: baseline; + justify-content: space-between; + + > .extended-info { + flex-shrink: 0; + } + } + + .caption { + p { + display: inline-block; + } + + img { + max-height: 1em; + } + } + + footer { + display: flex; + justify-content: space-between; + + padding-top: .5em; + } + + .title { + margin-right: 1em; + } + + &.minimal-item-layout > .main > header { + max-width: 100%; + height: 1.5em; + + > .caption { + flex: 1 1 auto; + height: 1.5em; + width: 0; + + &:not(:empty) { + margin-right: 1em; + } + + .text-ellipsis(); + } + } + + &.default-item-layout > .main { + > header { + height: 1.5em; + + > .title { + .flowing-content("default"); + } + + > .extended-info { + .flowing-content("default"); + } + } + + > .caption { + height: 1.5em; + + .text-ellipsis(); + } + } + + &.detailed-item-layout > .main { + > header { + > .title { + .flowing-content("detailed"); + + word-break: break-word; + hyphens: auto; + } + + > .extended-info { + .flowing-content("detailed"); + } + } + + > .caption { + display: block; + overflow: hidden; + position: relative; + + .line-clamp(5); + } + } +} + +// Style + +.item-layout { + color: var(--default-text-color-light, @default-text-color-light); + + .caption { + i { + opacity: 0.8; + } + + a { + color: var(--default-text-color, @default-text-color); + } + } + + .title { + .subject { + color: var(--default-text-color, @default-text-color); + } + + a { + color: var(--default-text-color, @default-text-color); + font-weight: bold; + + &:hover { + color: var(--link-hover-color, @link-hover-color); + text-decoration: none; + + .subject { + color: var(--link-hover-color, @link-hover-color); + } + } + } + } +} diff --git a/asset/css/list/item-list.less b/asset/css/list/item-list.less index c5c0bd2..56aba0d 100644 --- a/asset/css/list/item-list.less +++ b/asset/css/list/item-list.less @@ -4,82 +4,35 @@ list-style-type: none; } +.content:has(> .item-list) > .item-list > .empty-state { + .empty-state-bar(); +} + // Layout .item-list { margin: 0; padding: 0; - .list-item { - display: flex; - - .main { - flex: 1 1 auto; - padding: .5em 0; - width: 0; - margin-left: .5em; - } - - .visual { - display: flex; - align-items: center; - flex-direction: column; - } - - .caption { - height: 3em; - text-overflow: ellipsis; - overflow: hidden; - - .line-clamp(); - - img { - max-height: 1em; - } - } - - header { - display: flex; - align-items: flex-start; - justify-content: space-between; - } - - footer { - display: flex; - justify-content: space-between; - } - } - > .empty-state-bar { margin: 0 1em; } } -.item-list.default-layout .list-item { - .title { - display: inline-flex; - align-items: baseline; - white-space: nowrap; - min-width: 0; - - > * { - margin: 0 .28125em; // 0 calculated width - - &:first-child { - margin-left: 0; - } - - &:last-child { - margin-right: 0; - } - } - - .subject { - .text-ellipsis(); - } - } -} - .controls .list-item:not(:last-child) { margin-bottom: .5em; } + +:not(.dashboard) > .container > .content:has(> .item-list), // compat only, for Icinga Web (See #286) +.content:has(> .item-list) { + padding-left: 0; + padding-right: 0; + + > .item-list > .list-item { + padding-left: 1em; + padding-right: 1em; + } + > .item-list > .empty-state { + margin: 0 1em; + } +} diff --git a/asset/css/list/item-table.less b/asset/css/list/item-table.less index bd87503..d075702 100644 --- a/asset/css/list/item-table.less +++ b/asset/css/list/item-table.less @@ -4,79 +4,116 @@ ul.item-table { list-style-type: none; } -.table-row { - color: @default-text-color-light; - - .title { - .subject { - color: @default-text-color; - } - - a { - font-weight: bold; - - &:hover { - color: @list-item-title-hover-color; - text-decoration: none; - } - } - } -} - -@media print { - .item-table li.page-break-follows:not(:last-of-type) { - .col { - border-bottom: none; - } - - .visual { - margin-bottom: 0; - } - } +.content:has(> .item-table) > .item-table > .empty-state { + .empty-state-bar(); } // Layout -.table-row { - .title { - display: flex; +ul.item-table { + // Grid specific rules + display: grid; + grid-template-columns: minmax(0, 1fr) repeat(var(--columns), auto); + &:has(> li > .visual) { + grid-template-columns: auto minmax(0, 1fr) repeat(var(--columns), auto); + } - .visual { - width: 2.5em; - padding: .5em 0; - margin-top: -.5em; - margin-bottom: -.5em; + > li { + display: contents; + + &.item-layout .main { + // Usually, the parent is flex, but here it's contents. .main is still stretched though, + // because it's a grid item with a width of 1fr. But the default-item-layout sets a width + // which needs to be overridden. + width: auto; } - .column-content { - flex: 1 1 auto; - width: 0; + .col, &::before, &::after { + // The li might get a background on hover. Though, this won't be visible + // as it has no box model since we apply display:contents to it. + background-color: inherit; + } + } +} - > * { - .text-ellipsis(); +:not(.dashboard) > .container > .content:has(> .item-table), // compat only, for Icinga Web (See #286) +.content:has(> .item-table) { + padding-left: 0; + padding-right: 0; + + > .item-table > .empty-state { + margin: 0 1em; + } + + > ul.item-table { + // Again, since the li has no box model, it cannot have padding. So the first + // and last child need to get the left and right padding respectively. + // But we don't want to have a border that spans to the very right or left, + // so pseudo elements are required. We could add empty cells instead, but + // that would require hard coding the width here, which I'd like to avoid. + + grid-template-columns: ~"auto minmax(0, 1fr) repeat(var(--columns), auto) auto"; + &:has(> li > .visual) { + grid-template-columns: ~"auto auto minmax(0, 1fr) repeat(var(--columns), auto) auto"; + } + + > li.table-row { + &::before, &::after { + display: inline-block; + content: '\00a0'; + width: 0; + margin-bottom: 1px; + } + + &::before { + padding-left: 1em; + } + + &::after { + padding-right: 1em; } } } - - .col { - white-space: nowrap; - } -} - -ul.item-table { - display: grid; - - > .table-row { - .col:not(.title) { - display: grid; - align-items: center; - } - } } ul.item-table { + // General rules padding: 0; margin: 0; + + .table-row { + .col { + margin-right: 0; // Otherwise background has gaps + padding: .5em 1em .5em 0; + &:last-child { + padding-right: 0; + } + + .title { + margin-right: 0; + } + } + + // This is for the legacy layout only + // TODO: Drop this together with BaseTableRowItem + .col.title:has(> .visual) { + display: flex; + + > .visual { + padding-right: .5em; + } + } + + &:not(:last-of-type) { + .col { + border-bottom: 1px solid @list-item-separation-bg; + + &.visual { + border-color: @default-bg; + } + } + } + } } div.item-table { @@ -85,11 +122,10 @@ div.item-table { } } -div.table-row { - display: flex; - column-gap: 1em; - - .title { - flex: 1 1 auto; +@media print { + .item-table li.page-break-follows:not(:last-of-type) { + .col { + border-bottom: none; + } } } diff --git a/asset/css/list/list-item.less b/asset/css/list/list-item.less index 41b66ff..2b878f4 100644 --- a/asset/css/list/list-item.less +++ b/asset/css/list/list-item.less @@ -1,8 +1,6 @@ // Style .list-item { - color: @default-text-color-light; - &:not(:first-child) > .main { border-top: 1px solid @list-item-separation-bg; } @@ -10,40 +8,6 @@ &:not(:first-child) .visual { margin-top: 1px; } - - .caption { - i { - opacity: 0.8; - } - - a { - color: @default-text-color; - } - } - - .title { - .subject { - color: @default-text-color; - } - - a { - color: @default-text-color; - font-weight: bold; - - &:hover { - color: @list-item-title-hover-color; - text-decoration: none; - - .subject { - color: @list-item-title-hover-color; - } - } - } - } - - footer { - padding-top: .5em; - } } @media print { @@ -56,34 +20,10 @@ // Layout -.list-item { +.list-item.item-layout { + .main, .visual { - padding: .5em 0; - width: 2.5em; - } - - .caption { - p { - display: inline-block; - } - } - - .title { - margin-right: 1em; - - p { - margin: 0; - } - } - - time { - white-space: nowrap; - } - - footer { - > * { - font-size: .857em; - line-height: 1.5*.857em; - } + padding-top: .5em; + padding-bottom: .5em; } } diff --git a/asset/css/mixin/mixins.less b/asset/css/mixin/mixins.less index 58b9567..e82fb37 100644 --- a/asset/css/mixin/mixins.less +++ b/asset/css/mixin/mixins.less @@ -39,3 +39,8 @@ .monospace-font() { font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace; } + +.user-select(@user-select) { + -webkit-user-select: @user-select; + user-select: @user-select; +} diff --git a/asset/css/schedule-element.less b/asset/css/schedule-element.less index 1905a05..807b87a 100644 --- a/asset/css/schedule-element.less +++ b/asset/css/schedule-element.less @@ -19,7 +19,7 @@ } &:disabled { - color: @schedule-element-fields-disabled-color; + color: var(--schedule-element-fields-disabled-color, @schedule-element-fields-disabled-color); } } } @@ -39,7 +39,7 @@ .monthly, .ordinal:not(.annually) { padding: .5em; margin-left: -.5em; - border: 1px solid @schedule-element-fields-border-color; + border: 1px solid var(--schedule-element-fields-border-color, @schedule-element-fields-border-color); .rounded-corners(.75em); } @@ -56,13 +56,13 @@ pointer-events: none; label { - color: @schedule-element-fields-disabled-color; - background-color: @schedule-element-fields-disabled-bg; + color: var(--schedule-element-fields-disabled-color, @schedule-element-fields-disabled-color); + background-color: var(--schedule-element-fields-disabled-bg, @schedule-element-fields-disabled-bg); } input:checked + label { - background: @schedule-element-fields-disabled-selected-bg; - color: @schedule-element-fields-disabled-color; + background: var(--schedule-element-fields-disabled-selected-bg, @schedule-element-fields-disabled-selected-bg); + color: var(--schedule-element-fields-disabled-color, @schedule-element-fields-disabled-color); } } @@ -75,11 +75,11 @@ cursor: pointer; text-align: center; padding: .75em 0; - background: @schedule-element-fields-bg; - color: @schedule-element-fields-color; + background: var(--schedule-element-fields-bg, @schedule-element-fields-bg); + color: var(--schedule-element-fields-color, @schedule-element-fields-color); &:hover { - background-color: @schedule-element-fields-hover-bg; + background-color: var(--schedule-element-fields-hover-bg, @schedule-element-fields-hover-bg); } &:focus { @@ -88,27 +88,27 @@ } input:checked + label { - background-color: @schedule-element-fields-selected-bg; - color: @schedule-element-fields-selected-color; + background-color: var(--schedule-element-fields-selected-bg, @schedule-element-fields-selected-bg); + color: var(--schedule-element-fields-selected-color, @schedule-element-fields-selected-color); } input:checked + label:hover { - background-color: @schedule-element-fields-selected-hover-bg; - border-color: @schedule-element-fields-selected-hover-bg; + background-color: var(--schedule-element-fields-selected-hover-bg, @schedule-element-fields-selected-hover-bg); + border-color: var(--schedule-element-fields-selected-hover-bg, @schedule-element-fields-selected-hover-bg); } } &.multiple-fields { li:not(:last-child) label { - border-right: 1px solid @schedule-element-fields-border-color; + border-right: 1px solid var(--schedule-element-fields-border-color, @schedule-element-fields-border-color); } input:focus + label { - box-shadow: inset 0 0 0 3px @schedule-element-fields-outline-color; + box-shadow: inset 0 0 0 3px var(--schedule-element-fields-outline-color, @schedule-element-fields-outline-color); } input:checked:focus + label { - box-shadow: inset 0 0 0 3px @schedule-element-fields-selected-outline-color; + box-shadow: inset 0 0 0 3px var(--schedule-element-fields-selected-outline-color, @schedule-element-fields-selected-outline-color); } } @@ -128,7 +128,7 @@ } &:focus-within { - outline: 3px solid @schedule-element-fields-outline-color; + outline: 3px solid var(--schedule-element-fields-outline-color, @schedule-element-fields-outline-color); outline-offset: 2px; } @@ -137,7 +137,7 @@ } input:checked + label:hover { - background-color: @schedule-element-fields-selected-bg; + background-color: var(--schedule-element-fields-selected-bg, @schedule-element-fields-selected-bg); } } } @@ -145,20 +145,17 @@ .note { display: none; padding: .5em; - background: @schedule-element-keyboard-note-bg; + background: var(--schedule-element-keyboard-note-bg, @schedule-element-keyboard-note-bg); .rounded-corners(.25em); text-align: center; margin-top: 1em; line-height: 1.25; } - /* .weekly */ - .weekly { } - /* .monthly styles */ .monthly { li label { - border-top: 1px solid @schedule-element-fields-border-color; + border-top: 1px solid var(--schedule-element-fields-border-color, @schedule-element-fields-border-color); } li:first-child, @@ -189,14 +186,13 @@ li:nth-child(4n) label { margin-right: 0; } + } - .toggle-slider-controls { - display: flex; - column-gap: 1em; - align-items: center; - margin-top: 1em; - margin-bottom: -.6em; - } + .toggle-slider-controls { + display: flex; + column-gap: 1em; + align-items: center; + margin-bottom: -.6em; } } @@ -205,6 +201,6 @@ padding-top: 0.5625em; p { - color: @schedule-element-fields-disabled-color; + color: var(--schedule-element-fields-disabled-color, @schedule-element-fields-disabled-color); } } diff --git a/asset/css/search-bar.less b/asset/css/search-bar.less index 6ad1aec..deb5f9e 100644 --- a/asset/css/search-bar.less +++ b/asset/css/search-bar.less @@ -11,8 +11,8 @@ } // Submit button styles - input[type=submit], - button[type=submit], + input[type="submit"], + button[type="submit"], button:not([type]) { background: var(--primary-button-bg, @primary-button-bg); color: var(--primary-button-color, @primary-button-color); @@ -26,20 +26,20 @@ } // Hide the submit button, it must exist, but shouldn't be shown to the user - input[type=submit][value="hidden"] { + input[type="submit"][value="hidden"] { display: none; } // Left-most search dropdown style button.search-options { - i.icon:before { + i.icon::before { font-size: 1.2em; margin-right: 0; color: var(--control-color, @control-color); } &:disabled { - i.icon:before { + i.icon::before { color: var(--control-disabled-color, @control-disabled-color); } } @@ -52,7 +52,7 @@ background-color: var(--search-condition-remove-bg, @search-condition-remove-bg); color: var(--search-condition-remove-color, @search-condition-remove-color); - &:after { + &::after { content: ""; position: absolute; width: .4em; @@ -77,7 +77,7 @@ .terms > .filter-condition:first-child button { border-radius: 0 .4em .4em 0; - &:before { + &::before { content: ""; position: absolute; width: .4em; @@ -92,14 +92,14 @@ border-bottom-right-radius: .4em; } - &:after { + &::after { content: none; } } - .logical_operator, - .grouping_operator_open, - .grouping_operator_close { + .logical-operator, + .grouping-operator-open, + .grouping-operator-close { input { .rounded-corners(); background-color: var(--search-logical-operator-bg, @search-logical-operator-bg); @@ -108,9 +108,9 @@ } .operator, - .logical_operator, - .grouping_operator_open, - .grouping_operator_close { + .logical-operator, + .grouping-operator-open, + .grouping-operator-close { input { text-align: center; } @@ -153,7 +153,7 @@ li { display: inline; - &:not(:first-of-type):before { + &:not(:first-of-type)::before { display: inline; content: ', '; } @@ -193,12 +193,12 @@ left: ~"calc(-2em - 2px)"; // That's min-width + margin-right of an operator line-height: 16/12; // 16 (px) desired / default font size (px) - i:before { + i::before { margin-right: 0; } } - &:not(._hover_delay):hover button { + &:not([data-hover-delay]):hover button { display: inline; } } @@ -210,9 +210,9 @@ } label { - &.logical_operator, - &.grouping_operator_open, - &.grouping_operator_close { + &.logical-operator, + &.grouping-operator-open, + &.grouping-operator-close { margin-left: 1px; // adds up to 2px with the previous term margin-right: 2px; } diff --git a/asset/css/search-base.less b/asset/css/search-base.less index 416ee31..50e7fc7 100644 --- a/asset/css/search-base.less +++ b/asset/css/search-base.less @@ -58,20 +58,29 @@ fieldset:disabled .term-input-area [data-drag-initiator] { cursor: not-allowed; } -.invalid-reason { - padding: .25em; - .rounded-corners(.25em); - border: 1px solid black; - font-weight: bold; - background: var(--search-term-invalid-reason-bg, @search-term-invalid-reason-bg); +.term-input-area { + .invalid-reason { + padding: .25em; + .rounded-corners(.25em); + border: 1px solid black; + font-weight: bold; + background: var(--search-term-invalid-reason-bg, @search-term-invalid-reason-bg); - opacity: 0; - visibility: hidden; - transition: opacity 2s, visibility 2s; - &.visible { - opacity: 1; - visibility: visible; - transition: none; + opacity: 0; + visibility: hidden; + transition: opacity 2s, visibility 2s; + + &.visible { + opacity: 1; + visibility: visible; + transition: none; + } + } + + .remove-action { + background: var(--search-term-remove-action-bg, @search-term-remove-action-bg); + color: var(--search-term-remove-action-color, @search-term-remove-action-color); + .rounded-corners(0.25em); } } @@ -153,12 +162,15 @@ fieldset:disabled .term-input-area [data-drag-initiator] { // Layout .search-bar .filter-input-area, .term-input-area:not(.vertical) { + --term-padding-v: .25em; + --term-padding-h: .5em; + overflow: auto hidden; - overflow-x: overlay; // Not invalid, but proprietary feature by chrome/webkit display: flex; flex-wrap: nowrap; width: 100%; - height: ~"calc(2em + 10px)"; // Search bar height + approximate scrollbar height + // input line-height + (input vertical padding * 2) + approximate scrollbar height + height: ~"calc(20px + calc(var(--term-padding-v) * 2) + 10px)"; // Lets inputs grow based on their contents, Inspired by https://css-tricks.com/auto-growing-inputs-textareas/ label { @@ -170,7 +182,7 @@ fieldset:disabled .term-input-area [data-drag-initiator] { &::after, input { width: auto; - padding: .25em .5em; + padding: var(--term-padding-v) var(--term-padding-h); resize: none; } @@ -208,6 +220,11 @@ fieldset:disabled .term-input-area [data-drag-initiator] { margin-right: 1px; } } + + &.read-only [data-index] .remove-action { + line-height: 20/12; + padding: var(--term-padding-v) var(--term-padding-h); + } } .term-input-area.vertical { @@ -278,7 +295,6 @@ fieldset:disabled .term-input-area [data-drag-initiator] { position: relative; input { - padding-left: 1.5em; text-align: center; cursor: pointer; @@ -305,6 +321,36 @@ fieldset:disabled .term-input-area [data-drag-initiator] { top: 85%; left: .5em; } + + .remove-action { + display: flex; + align-items: center; + visibility: visible; + position: absolute; + width: 100%; + top: 0; + line-height: normal; + padding: 0.5em; + cursor: pointer; + + i.icon { + margin-left: auto; + } + + .remove-action-label { + margin-right: auto; + .text-ellipsis(); + } + } + + input:invalid ~ .remove-action, + input.invalid ~ .remove-action { + pointer-events: none; + } + + &:not(:hover) .remove-action { + visibility: hidden; + } } } } @@ -324,7 +370,7 @@ fieldset:disabled .term-input-area [data-drag-initiator] { padding: 0; li.suggestion-title { - padding: 1.25em .625em 0 .625em; + padding: 1.25em .625em 0; } li.failure-message { diff --git a/asset/css/search-editor.less b/asset/css/search-editor.less index d32d31c..81803da 100644 --- a/asset/css/search-editor.less +++ b/asset/css/search-editor.less @@ -28,7 +28,7 @@ .rounded-corners(0); } - i.icon:before { + i.icon::before { color: var(--search-editor-control-color, @search-editor-control-color); } @@ -110,7 +110,7 @@ border-top-right-radius: 0; } - &:before { + &::before { // The left pointing arrow border-bottom: 1px solid var(--search-editor-context-menu-border-color, @search-editor-context-menu-border-color); border-left: 1px solid var(--search-editor-context-menu-border-color, @search-editor-context-menu-border-color); @@ -118,7 +118,7 @@ } } - &:hover i.icon:before { + &:hover i.icon::before { .rounded-corners(); background: var(--primary-button-bg, @primary-button-bg); color: var(--primary-button-color, @primary-button-color); @@ -202,7 +202,7 @@ margin-left: .5em; } - i.icon:before { + i.icon::before { margin: 0; font-size: 1.5em; line-height: 1.5; @@ -227,7 +227,7 @@ white-space: nowrap; } - &:before { + &::before { // The left pointing arrow content: ""; display: block; @@ -246,7 +246,7 @@ display: block; } - i.icon:before { + i.icon::before { padding: ((28/18)-1)/2em; // (Container pixels / default font size) - line height / (padding-top,padding-bottom) line-height: 1; } diff --git a/asset/css/suggestion-element.less b/asset/css/suggestion-element.less new file mode 100644 index 0000000..db6b89f --- /dev/null +++ b/asset/css/suggestion-element.less @@ -0,0 +1,29 @@ +.suggestion-element-group { + display: inline-flex; + + .suggestion-element, + .suggestion-element-icon { + line-height: normal; + height: 2.25em; + padding: 0.5em; + background-color: var(--default-input-bg, @default-input-bg); + color: var(--default-text-color, @default-text-color); + } + + .suggestion-element { + border: none; + outline: none; + border-radius: 0 0.25em 0.25em 0; + } + + .suggestion-element-icon { + padding-right: 0; + border-radius: 0.25em 0 0 0.25em; + } + + &:focus-within { + border-radius: 0.25em; + outline: 3px solid var(--default-input-outline-color, @default-input-outline-color); + outline-offset: 1px; + } +} diff --git a/asset/css/variables.less b/asset/css/variables.less index 322049c..01c2e68 100644 --- a/asset/css/variables.less +++ b/asset/css/variables.less @@ -41,6 +41,12 @@ @default-text-color-light: fade(@default-text-color, 75%); @default-text-color-inverted: @default-bg; @default-input-bg: #404d72; +@default-input-hover-bg: #434374; +@default-input-outline-color: @base-primary-light; +@default-remove-bg: @state-critical; +@default-remove-color: @default-text-color-inverted; +@default-delete-bg: @state-critical; +@default-delete-color: @default-text-color-inverted; @state-ok: #44bb77; @state-up: @state-ok; @@ -54,6 +60,7 @@ @primary-button-color: @default-text-color-inverted; @primary-button-bg: @base-primary-bg; @primary-button-hover-bg: @base-primary-dark; +@link-hover-color: @base-primary-color; @search-term-bg: @base-gray; @search-term-color: @default-text-color-inverted; @@ -66,6 +73,8 @@ @search-term-highlighted-bg: @base-primary-bg; @search-term-highlighted-color: @default-text-color-inverted; @search-term-drag-border-color: @base-gray; +@search-term-remove-action-bg: @default-remove-bg; +@search-term-remove-action-color: @default-remove-color; @search-condition-remove-bg: @state-critical; @search-condition-remove-color: @default-text-color-inverted; @@ -115,7 +124,7 @@ @schedule-element-fields-selected-bg: @primary-button-bg; @schedule-element-fields-selected-color: @default-text-color-inverted; @schedule-element-fields-hover-bg: @base-primary-light; -@schedule-element-fields-outline-color: fade(@base-primary-bg, 50%); +@schedule-element-fields-outline-color: @default-input-outline-color; @schedule-element-fields-selected-outline-color: fade(#fff, 50%); @schedule-element-fields-selected-hover-bg: @primary-button-hover-bg; @schedule-element-fields-disabled-color: @base-gray; @@ -126,7 +135,7 @@ @empty-state-color: @base-gray-semilight; @empty-state-bar-bg: @base-gray-lighter; -@list-item-title-hover-color: @base-primary-color; +@list-item-title-hover-color: @link-hover-color; @list-item-separation-bg: @base-gray-light; @iplWebLightRules: { @@ -143,10 +152,17 @@ --default-text-color-light: fade(#535353, 75%); // --default-text-color --default-text-color-inverted: #F5F9FA; --default-input-bg: #DEECF1; + --default-input-hover-bg: #C0CCCD; + --default-input-outline-color: @base-primary-light; + --default-remove-bg: var(--base-remove-bg); + --default-remove-color: var(--default-text-color-inverted); + --default-delete-bg: var(--base-remove-bg); + --default-delete-color: var(--default-text-color-inverted); --primary-button-color: var(--default-text-color-inverted); --primary-button-bg: @primary-button-bg; --primary-button-hover-bg: @primary-button-hover-bg; + --link-hover-color: var(--base-primary-color); --searchbar-bg: var(--default-input-bg); --searchbar-scrollbar-bg: var(--base-gray-light); @@ -162,6 +178,8 @@ --search-term-highlighted-bg: var(--primary-button-bg); --search-term-highlighted-color: var(--default-text-color-inverted); --search-term-drag-border-color: var(--base-gray); + --search-term-remove-action-bg: var(--default-remove-bg); + --search-term-remove-action-color: var(--default-remove-color); --search-condition-remove-bg: var(--base-remove-bg); --search-condition-remove-color: var(--default-text-color-inverted); @@ -203,7 +221,7 @@ --schedule-element-fields-selected-bg: var(--primary-button-bg); --schedule-element-fields-selected-color: var(--default-text-color-inverted); --schedule-element-fields-hover-bg: @base-primary-light; - --schedule-element-fields-outline-color: fade(@base-primary-bg, 50%); + --schedule-element-fields-outline-color: @default-input-outline-color; --schedule-element-fields-selected-outline-color: fade(#fff, 50%); --schedule-element-fields-selected-hover-bg: var(--primary-button-hover-bg); --schedule-element-fields-disabled-color: var(--base-gray); @@ -214,7 +232,7 @@ --empty-state-color: var(--base-gray-semilight); --empty-state-bar-bg: var(--base-gray-lighter); - --list-item-title-hover-color: var(--base-primary-color); + --list-item-title-hover-color: var(--link-hover-color); --list-item-separation-bg: var(--base-gray-light); } }; diff --git a/asset/js/iterator.js b/asset/js/iterator.js new file mode 100644 index 0000000..2c78d9f --- /dev/null +++ b/asset/js/iterator.js @@ -0,0 +1,96 @@ +(function (root, factory) { + "use strict"; + + if (typeof define === "function" && define.icinga) { + define(["exports"], factory); + } else { + factory(root.icingaIteratorPolyfill = root.icingaIteratorPolyfill || {}); + } +}(self, function (exports) { + /** + * Polyfill for `Iterator.filter` + * + * @param {Symbol.iterator} iterator + * @param {function} callback + * @returns {Generator<*, void, *>} + */ + function* filter(iterator, callback) { + if (typeof iterator.filter === "function") { + yield* iterator.filter(callback); + } + + for (const item of iterator) { + if (callback(item)) { + yield item; + } + } + } + + /** + * Polyfill for `Iterator.find` + * + * @param {Symbol.iterator} iterator + * @param {function} callback + * @returns {*} + */ + function find(iterator, callback) { + if (typeof iterator.find === "function") { + return iterator.find(callback); + } + + for (const item of iterator) { + if (callback(item)) { + return item; + } + } + } + + /** + * Polyfill for `Iterator.map` + * + * @param {Symbol.iterator} iterator + * @param {function} callback + * @returns {Generator<*, void, *>} + */ + function* map(iterator, callback) { + if (typeof iterator.map === "function") { + yield* iterator.map(callback); + } + + for (const item of iterator) { + yield callback(item); + } + } + + /** + * Find the first key in the map whose value satisfies the provided testing function. + * @param {Map} map + * @param {function} callback Passed arguments are: value, key, map + * @returns {*} Returns undefined if no key satisfies the testing function. + */ + function findKey(map, callback) { + for (const key of findKeys(map, callback)) { + return key; + } + } + + /** + * Find all keys in the map whose value satisfies the provided testing function. + * @param {Map} map + * @param {function} callback Passed arguments are: value, key, map + * @returns {Generator<*, void, *>} + */ + function* findKeys(map, callback) { + for (const [ key, value ] of map) { + if (callback(value, key, map)) { + yield key; + } + } + } + + exports.findKeys = findKeys; + exports.findKey = findKey; + exports.filter = filter; + exports.find = find; + exports.map = map; +})); diff --git a/asset/js/widget/BaseInput.js b/asset/js/widget/BaseInput.js index eca7371..360d502 100644 --- a/asset/js/widget/BaseInput.js +++ b/asset/js/widget/BaseInput.js @@ -632,7 +632,11 @@ define(["../notjQuery", "Completer"], function ($, Completer) { let eventData = { submittedBy: input }; if (changeType === 'paste') { // Ensure that what's pasted is also transmitted as value - eventData['terms'] = this.termsToQueryString(data['terms']) + this.separator + data['input']; + if (data['terms'].length === 0) { + eventData['terms'] = data['input']; + } else { + eventData['terms'] = this.termsToQueryString(data['terms']) + this.separator + data['input']; + } } $(this.input.form).trigger('submit', eventData); @@ -713,7 +717,14 @@ define(["../notjQuery", "Completer"], function ($, Completer) { this.input.name = ''; // Set the hidden input's value, it's what's sent - if (event.detail && 'terms' in event.detail) { + if ( + event.detail + && 'terms' in event.detail + && ( + ! ('submittedBy' in event.detail) + || event.detail.submittedBy === this.input + ) + ) { this.termInput.value = event.detail.terms; } else { let renderedTerms = this.termsToQueryString(this.usedTerms); diff --git a/asset/js/widget/FilterInput.js b/asset/js/widget/FilterInput.js index fad3da0..3f1d947 100644 --- a/asset/js/widget/FilterInput.js +++ b/asset/js/widget/FilterInput.js @@ -13,7 +13,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { * * @type {{}} */ - this.negationOperator = { label: '!', search: '!', class: 'logical_operator', type: 'negation_operator' }; + this.negationOperator = { label: '!', search: '!', class: 'logical-operator', type: 'negation_operator' }; /** * Supported grouping operators @@ -21,8 +21,8 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { * @type {{close: {}, open: {}}} */ this.grouping_operators = { - open: { label: '(', search: '(', class: 'grouping_operator_open', type: 'grouping_operator' }, - close: { label: ')', search: ')', class: 'grouping_operator_close', type: 'grouping_operator' } + open: { label: '(', search: '(', class: 'grouping-operator-open', type: 'grouping_operator' }, + close: { label: ')', search: ')', class: 'grouping-operator-close', type: 'grouping_operator' } }; /** @@ -33,8 +33,8 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { * @type {{}[]} */ this.logical_operators = [ - { label: '&', search: '&', class: 'logical_operator', type: 'logical_operator', default: true }, - { label: '|', search: '|', class: 'logical_operator', type: 'logical_operator' }, + { label: '&', search: '&', class: 'logical-operator', type: 'logical_operator', default: true }, + { label: '|', search: '|', class: 'logical-operator', type: 'logical_operator' }, ]; /** @@ -958,7 +958,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { label.dataset.type = termData.type; if (! termData.class) { - label.classList.add(termData.type); + label.classList.add(termData.type.replace('_', '-')); } if (termData.counterpart >= 0) { @@ -1256,11 +1256,11 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { let label = event.currentTarget; if (['column', 'operator', 'value'].includes(label.dataset.type)) { - // This adds a class to delay the remove button. If it's shown instantly upon hover + // This adds an attr to delay the remove button. If it's shown instantly upon hover // it's too easy to accidentally click it instead of the desired grouping operator. - label.parentNode.classList.add('_hover_delay'); + label.parentNode.dataset.hoverDelay = ""; setTimeout(function () { - label.parentNode.classList.remove('_hover_delay'); + delete label.parentNode.dataset.hoverDelay; }, 500); } diff --git a/asset/js/widget/TermInput.js b/asset/js/widget/TermInput.js index 9e2d9de..c015469 100644 --- a/asset/js/widget/TermInput.js +++ b/asset/js/widget/TermInput.js @@ -187,8 +187,16 @@ define(["../notjQuery", "../vendor/Sortable", "BaseInput"], function ($, Sortabl const label = super.renderTerm(termData, termIndex); if (this.readOnly) { + const removeLabel = this.termContainer.dataset.removeActionLabel; label.firstChild.readOnly = true; - label.appendChild($.render('')); + label.appendChild( + $.render( + `
- *
- * @internal
- */
-final class Php80
-{
- public static function fdiv(float $dividend, float $divisor): float
- {
- return @($dividend / $divisor);
- }
-
- public static function get_debug_type($value): string
- {
- switch (true) {
- case null === $value: return 'null';
- case \is_bool($value): return 'bool';
- case \is_string($value): return 'string';
- case \is_array($value): return 'array';
- case \is_int($value): return 'int';
- case \is_float($value): return 'float';
- case \is_object($value): break;
- case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
- default:
- if (null === $type = @get_resource_type($value)) {
- return 'unknown';
- }
-
- if ('Unknown' === $type) {
- $type = 'closed';
- }
-
- return "resource ($type)";
- }
-
- $class = \get_class($value);
-
- if (false === strpos($class, '@')) {
- return $class;
- }
-
- return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
- }
-
- public static function get_resource_id($res): int
- {
- if (!\is_resource($res) && null === @get_resource_type($res)) {
- throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
- }
-
- return (int) $res;
- }
-
- public static function preg_last_error_msg(): string
- {
- switch (preg_last_error()) {
- case \PREG_INTERNAL_ERROR:
- return 'Internal error';
- case \PREG_BAD_UTF8_ERROR:
- return 'Malformed UTF-8 characters, possibly incorrectly encoded';
- case \PREG_BAD_UTF8_OFFSET_ERROR:
- return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
- case \PREG_BACKTRACK_LIMIT_ERROR:
- return 'Backtrack limit exhausted';
- case \PREG_RECURSION_LIMIT_ERROR:
- return 'Recursion limit exhausted';
- case \PREG_JIT_STACKLIMIT_ERROR:
- return 'JIT stack limit exhausted';
- case \PREG_NO_ERROR:
- return 'No error';
- default:
- return 'Unknown error';
- }
- }
-
- public static function str_contains(string $haystack, string $needle): bool
- {
- return '' === $needle || false !== strpos($haystack, $needle);
- }
-
- public static function str_starts_with(string $haystack, string $needle): bool
- {
- return 0 === strncmp($haystack, $needle, \strlen($needle));
- }
-
- public static function str_ends_with(string $haystack, string $needle): bool
- {
- if ('' === $needle || $needle === $haystack) {
- return true;
- }
-
- if ('' === $haystack) {
- return false;
- }
-
- $needleLength = \strlen($needle);
-
- return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength);
- }
-}
diff --git a/vendor/symfony/polyfill-php80/PhpToken.php b/vendor/symfony/polyfill-php80/PhpToken.php
deleted file mode 100644
index cd78c4c..0000000
--- a/vendor/symfony/polyfill-php80/PhpToken.php
+++ /dev/null
@@ -1,106 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Polyfill\Php80;
-
-/**
- * @author Fedonyuk Anton